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();
	}
}

불러올 때 중앙에 소환하도록 한다.