League Of Legends - Link Select [winAPI 07] Scene & Scene Manager
๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿค“ Study/winAPI

[winAPI 07] Scene & Scene Manager

by GAMEMING 2024. 6. 4.
728x90

 

 

๊ฒŒ์ž„์—๋Š” ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์”ฌ์ด ์กด์žฌํ•œ๋‹ค. ์”ฌ์€ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„๋ ๊นŒ?

๊ฒŒ์ž„ ๋‚ด์—๋Š” ์ˆ˜ ๋งŽ์€ ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ์กด์žฌํ•˜๋Š”๋ฐ ์ด๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ์”ฌ์ด๋ผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 

- ์”ฌ ๊ตฌ์กฐ ๋งŒ๋“ค๊ธฐ

 ์—ฌ๊ธฐ์„œ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๊ด€๋ฆฌํ•  ๊ฒƒ์ธ๋ฐ ์”ฌ๋„ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์”ฌ์œผ๋กœ ๋‚˜๋‰˜๊ธฐ์— ์ƒ์†์œผ๋กœ ๊ตฌํ˜„๋œ๋‹ค. ์”ฌ์— ์กด์žฌํ•˜๋Š” ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์—ฌ๋Ÿฌ ๊ทธ๋ฃน์œผ๋กœ ๋‚˜๋ˆ  ๊ตฌ๋ณ„ํ•˜๊ธฐ ์œ„ํ•ด ์•„๋ž˜์ฒ˜๋Ÿผ enum class๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

// define.h์— ์ถ”๊ฐ€

enum class GROUP_TYPE {
	DEFAULT,
	PLAYER,
	MISSTLE,
	MONSTER,

	END = 32,
};
// Scene.h ์ƒ์„ฑ

class Object;	// ์ „๋ฐฉ์„ ์–ธ
class Scene {
private:
	vector<Object*> arrObj[(UINT)GROUP_TYPE::END];	
	wstring			strName;

public:
	Scene();
	virtual ~Scene();

	void SetName(const wstring& _strName) { strName = _strName; }
	const wstring& GetName() { return strName; }

	void update();
	void render(HDC _hdc);

	virtual void Enter() = 0;
	virtual void Exit() = 0;

protected:
	void AddObject(Object* obj, GROUP_TYPE type)
	{
		arrObj[(UINT)type].push_back(obj);
	}
};

 

์ „๋ฐฉ์„ ์–ธ  : ์ปดํŒŒ์ผ ์†๋„์— ๋ถ€๋‹ด ๋œ๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ. ์•„๋ž˜์—์„  Object ํ—ค๋” ํŒŒ์ผ ๋‚ด๋ถ€ ๋‚ด์šฉ์ด ๋ณ€๊ฒฝ๋˜๋”๋ผ๋„ Scene ํŒŒ์ผ์€ ๋‹ค์‹œ ์ปดํŒŒ์ผ ๋˜์ง€ ์•Š์Œ.

 

Scene ํด๋ž˜์Šค๋Š” ์ƒ์„ฑ๋˜๋Š” ๋ชจ๋“  ์”ฌ์˜ ๋ถ€๋ชจ ํด๋ž˜์Šค๋‹ค.

private์œผ๋กœ ์„ ์–ธ๋œ arrObj์™€ strName์€ ๊ฐ๊ฐ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ €์žฅ ๋ฐ ๊ด€๋ฆฌํ•  ๋ฒกํ„ฐ๋ฅผ ๊ทธ๋ฃน ๊ฐœ์ˆ˜๋งŒํผ ์„ ์–ธํ•œ ๋ณ€์ˆ˜์™€ ์”ฌ ์ด๋ฆ„์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋ณ€์ˆ˜์ด๋‹ค.

 

 

Object๊ฐ€ ํฌ์ธํ„ฐ๋กœ ์˜ค๋Š” ์ด์œ ๋Š” ์ž์‹ ํด๋ž˜์Šค ํƒ€์ž…๋“ค์€ ๋ถ€๋ชจ ํฌ์ธํ„ฐ ํƒ€์ž…์œผ๋กœ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๊ธฐ์— ๋ถ€๋ชจ ํด๋ž˜์Šค์ธ Object์˜ ํฌ์ธํ„ฐ๋กœ ๊ฐ€์ ธ์˜จ ๊ฒƒ. 

 

