1. EditScene
(1) Player를 그리는 툴 만들기
EditScene은 플레이어의 형태를 띨 수 있도록 직접 라인을 그릴 수 있게 하는 Scene이다.
SceneManager에 case 문을 추가한다.
case SceneType::EditScene:
newScene = new EditScene();
break;
Enums.h에 아래 코드를 추가한다.
enum class SceneType
{
None,
DevScene,
GameScene,
EditScene,
};
Game.cpp의 Init 함수 안에서 ChangeScene을 변경한다.
GET_SINGLE(SceneManager)->ChangeScene(SceneType::EditScene);
그리고 새로 EditScene 클래스를 만들어 관리한다.
#pragma once
#include "Scene.h"
class EditScene : public Scene
{
public:
EditScene();
virtual ~EditScene() override;
virtual void Init() override;
virtual void Update() override;
virtual void Render(HDC hdc) override;
private:
vector<pair<POINT, POINT>> _lines;
bool _setOrigin = true;
POINT _lastPos = {};
};
더보기
#include "pch.h"
#include "EditScene.h"
#include "InputManager.h"
EditScene::EditScene()
{
}
EditScene::~EditScene()
{
}
void EditScene::Init()
{
}
void EditScene::Update()
{
if (GET_SINGLE(InputManager)->GetButtonDown(KeyType::LeftMouse))
{
POINT mousePos = GET_SINGLE(InputManager)->GetMousePos();
if (_setOrigin)
{
_lastPos = mousePos;
_setOrigin = false;
}
else
{
_lines.push_back(make_pair(_lastPos, mousePos));
_lastPos = mousePos;
}
}
if (GET_SINGLE(InputManager)->GetButtonDown(KeyType::RIghtMouse))
_setOrigin = true;
}
void EditScene::Render(HDC hdc)
{
for (auto& line : _lines)
{
POINT pt1 = line.first;
POINT pt2 = line.second;
Pos pos1;
pos1.x = (float)pt1.x;
pos1.y = (float)pt1.y;
Pos pos2;
pos2.x = (float)pt2.x;
pos2.y = (float)pt2.y;
Utils::DrawLine(hdc, pos1, pos2);
}
}
왼쪽 버튼이 눌리면 이전 좌표의 정보를 가지고 있는지 여부(true이면 이전 정보 없음)를 판별하는 불리언 _setOrigin의 여부를 판단한다.
true이면 찍은 좌표의 값을 _lastPos에 넘겨주고, false이면 이전에 찍은 좌표와 지금 찍은 좌표를 pair로 만들어 저장한다.
그리고 오른쪽 버튼을 누르면 선을 끊어주도록 _setOrigin을 true로 만들어준다.
이어서 pair로 만들어진 정보를 꺼내와서 DrawLine 함수로 그려준 뒤에 프로그램을 실행하면 EditScene 상에서 도형을 그릴 수 있게 된다.
(2) 저장 및 불러오기
InputManager::Update()에 구현한다.
(2-1) 저장
// 저장
if (GET_SINGLE(InputManager)->GetButtonDown(KeyType::S))
{
wofstream file;
file.open(L"Unit.txt");
file << static_cast<int32>(_lines.size()) << endl;
for (auto& line : _lines)
{
POINT from = line.first;
POINT to = line.second;
// std::format을 사용하여 (0,0)->(1,1)로 나타내기
wstring str = std::format(L"({0},{1})->({2},{3})", from.x, from.y, to.x, to.y);
file << str << endl;
}
file.close();
}
(2-2) 불러오기
// 불러오기
if (GET_SINGLE(InputManager)->GetButtonDown(KeyType::D))
{
wifstream file;
file.open(L"Unit.txt");
// 라인의 갯수
int32 count;
file >> count;
_lines.clear();
for (int32 i = 0; i < count; i++)
{
// pt1과 pt2에 정보 저장하기
POINT pt1 = { 0, 0 };
POINT pt2 = { 0, 0 };
wstring str;
file >> str;
// %d : 정수, %s : 문자
::swscanf_s(str.c_str(), L"(%d,%d)->(%d,%d)", &pt1.x, &pt1.y, &pt2.x, &pt2.y);
_lines.push_back(make_pair(pt1, pt2));
_setOrigin = true;
}
file.close();
}
(3) 저장한 리소스의 피벗(기준점)을 중앙으로 맞추기
리소스의 y 좌표 차이의 절반, x 좌표 차이의 절반이 중심이다.
// 저장
if (GET_SINGLE(InputManager)->GetButtonDown(KeyType::S))
{
wofstream file;
file.open(L"Unit.txt");
int32 minX = INT32_MAX;
int32 maxX = INT32_MIN;
int32 minY = INT32_MAX;
int32 maxY = INT32_MIN;
for (auto& line : _lines)
{
POINT from = line.first;
POINT to = line.second;
minX = min(min(minX, from.x), to.x);
maxX = max(max(maxX, from.x), to.x);
minY = min(min(minY, from.y), to.y);
maxY = max(max(maxY, from.y), to.y);
}
int32 midX = (maxX + minX) / 2;
int32 midY = (maxY + minY) / 2;
file << static_cast<int32>(_lines.size()) << endl;
for (auto& line : _lines)
{
POINT from = line.first;
from.x -= midX;
from.y -= midY;
POINT to = line.second;
to.x -= midX;
to.y -= midY;
wstring str = std::format(L"({0},{1})->({2},{3})", from.x, from.y, to.x, to.y);
file << str << endl;
}
file.close();
}
// 불러오기
if (GET_SINGLE(InputManager)->GetButtonDown(KeyType::D))
{
wifstream file;
file.open(L"Unit.txt");
// 라인의 갯수
int32 count;
file >> count;
_lines.clear();
int32 midX = 400;
int32 midY = 300;
for (int32 i = 0; i < count; i++)
{
// pt1과 pt2에 정보 저장하기
POINT pt1;
POINT pt2;
wstring str;
file >> str;
// %d : 정수, %s : 문자
::swscanf_s(str.c_str(), L"(%d,%d)->(%d,%d)", &pt1.x, &pt1.y, &pt2.x, &pt2.y);
pt1.x += midX;
pt1.y += midY;
pt2.x += midX;
pt2.y += midY;
_lines.push_back(make_pair(pt1, pt2));
_setOrigin = true;
}
file.close();
}
}
불러올 때 중앙에 소환하도록 한다.
'Windows API & 게임 수학' 카테고리의 다른 글
1-11. 번외 - 충돌 판정(Collision) 구현하기 (0) | 2023.10.24 |
---|---|
1-10. 번외 - 점수(Score) 구현하기 (0) | 2023.10.24 |
1-7. 오브젝트(Object) 설계 (2) - 디버깅, 몬스터, 피격 판정 (0) | 2023.10.17 |
1-6. 오브젝트(Object) 설계 (1) - 플레이어, 투사체, ObjectManager (0) | 2023.10.17 |
1-5. 더블 버퍼링 (Double Buffering) (0) | 2023.10.17 |