한때 문제를 매우 우아하게 해결 하는 기사 를 보았습니다. 기본 루프에서 호출되는 기본 FSM 구현입니다. 이 답변의 나머지 부분에서 기사의 기본 요약을 설명했습니다.
기본 게임 상태는 다음과 같습니다 :
class CGameState
{
public:
// Setup and destroy the state
void Init();
void Cleanup();
// Used when temporarily transitioning to another state
void Pause();
void Resume();
// The three important actions within a game loop
void HandleEvents();
void Update();
void Draw();
};
각 게임 상태는이 인터페이스의 구현으로 나타납니다. Battlechess 예제의 경우 다음 상태를 의미 할 수 있습니다.
- 소개 애니메이션
- 메인 메뉴
- 체스 판 설정 애니메이션
- 플레이어 이동 입력
- 플레이어 이동 애니메이션
- 상대 이동 애니메이션
- 일시 정지 메뉴
- 최종 게임 화면
상태 엔진에서 상태가 관리됩니다.
class CGameEngine
{
public:
// Creating and destroying the state machine
void Init();
void Cleanup();
// Transit between states
void ChangeState(CGameState* state);
void PushState(CGameState* state);
void PopState();
// The three important actions within a game loop
// (these will be handled by the top state in the stack)
void HandleEvents();
void Update();
void Draw();
// ...
};
각 상태는 어느 시점에서 CGameEngine에 대한 포인터가 필요하므로 상태 자체가 새로운 상태를 입력해야하는지 여부를 결정할 수 있습니다. 이 기사에서는 CEventEngine을 HandleEvents, Update 및 Draw에 대한 파라미터로 전달할 것을 제안합니다.
결국 메인 루프는 상태 엔진 만 처리합니다.
int main ( int argc, char *argv[] )
{
CGameEngine game;
// initialize the engine
game.Init( "Engine Test v1.0" );
// load the intro
game.ChangeState( CIntroState::Instance() );
// main loop
while ( game.Running() )
{
game.HandleEvents();
game.Update();
game.Draw();
}
// cleanup the engine
game.Cleanup();
return 0;
}