์œ„์—์„œ ์–ธ๊ธ‰ํ•˜์˜€ ๋“ฏ์ด ์”ฌ์€ ์—ฌ๋Ÿฌ ๊ฐœ๊ฐ€ ์กด์žฌํ•˜๊ธฐ์— ์ด๋“ค์„ ๊ด€๋ฆฌํ•˜๋Š” Scene Manager๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

// SceneManager.h

class Scene;

class SceneManager{
	SINGLE(SceneManager);

private:
	Scene*	arrScene[(UINT)SCENE_TYPE::END];	
	Scene*	currScene;				

public:
	void init();
	void update();
	void render(HDC _hdc);
};

 

์ด ์นœ๊ตฌ๋Š” ์—ฌ๋Ÿฌ ์”ฌ์„ ๊ด€๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋“  ์”ฌ์˜ ๋ชฉ๋ก๊ณผ ํ˜„์žฌ ์–ด๋–ค ์”ฌ์ธ์ง€๋ฅผ ๊ฐ–๊ณ  ์žˆ์–ด์•ผ ํ•œ๋‹ค.

๊ฐ๊ฐ arrScene์™€ currScene ๋ณ€์ˆ˜๊ฐ€ ์ด๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

 

์ง€๊ธˆ๊นŒ์ง€ ๋งŒ๋“  ๊ฒƒ์€ ์”ฌ์˜ ๋ถ€๋ชจ์ด์ž ํ† ๋Œ€๊ฐ€ ๋˜๋Š” ์นœ๊ตฌ๋“ค์ด๋‹ค.

๋งŒ์•ฝ ๊ฒŒ์ž„์„ ์‹œ์ž‘ํ•˜๋Š” Start Scene์„ ๊ตฌํ˜„ํ•ด๋ณด์ž.

 

๊ธฐ๋ณธ ํด๋ž˜์Šค์— Scene์„ ๋„ฃ์œผ๋ฉด ์•Œ์•„์„œ ์ƒ์†๋œ๋‹ค

 

// Scene_Start.h

#include "Scene.h"

class Scene_Start : public Scene {
public:
	Scene_Start();
	~Scene_Start();

	virtual void Enter();
	virtual void Exit();
};
Scene_Start::Scene_Start()
{

}

Scene_Start::~Scene_Start()
{
}

void Scene_Start::Enter()
{
	// Object ์ถ”๊ฐ€
	Object* obj = new Object;
	obj->setPos(Vec2(640.f, 384.f));
	obj->setScale(Vec2(100.f, 100.f));

	AddObject(obj, GROUP_TYPE::DEFAULT);
}

void Scene_Start::Exit()
{

}

 

 

์”ฌ์˜ Enterํ•จ์ˆ˜์™€ Exitํ•จ์ˆ˜์—๋Š” ๊ฐ๊ฐ ์”ฌ์— ์ง„์ž…ํ•  ๋•Œ์™€ ํƒˆ์ถœํ•  ๋•Œ ํ•ด์•ผ ํ•˜๋Š” ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•œ๋‹ค. ์ด Enter()์™€ Exit()๋Š” ๋ชจ๋“  ์”ฌ์— ํฌํ•จ๋˜์–ด์•ผ ํ•˜๊ธฐ์— ๋ถ€๋ชจ์ธ ์”ฌ ํด๋ž˜์Šค ๋‚ด๋ถ€์—์„œ ๊ฐ€์ƒ ํ•จ์ˆ˜๋กœ ๋งŒ๋“ค์–ด ์ƒ์† ๋ฐ›๊ณ  ์žˆ๋Š” ์ƒ์† ๋ฐ›๋Š” ์ž์‹ ํด๋ž˜์Šค๊ฐ€ ์ž์‹ ๋งŒ์˜ ๋ฒ„์ „์„ ๊ตฌํ˜„ํ•˜๋„๋ก ๊ฐ•์ œํ•ด์•ผ ํ•œ๋‹ค. ( ์ฆ‰ Enter๊ณผ Exit ํ•จ์ˆ˜๋Š” ์—ฌ๊ธฐ์„œ ์ธํ„ฐํŽ˜์ด์Šค ํ•จ์ˆ˜์ž„ )

 

Sence ํด๋ž˜์Šค ๋‚ด๋ถ€์— ์„ ์–ธ๋œ ๊ฐ€์ƒ ํ•จ์ˆ˜ Enter, Exit

 

