[C++ 기초] 갤러그 리팩토링

라멘커비·2024년 1월 15일
0

CPP 입문

목록 보기
23/25

갤러그 리팩토링

겉으로 보기에 바뀌는 것은 없고 내부적으로 구조와 코드를 (더 편리하거나 효율적으로) 바꿈.

🛩️list erase할 때

erase는 노드 속에 있는 동적 할당된 데이터를 delete하는 것이 아닌 노드를 지워주는 것이다. 그렇기 때문에 delete를 해준 뒤에 erase를 해야 한다.
또한 erase()는 다음 iterator를 리턴하기 때문에 for문에서 StartIterator++ 하는 코드를 주의해야 한다.

🛩️릴리즈 구조

게임에서 1프레임에 업데이트 - 랜더링 구조로 진행한다고 할 때 릴리즈는 마지막에 해줘야 한다. (또는 맨 앞) 절대 랜더링이나 업데이트 중간에 릴리즈하지 않는다.

🛩️map<int, list>

enum class로 Player, Bullet, Monster 넣어두고
map<int, 리스트> 구조로 변환하면 map에서 키값이 enum class 순서로 정렬도 되고 객체별로 관리가 가능해진다.

map의 key가 0번(Player)이면 value가 Player객체 리스트
map의 key가 1번(Bullet)이면 value가 Bullet객체 리스트
map의 key가 2번(Monster)이면 value가 Monster객체 리스트

🛩️엔진

Object, Screen 관련 기능과 코드 모두 엔진으로 몰아넣었다. Player의 위치 등 엔진이 알 수 없는 것들만 바깥(?) 코드에서 해줌.
엔진을 GetCore()해서 엔진의 기능을 이용해야 함.

🛩️바뀐 갤러그 코드

오늘 바뀐 갤러그 코드 보기

EngineCore

AllUpdateObject, AllRenderObject

std::map<int, std::list<ConsoleObject*>> AllUpdateObject;
std::map<int, std::list<ConsoleObject*>> AllRenderObject;

AllUpdateObjectAllRenderObject는 모두 플레이어, 몬스터, 총알 각각이
"Enum 번호 - 해당 객체 list" 형태로 연결된 map이다.

CreateObject 함수

CreateObject함수는 AllUpdateObject, AllRenderObject 맵에 각 enum순서별로 객체 리스트를 넣어주는 함수이다.

	template<typename ObjectType, typename EnumType>
	ObjectType* CreateObject(EnumType _Order)
	{
		return CreateObject<ObjectType>(_Order, _Order);
	}

	template<typename ObjectType, typename UpdateEnumType, typename RenderEnumType>
	ObjectType* CreateObject(UpdateEnumType _UpdateOrder, RenderEnumType _RenderOrder)
	{
		return CreateObject<ObjectType>(static_cast<int>(_UpdateOrder), static_cast<int>(_RenderOrder));
	}

	template<typename ObjectType>
	ObjectType* CreateObject(int _UpdateOrder, int _RenderOrder)
	{
		ObjectType* NewObject = new ObjectType();
		NewObject->ConsoleObject::SetCore(this);
		AllUpdateObject[_UpdateOrder].push_back(NewObject);
		AllRenderObject[_RenderOrder].push_back(NewObject);
		return NewObject;
	}

GetUpdateGroup 함수

리턴값이 list의 참조형이 아닌 값형으로 되어있다. 값을 아예 복사해서 옮기므로 함수가 무거워지지만 엔진 외의 곳에서 원본을 건드릴 수 있게할 수 없기 때문에 깊은 복사하여 쓰도록 만들어졌다.

	std::list<ConsoleObject*> GetUpdateGroup(int _Order)
	{
		return AllUpdateObject[_Order];
	}
  • ConsoleEngine이 관리하는 곳 안에서는 리스트를 참조형으로 받아 사용할 수 있다. 엔진이 관리하는 곳이기 때문에.

SetCore 함수

ConsoleObject에 EngineCore의 객체를 연결시켜주는? 역할을 한다.

과제

🛩️몬스터 움직이게 만들기

몬스터가 어떤 방향으로 이동하다가 벽에 닿으면 한 칸 아래로 이동, 방향 반대로.

  • 선생님이 알려주신 힌트로 만든 진짜 갤러그같은 움직임 코드
#include "Monster.h"
#include "ContentsEnum.h"
#include "ConsoleEngine/EngineCore.h"


void Monster::Update()
{
	AddPos(Dir);

	--Count;
	if (Count <= 0) {
		
		Dir = (Dir == Left) ? Right : Left;
		AddPos(Down);
		Count = 11;
	}

	ConsoleObject* CollisionObject = Collision(GalagaUpdateType::Bullet);

	if (GetPos().Y == 19) {
		Destroy();
		GetCore()->EngineEnd();
		//return;
	}


	if (nullptr != CollisionObject)
	{
		Destroy();
		CollisionObject->Destroy();
	}

	ConsoleObject* CollisionObject2 = Collision(GalagaUpdateType::Player);
	if (nullptr != CollisionObject2)
	{
		Destroy();
		CollisionObject2->Destroy();
		GetCore()->EngineEnd();
	}

}
profile
일단 시작해보자

0개의 댓글

관련 채용 정보