CEntity
는 모든 클래스의 기본이 되는 클래스로, 공통적인 속성이나 기능을 제공합니다.
모든 객체는 CEntity
로부터 파생되며, 각 객체는 고유한 ID를 가집니다.
CEntity클래스를 파생받는 대표적인 2가지는 오브젝트
와 에셋
이다.
Object
클래스는 게임 상에서 존재하는 물체를 나타내는 클래스입니다.
Object
클래스의 파생 클래스가 됩니다.오브젝트는 게임 내에서 존재하는 실체를 나타내며, 다양한 행동과 상호작용을 구현할 수 있습니다.
오브젝트에서 파생된 애들만 게임상에서 존재할수 잇다.
Asset
클래스는 게임 상의 존재하는 물체가 아니지만, 오브젝트가 사용하는 자원을 나타냅니다.
대표적인 에셋으로는 이미지(캐릭터, 배경 등)와 사운드(효과음, 배경음악 등)가 있습니다.
오브젝트는 필요에 따라 다양한 에셋을 사용하여 시각적이나 청각적인 요소를 표현합니다.
레벨 클래스는 게임 내에서 오브젝트들이 존재하는 공간을 관리합니다.
게임의 스테이지나 레벨 개념을 구현하며, 다양한 오브젝트들을 일괄적으로 관리하고 제어하는 역할을 합니다.
예를 들어, 스테이지 전환 시 오브젝트들의 상태 변화, UI 요소의 관리 등을 수행합니다.
몬스터 플레이어만 오브젝트가 아니라 ui들 조차도 오브젝트이다(게임 시작시 메뉴창 이어하기 옵션, 종료 요딴거)
여기가 바로 스테이지다.
게임 스테이지가 아니라 물체를 관리하면서 하나의 어떤 레벨개념이다.
// CLevel.h 파일 내부
#pragma once
#include "CEntity.h"
class CObj;
class CLevel :
public CEntity
{
private:
// 1
vector<CObj*> m_vecObj;
public:
// 2
void begin(); // 레벨이 시작될 떄
void tick(); // 매 프레임마다 호출
void finaltick(); // 매 프레임 마다 호출
void render(); // 매 프레임 마다 호출
// 4
public:
void AddObject(CObj* _Obj) { m_vecObj.push_back(_Obj); }
// 3
public:
CLevel();
~CLevel();
};
하나의 레벨안에는 다양한 오브젝트들이 있을것이다.
1번처럼 맴버로 오브젝트를 알아야한다.
동적배열처럼 관리하는 오브젝트이다.
저장하는 데이터 단위가 CObj 포인터 타입이다.
8바이트형태로 주소를 저장하는 형태이다.
주소를 왜 저장하냐? 오브젝트를 포인터를 가리키고 잇다면 오브젝트로 부터 상속된 어떤 클래스의 객체로 다 가리킬수 있다.(다형성)
오브젝트로 파생된 애들이 다 들어 갈 수 있다.
오브젝트부터 파생된애들이어야 오브젝트 포인터로 가리 킬수 있다.
CEntity포인터로 했다면 말이 안된다.
tick
과 finaltick
와render
매프레임 마다 호출되지만 매 프레임마다 시점이 조금씩 다르다. begin
은 레벨 시작할떄 딱 한번 호출 된다. 레벨에 포함된 오브젝트들이 해야될 초기작업을 수행할떄 begin
함수 호출한다.// CObj.h 파일 전체
#pragma once
#include "CEntity.h"
class CObj :
public CEntity
{
private:
// 1
POINT m_Pos; // 위치
// 2
POINT m_Scale; // 크기
public:
// 4
void SetPos(POINT _Pos) { m_Pos = _Pos; }
void SetScale(POINT _Scale) { m_Scale = _Scale; }
// 5
POINT GetPos() { return m_Pos; }
POINT GetScale() { return m_Scale; }
public:
// 6
virtual void begin();
virtual void tick();
virtual void finaltick();
virtual void render();
public:
// 3
CObj();
~CObj();
};
오브젝트(물체)가 정말로 존재해야한다.
오브젝트가 레벨에서 활동을 할려면 가져야할 데이터가 있다.
1번처럼 위치값
2번처럼 크기값
3번에 생성자 소멸자.
외부에서 위치와 크기를 조절할수 있게 Set함수를 각각 만들어 줬다.
외부에서 위치와 크기를 가져갈수 있게 Get함수를 각각 만들어 줬다.
6번처럼 시점 함수에 가상 함수를 붙인 이유는 레벨을 begin이 호출되면 다형성을 위해서 가상함수를 해준다.
오브젝트가 레벨이 시작되는 순간에 begin함수를 구현을 할것인데 만약에 오브젝트를 상속받아간 플레이어는 레벨에 begin이 발생햇을떄 begin 함수가 호출될건대 오브젝트마다 할 일이 다를수 있어서 각 클래스 별로 오버라이딩 하게 할려고 가상함수로 만들었다.
비긴이 호출되면 본인 레벨의 오브젝트를 상속받은 애들은 전부다 전부다 비긴을 호출해줄것이다.
가상함수가 아니였다면 오브젝트(부모)쪽에 잇는 함수만 호출 될것이기 때문에 가상함수로 해야만 한다.
// CLevel.cpp 내부
void CLevel::begin()
{
for (size_t i = 0; i < m_vecObj.size(); ++i)
{
m_vecObj[i]->begin();
}
}
begin
함수의 구현부분으로 반복문을 돌아서 오브젝트의 크기만큼 오브젝트를 파생받은 모든 클래스의 begin
함수를 호출할것이다.#pragma once
#include "CEntity.h"
class CObj;
class CLevel :
public CEntity
{
private:
vector<CObj*> m_vecObj;
public:
// 시점 함수
void begin(); // 레벨이 시작될 때
void tick(); // 매 프레임마다 호출
void finaltick(); // 매 프레임마다 호출
void render(); // 매프레임마다 호출
public:
void AddObject(CObj* _Obj) { m_vecObj.push_back(_Obj); }
public:
CLevel();
~CLevel();
};
#include "pch.h"
#include "CLevel.h"
#include "CObj.h"
CLevel::CLevel()
{
}
CLevel::~CLevel()
{
}
void CLevel::begin()
{
for (size_t i = 0; i < m_vecObj.size(); ++i)
{
m_vecObj[i]->begin();
}
}
void CLevel::tick()
{
}
void CLevel::finaltick()
{
}
void CLevel::render()
{
}
#pragma once
#include "CEntity.h"
class CObj :
public CEntity
{
private:
POINT m_Pos; // 위치
POINT m_Scale; // 크기
public:
void SetPos(POINT _Pos) { m_Pos = _Pos; }
void SetScale(POINT _Scale) { m_Scale = _Scale; }
POINT GetPos() { return m_Pos; }
POINT GetScale() { return m_Scale; }
public:
virtual void begin();
virtual void tick();
virtual void finaltick();
virtual void render();
public:
CObj();
~CObj();
};
#include "pch.h"
#include "CObj.h"
CObj::CObj()
{
}
CObj::~CObj()
{
}
void CObj::begin()
{
}
void CObj::tick()
{
}
void CObj::finaltick()
{
}
void CObj::render()
{
}
1차 24.01.23
2차 24.01.24
3차 24.01.25
4차 24.01.26