๊ทธ๋ฆฌ๊ณ  ๋ชจ๋“  ์”ฌ์€ Scene ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›๋Š”๋ฐ ์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ ์ ์€ ์†Œ๋ฉธ์ž์— virtual ํ‚ค์›Œ๋“œ๊ฐ€ ๋ถ™์–ด์•ผ ํ•œ๋‹ค.
๊ฐ€์ƒ ํ•จ์ˆ˜๊ฐ€ ์—†์—ˆ๋‹ค๋ฉด ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ ์†Œ๋ฉธ์ž๋งŒ ํ˜ธ์ถœ๋˜๊ณ  ์ž์‹ ํด๋ž˜์Šค์˜ ์†Œ๋ฉธ์ž๊ฐ€ ํ˜ธ์ถœ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, Scene, Object ํด๋ž˜์Šค์™€ ๊ฐ™์€ ์ƒ์†์ด ๋ชฉ์ ์ด ๋˜๋Š” ํด๋ž˜์Šค๋Š” ๋ฐ˜๋“œ์‹œ ์†Œ๋ฉธ์ž์— virtual์„ ๋ถ™์—ฌ์•ผ ํ•จ!

 

Scene_Start class ์ฒ˜๋Ÿผ ๊ฐ€์ƒ ํ•จ์ˆ˜๋ฅผ ๋ถ€๋ชจ ํด๋ž˜์Šค๋กœ๋ถ€ํ„ฐ ์ƒ์† ๋ฐ›๋Š” ์ž…์žฅ์ด๋ผ๋ฉด, ๊ตณ์ด virtual ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™์ผ ํ•„์š”๊ฐ€ ์—†๋‹ค. ํ•˜์ง€๋งŒ ๋ช…์‹œ์ ์œผ๋กœ ๊ฐ€์ƒํ•จ์ˆ˜์ž„์„ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•ด ์ž‘์„ฑํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค.

 

Enter ํ•จ์ˆ˜ ๋‚ด๋ถ€ํ„ฐ์—์„œ๋Š” ๋ณธ๊ฒฉ์ ์ธ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฒŒ ๋˜๋Š”๋ฐ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋™์ ์œผ๋กœ ๋งŒ๋“œ๋Š” ์• ๋“ค์ด๊ธฐ์— ์†Œ๋ฉธ์‹œ์ผœ ์ฃผ์–ด์•ผ ํ•œ๋‹ค. ์–ด๋””์„œ? → ์ƒ์†์„ ์ด์šฉํ•˜๋Š” ์ด์œ ๋Š” ์ฝ”๋“œ์˜ ์žฌ์‚ฌ์šฉ์— ์žˆ๋‹ค. ๊ตณ์ด ์ด ํด๋ž˜์Šค ๋‚ด๋ถ€์—์„œ ํ•˜๋‚˜ํ•˜๋‚˜ ํ•ด์ œํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ ๋ถ€๋ชจ ํด๋ž˜์Šค์ธ Scene ๋‚ด๋ถ€์—์„œ ์ง€์›Œ์ฃผ๋ฉด ๋œ๋‹ค.

// Scene.cpp

Scene::~Scene()
{
	for (UINT i = 0; i < (UINT)GROUP_TYPE::END; ++i)
		for (size_t j = 0; j < arrObj[i].size(); ++j)
			// arrObj[i] ๊ทธ๋ฃน ๋ฒกํ„ฐ์˜ j๋ฌผ์ฒด ์‚ญ์ œ
			delete arrObj[i][j];
}

 

์˜ค๋ธŒ์ ํŠธ ์ถ”๊ฐ€๋„ ์•„๋ž˜์˜ ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด์„œ ํ•œ๋‹ค.

// Scene.h

protected:
	void AddObject(Object* obj, GROUP_TYPE type)
	{
		arrObj[(UINT)type].push_back(obj);
	}

 

+ ๋ฒกํ„ฐ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ์ง€ ์•Š๋Š” ์ด์ƒ ๋ฉ”๋ชจ๋ฆฌ ์•ˆ ๋จน์Œ ( ๋ฐ์ดํ„ฐ๊ฐ€ ์‚ฝ์ž…๋˜๊ธฐ ์ „์—๋Š” ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ฑฐ์˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ. ๋ฒกํ„ฐ ์ž์ฒด์˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ(์˜ˆ: ํฌ์ธํ„ฐ, ํฌ๊ธฐ, ์šฉ๋Ÿ‰ ๋“ฑ)๋งŒ์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ์•ฝ๊ฐ„์˜ ๋ฉ”๋ชจ๋ฆฌ๋งŒ ์‚ฌ์šฉํ•จ - ๋ฒกํ„ฐ = ๋™์  ๋ฐฐ์—ด )

 

