📁 03.Object > 📄 ObjectType.h enum class ObjectType: 게임 내 객체 유형(예: None, Player, Monster, Projectie)을 구분하여 타입 체크와 로직 처리를 용이하게 합니다.Types.h에 구조체로 정의해 재사용성을 높입니다.📁 03.Object > 📁 Game > 📄 Player 경로에 생성되어 구조를 체계적으로 관리합니다.Init 메서드:Update 메서드:Render 메서드:📁 03.Object > 📁 Game > 📄 Missile에 작성되며, 초기화(Init), 업데이트(Update), 렌더링(Render)을 처리합니다.Init 메서드:Update 메서드:Render 메서드:📁 03.Object > 📁 Game > 📄 Monster 경로에 생성됩니다.Init 메서드: 몬스터의 체력, 속도, 위치 등의 기본값을 설정합니다.Render 메서드: Utils 라이브러리를 사용해 몬스터를 사각형으로 렌더링합니다.DevScene을 제거하고, 실제 게임 플레이를 위한 GameScene을 활성화합니다.GameScene에서 플레이어를 초기화하고, Update와 Render 메서드를 호출하여 객체 상태를 갱신 및 렌더링합니다.Add), 제거(Remove), 초기화(Clear), 생성(CreateObject) 등의 기능을 제공합니다.CreateObject 템플릿: 객체 생성 시 타입 검사를 통해 컴파일 타임에서 오류를 방지하고, 생성 후 초기화(Init)를 호출합니다.Update 메서드에서 스페이스바 입력 시 미사일을 생성하고 ObjectManager에 추가합니다.Add 메서드:Remove 메서드:Clear 메서드:다음은 게임 오브젝트 설계와 구현을 설명하는 강의와 예제 코드를 분석하여 작성된 완성된 문서입니다. 주요 내용과 각 단계의 코드 분석이 포함되어 있습니다.
Object 클래스는 게임 내 모든 요소(Player, Monster, Missile 등)의 최상위 부모 역할을 합니다. Scene처럼 오브젝트를 관리하며, 다른 게임 객체들이 상속받아 기능을 추가하도록 설계되었습니다.
#pragma once
enum class ObjectType
{
None,
Player,
Monster,
Projectie,
};
class Object
{
public:
Object(ObjectType type);
virtual ~Object(); // 최상위 객체는 가상 함수로
virtual void Init() abstract;
virtual void Update() abstract;
virtual void Render(HDC hdc) abstract;
public:
ObjectType GetObjectType() { return _type; }
Pos GetPos() { return _pos; }
void SetPos(Pos pos) { _pos = pos; }
protected:
ObjectType _type = ObjectType::None;
Stat _stat = {};
Pos _pos = {};
};
enum class ObjectType: 게임 내 객체 유형을 구분합니다. 예를 들어, Player, Monster, Projectie는 각각 플레이어, 몬스터, 투사체를 의미합니다.Init, Update, Render: 순수 가상 함수로 선언되어, 상속받는 클래스에서 구현해야 합니다._type, _stat, _pos: 객체의 타입, 능력치, 위치 정보를 저장합니다.#include "pch.h"
#include "Object.h"
Object::Object(ObjectType type) : _type(type)
{
}
Object::~Object()
{
}
_type을 초기화합니다.Player는 Object를 상속받아 플레이어 전용 기능을 추가한 클래스입니다.
#pragma once
#include "Object.h"
class Player : public Object
{
public:
Player();
virtual ~Player();
virtual void Init() override;
virtual void Update() override;
virtual void Render(HDC hdc) override;
};
#include "pch.h"
#include "Player.h"
#include "TimeManager.h"
#include "InputManager.h"
#include "Missile.h"
#include "ObjectManager.h"
Player::Player() : Object(ObjectType::Player) {}
Player::~Player() {}
void Player::Init()
{
_stat.hp = 100;
_stat.maxHp = 100;
_stat.speed = 500.0f;
_pos.x = 400;
_pos.y = 500;
}
void Player::Update()
{
float deltaTime = GET_SINGLE(TimeManager)->GetDeltaTime();
if (GET_SINGLE(InputManager)->GetButton(KeyType::A)) _pos.x -= _stat.speed * deltaTime;
if (GET_SINGLE(InputManager)->GetButton(KeyType::D)) _pos.x += _stat.speed * deltaTime;
if (GET_SINGLE(InputManager)->GetButton(KeyType::W)) _pos.y -= _stat.speed * deltaTime;
if (GET_SINGLE(InputManager)->GetButton(KeyType::S)) _pos.y += _stat.speed * deltaTime;
if (GET_SINGLE(InputManager)->GetButtonDown(KeyType::SpaceBar))
{
Missile* missile = GET_SINGLE(ObjectManager)->CreateObject<Missile>();
missile->SetPos(_pos);
GET_SINGLE(ObjectManager)->Add(missile);
}
}
void Player::Render(HDC hdc)
{
Utils::DrawCircle(hdc, _pos, 50);
}
Init: 플레이어의 능력치와 위치를 초기화합니다.Update: 키 입력 처리(WASD 이동 및 스페이스바로 미사일 발사).Render: 플레이어를 원형으로 렌더링.Missile은 Object를 상속받아 투사체 전용 기능을 추가한 클래스입니다.
#pragma once
#include "Object.h"
class Missile : public Object
{
public:
Missile();
virtual ~Missile();
virtual void Init() override;
virtual void Update() override;
virtual void Render(HDC hdc) override;
};
#include "pch.h"
#include "Missile.h"
#include "TimeManager.h"
#include "ObjectManager.h"
Missile::Missile() : Object(ObjectType::Projectie) {}
Missile::~Missile() {}
void Missile::Init()
{
_stat.hp = 1;
_stat.maxHp = 1;
_stat.speed = 600;
}
void Missile::Update()
{
float deltaTime = GET_SINGLE(TimeManager)->GetDeltaTime();
_pos.y -= deltaTime * _stat.speed;
const vector<Object*> objects = GET_SINGLE(ObjectManager)->GetObjects();
for (Object* object : objects)
{
if (object == this || object->GetObjectType() != ObjectType::Monster) continue;
Pos p1 = GetPos();
Pos p2 = object->GetPos();
const float dx = p1.x - p2.x;
const float dy = p1.y - p2.y;
float dist = sqrt(dx * dx + dy * dy);
if (dist < 25)
{
GET_SINGLE(ObjectManager)->Remove(object);
GET_SINGLE(ObjectManager)->Remove(this);
return;
}
}
if (_pos.y < -200)
{
GET_SINGLE(ObjectManager)->Remove(this);
return;
}
}
void Missile::Render(HDC hdc)
{
Utils::DrawCircle(hdc, _pos, 25);
}
Init: 미사일의 속도와 체력을 초기화합니다.Update: 미사일 이동 및 충돌 처리. 화면을 벗어난 경우 제거.Render: 미사일을 작은 원형으로 렌더링.#pragma once
#include "Scene.h"
class GameScene : public Scene
{
public:
GameScene();
virtual ~GameScene() override;
virtual void Init() override;
virtual void Update() override;
virtual void Render(HDC hdc) override;
};
#include "pch.h"
#include "GameScene.h"
#include "Player.h"
#include "Monster.h"
#include "ObjectManager.h"
GameScene::GameScene() {}
GameScene::~GameScene() {}
void GameScene::Init()
{
Player* player = GET_SINGLE(ObjectManager)->CreateObject<Player>();
player->SetPos(Pos{ 400, 400 });
GET_SINGLE(ObjectManager)->Add(player);
for (int i = 0; i < 5; ++i)
{
Monster* monster = GET_SINGLE(ObjectManager)->CreateObject<Monster>();
monster->SetPos(Pos{ static_cast<float>(i + 1) * 100, 100 });
GET_SINGLE(ObjectManager)->Add(monster);
}
}
void GameScene::Update()
{
const vector<Object*> objects = GET_SINGLE(ObjectManager)->GetObjects();
for (Object* object : objects)
object->Update();
}
void GameScene::Render(HDC hdc)
{
const vector<Object*> objects = GET_SINGLE(ObjectManager)->GetObjects();
for (Object* object : objects)
object->Render(hdc);
}
Init: 플레이어와 몬스터 초기화 및 추가.Update: 모든 객체의 Update 호출.Render: 모든 객체의 Render 호출.#pragma once
class ObjectManager
{
public:
DECLARE_SINGLE(ObjectManager);
~ObjectManager();
void Add(Object* object);
void Remove(Object* object);
void Clear();
const vector<Object*>& GetObjects() { return _objects; }
template<typename T>
T* CreateObject()
{
static_assert(std::is_convertible_v<T*, Object*>);
T* object = new T();
object->Init();
return object;
}
private:
vector<Object*> _objects;
};
#include "pch.h"
#include "ObjectManager.h"
#include "Object.h"
ObjectManager::~ObjectManager()
{
Clear();
}
void ObjectManager::Add(Object* object)
{
if (!object || std::find(_objects.begin(), _objects.end(), object) != _objects.end())
return;
_objects.push_back(object);
}
void ObjectManager::Remove(Object* object)
{
if (!object) return;
auto it = std::remove(_objects.begin(), _objects.end(), object);
_objects.erase(it, _objects.end());
delete object;
}
void ObjectManager::Clear()
{
for (Object* object : _objects)
delete object;
_objects.clear();
}
Add: 객체를 중복 없이 추가.Remove: 객체를 제거하고 메모리를 해제.Clear: 모든 객체를 삭제하며 메모리를 정리.