Portfolio

게임인재원 1기 2차 미니프로젝트

Lunatics_ 2021. 7. 9. 02:06

사용기술 : C++, WinAPI, Direct2D, FMOD, RapidJSON

개발기간 : 2020년 03월 09일 ~ 2020년 03월 27일 (3주)

개발인원 : 9인 (기획 3인, 아트 3인, 프로그래머 3인)

 

리드 프로그래머, 클라이언트 프로그래머 : 노종원

클라이언트 프로그래머 : 송인수 - 

툴 프로그래머 : 홍성필 - 

 

원죄:Sin

2D isometric view의 공포게임입니다.

 

배드엔딩 영상입니다.

 

Direct2D를 이용한 렌더링, isometric view, 2D Collision(Circle,AABB, OOBB)과 C++의 Fucntor를 이용한 트리거 시스템을 구현했습니다.

RapidJSON라이브러리를 이용하여 외부에서 트리거를 작성하여 트리거시스템이 동작 할 수 있도록 하였고 JSON스키마를 툴 프로그래머에게 전달하여 툴에서 JSON파일을 편집할 수 있도록 했습니다.

아래는 코드샘플입니다

class Trigger : public GameObject
{
private:
	//트리거가 실행될 조건
	std::set<int> Condition;
    //트리거가 실행할 행동
	std::set<int> Action;
    //트리거의 충돌영역
	Collider* Collision;
public:
	Trigger();
	virtual ~Trigger();
	void AddCondition(int n);
	void AddAction(int n);
	virtual void Excute();

	Collider* GetCollision()const;
	void SetCollision(Collider* col);
};

트리거에 트리거의 작동조건과 트리거의 조건이 충족되었을때 실행할 액션을 저장하고 트리거의 충돌박스를 정할 수 있습니다.

std::set을 이용하여 같은조건이나 같은 액션의 중복을 막았습니다.

void Trigger::Excute()
{
	TriggerCondition* condition;
	TriggerAction* action;
	//충돌 검사
	if (Collision != nullptr)
	{
		if (!Collision->IsCollision)
		{
			return;
		}
	}

	if (0 < Condition.size())
	{
    	//트리거의 조건이 모두 만족되었는지 검사
		bool IsAction = true;
		for (auto i : Condition)
		{
			condition = DataManager::GetIns()->GetTriggerCondition(i);
			if (!(*condition)())
			{
				IsAction = false;
			}
		}
        //트리거의 조건에 모두 만족했다면 실행
		if (IsAction)
		{
			for (auto i : Action)
			{
				action = DataManager::GetIns()->GetTriggerAction(i);
				(*action)();
			}
		}
	}
}

트리거가 실행되는 코드입니다.

class TriggerCondition abstract
{
protected:
	static DataManager* Data;
public:
	virtual ~TriggerCondition();
	virtual bool operator()() abstract;
};

트리거의 조건입니다. 현제 게임의 상태, 스위치등을 가진 DataManager의 포인터를 내부적으로 가지고있습니다.

DataManager는 하나만 존재해야하고 변경될 이유가 없기때문에 static으로 선언하였습니다.

operator()()를 순수가상함수로 정의하여 해당 클래스를 상속받은 클래스가 모두 Functor가 되도록 했습니다.

class IsSwitchCondition :public TriggerCondition
{
private:
	int SwitchNum;
	bool State;
public:
	IsSwitchCondition(int num, bool b);
	bool operator()() override;
};

IsSwitchCondition::IsSwitchCondition(int num, bool b) 
	:SwitchNum(num), State(b)
{
}

bool IsSwitchCondition::operator()()
{
	return Data->GetSwitch(SwitchNum) == State;
}

게임내부의 스위치의 상태를 조사하는 조건입니다. 스위치가 켜졌을때, 혹은 꺼졌을때의 조건을 만들 수 있습니다.

class TriggerAction abstract
{
protected:
	static DataManager* Data;
public:
	virtual ~TriggerAction();
	virtual void operator()() abstract;
};

트리거가 실행할 액션입니다. 클래스 이름만 다르고 내부는 TriggerCondition과 같습니다.

이렇게 만든 이유는 TriggerCondition과 TriggerAction이 혼용될 여지를 막기위해서 같은내용이지만 다른클래스로 정의하였습니다.

class SetSwitchAction :public TriggerAction
{
private:
	int SwitchNum;
	bool State;
public:
	SetSwitchAction(int num, bool state);
	void operator()();
};

SetSwitchAction::SetSwitchAction(int num, bool state) 
	:SwitchNum(num), State(state)
{
}

void SetSwitchAction::operator()()
{
	Data->SetSwitch(SwitchNum, State);
}

스위치를 켜거나 끄는 행동을하는 TriggerAction입니다.

이외에 다양한 조건들과 액션들을 조합하여 트리거를 만들고 매 프레임마다 트리거의 Execute를 호출하여 트리거의 작동여부를 판단할 수 있도록 제작하였습니다.

위와 같이 만든 총 17개의 조건과 20개의 액션으로 조합하여 트리거를 만들 수 있습니다.