์”ฌ์— ๋”ฐ๋ผ์„œ ์—…๋ฐ์ดํŠธ๋ฅผ ํ•˜๊ณ  ๊ทธ๋ฆฌ๊ธฐ ์œ„ํ•ด์„œ๋Š” ๊ธฐ์กด Core ์ฝ”๋“œ๋„ ์ˆ˜์ •ํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค. ์”ฌ ๋งค๋‹ˆ์ € ๋˜ํ•œ ์ฝ”์–ด ๋‚ด๋ถ€์—์„œ Initํ•จ์ˆ˜์™€ updateํ•จ์ˆ˜๋ฅผ ๋ถˆ๋Ÿฌ์™€์•ผ ํ•˜๊ณ  ์ถ”๊ฐ€์ ์œผ๋กœ ํ•ด๋‹น ์”ฌ์„ ๊ทธ๋ฆฌ๋Š” renderํ•จ์ˆ˜๋„ ์ถ”๊ฐ€๋˜์–ด์•ผ ํ•œ๋‹ค.

#include "SceneManager.h"	//์ถ”๊ฐ€

int Core::Init(HWND _handle, POINT _ptResolution)
{
	//...
    // Manager์ดˆ๊ธฐํ™”
	TimeManager::Instance()->Init();
	KeyManager::Instance()->init();
	SceneManager::Instance()->init();	// ์ถ”๊ฐ€ - ๋ชจ๋“  ์”ฌ ์ƒ์„ฑ
	
    // ..
}

void Core::Progress()	// ์ˆ˜์ •
{
	// Manager update
	TimeManager::Instance()->update();
	KeyManager::Instance()->update();

	SceneManager::Instance()->update();

	// Rendering
	// ํ™”๋ฉด clear
	Rectangle(mDC, -1, -1, ptResolution.x + 1, ptResolution.y + 1);

	SceneManager::Instance()->render(mDC);

	BitBlt(hDC, 0, 0, ptResolution.x, ptResolution.y, mDC, 0, 0, SRCCOPY); 
}

 

 

์”ฌ ๋งค๋‹ˆ์ € ๋‚ด๋ถ€์—์„œ๋Š” ์ด ๊ฐ ํ•จ์ˆ˜๊ฐ€ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„๋ ๊นŒ?

๊ฐ ํ•จ์ˆ˜๊ฐ€ ํ•˜๋Š” ์ผ๊ณผ ๊ทธ ๋‚ด๋ถ€ ๊ตฌํ˜„์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

 

#include "pch.h"
#include "SceneManager.h"

#include "Scene_Start.h"

SceneManager::SceneManager()
	:arrScene{}
	,currScene(nullptr)
{

}

SceneManager::~SceneManager()
{
	// ์”ฌ ์ „๋ถ€ ์‚ญ์ œ
	for (UINT i = 0; i < (UINT)SCENE_TYPE::END; ++i)
		if (nullptr != arrScene[i])
			delete arrScene[i];
}

void SceneManager::init()
{
	// Scene ์ƒ์„ฑ
	arrScene[(UINT)SCENE_TYPE::START] = new Scene_Start;
	arrScene[(UINT)SCENE_TYPE::START]->SetName(L"Start Scene");
	// arrScene[(UINT)SCENE_TYPE::TOOL] = new Scene_Tool;
	// arrScene[(UINT)SCENE_TYPE::STAGE_01] = new Scene_Stage01;
	// arrScene[(UINT)SCENE_TYPE::STAGE_02] = new Scene_Stage02;

	// ํ˜„์žฌ ์”ฌ ์ง€์ •
	currScene = arrScene[(UINT)SCENE_TYPE::START];
	currScene->Enter();
}

void SceneManager::update()
{
	// ํ˜„์žฌ ์”ฌ ์—…๋ฐ์ดํŠธ
	currScene->update();
}

void SceneManager::render(HDC _hdc)
{
	// ํ˜„์žฌ ์”ฌ ๊ทธ๋ฆฌ๊ธฐ
	currScene->render(_hdc);
}

 

๊ทธ๋ ‡๋‹ค๋ฉด ์—ฌ๊ธฐ์„œ ํ˜„์žฌ ์”ฌ์€ Scene ํด๋ž˜์Šค์˜ ํฌ์ธํ„ฐ์ž„์œผ๋กœ ์”ฌ ํด๋ž˜์Šค ์ž์ฒด์—์„œ๋„ updateํ•จ์ˆ˜์™€ renderํ•จ์ˆ˜๋„ ๊ตฌํ˜„๋˜์–ด์•ผ ํ•œ๋‹ค. 

 

#include "pch.h"
#include "Scene.h"

#include "Object.h"

Scene::Scene()
{

}

Scene::~Scene()
{
	for (UINT i = 0; i < (UINT)GROUP_TYPE::END; ++i)
		for (size_t j = 0; j < arrObj[i].size(); ++j)
			// arrObj[i] ๊ทธ๋ฃน ๋ฒกํ„ฐ์˜ j๋ฌผ์ฒด ์‚ญ์ œ
			delete arrObj[i][j];
}

void Scene::update()
{
	for (UINT i = 0; i < (UINT)GROUP_TYPE::END; ++i) {
		for (size_t j = 0; j < arrObj[i].size(); ++j) {
			arrObj[i][j]->update();
		}
	}
}

void Scene::render(HDC _hdc)
{
	for (UINT i = 0; i < (UINT)GROUP_TYPE::END; ++i) {
		for (size_t j = 0; j < arrObj[i].size(); ++j) {
			arrObj[i][j]->render(_hdc);
		}
	}
}

 

์ด๋Ÿฌ๋ฉด ๊ฐ ์˜ค๋ธŒ์ ํŠธ ๋˜ํ•œ update์™€ renderํ•จ์ˆ˜๊ฐ€ ์กด์žฌํ•ด์•ผ ํ•˜๊ธฐ์— Object ํด๋ž˜์Šค๋„ ์•„๋ž˜์ฒ˜๋Ÿผ ๋ณ€๊ฒฝ๋œ๋‹ค.

 

// Object.h

class Object {
private:
	Vec2	vPos;
	Vec2	vScale;

public:
	Object();
	virtual ~Object();

	void setPos(Vec2 _vPos) { vPos = _vPos; }
	void setScale(Vec2 _vScale) { vScale = _vScale; }

	Vec2 getPos() { return vPos; }
	Vec2 getScale() { return vScale; }

public:
	void update();
	void render(HDC _hdc);
};


// Object.cpp
#include "pch.h"
#include "Object.h"

#include "KeyManager.h"
#include "TimeManager.h"

Object::Object()
	: vPos{}
	, vScale{}
{
}

Object::~Object()
{
}

void Object::update()
{
	if (KeyManager::Instance()->GetKeyState(KEY::W) == KEY_STATE::HOLD) {
		vPos.y -= 200.f * DT;
	}

	if (KeyManager::Instance()->GetKeyState(KEY::S) == KEY_STATE::HOLD) {
		vPos.y += 200.f * DT;
	}

	if (KeyManager::Instance()->GetKeyState(KEY::A) == KEY_STATE::HOLD) {
		vPos.x -= 200.f * DT;
	}

	if (KeyManager::Instance()->GetKeyState(KEY::D) == KEY_STATE::HOLD) {
		vPos.x += 200.f * DT;
	}
}

void Object::render(HDC _hdc)
{
	// ๊ฐ์ž ์ž๊ธฐ๊ฐ€ ์ž๊ธฐ๋ฅผ ๊ทธ๋ฆฌ๋ฉด ๋จ
	Rectangle(_hdc, (int)(vPos.x - vScale.x / 2.f), (int)(vPos.y - vScale.y / 2.f),
		(int)(vPos.x + vScale.x / 2.f), (int)(vPos.y + vScale.y / 2.f));
}

'๐Ÿค“ Study > winAPI' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[winAPI 09] ๊ธฐ์ดˆ ์ˆ˜ํ•™  (0) 2024.06.05
[winAPI 08] Object  (0) 2024.06.05
[winAPI 06] Key Manager  (1) 2024.06.04
[winAPI 05] Double Buffering  (0) 2024.06.04
[winAPI 04] Timer  (0) 2024.04.09