기본적으로이 정확한 시스템을 여러 시스템에서 직교 적으로 사용했습니다. 예를 들어, 프론트 엔드 및 게임 내 메뉴 (일명 "일시 정지") 상태에는 자체 상태 스택이 있습니다. 게임 내 UI는 상태 전환이 틴트 될 수있는 "전역"측면 (헬스 바 및 맵 / 레이더와 같은)을 가지고 있지만 상태간에 공통적 인 방식으로 업데이트되었지만 이와 같은 것을 사용했습니다.
게임 내 메뉴는 DAG로 "더 나은"표현 일 수 있지만 암시 적 상태 시스템 (다른 화면으로 이동하는 각 메뉴 옵션은 이동 방법을 알고 있으며 뒤로 버튼을 누르면 항상 맨 위 상태로 나타남)을 사용합니다. 정확히 동일합니다.
이러한 다른 시스템들 중 일부는 "상위 상태 바꾸기"기능을 가지고 있었지만 일반적으로 StatePop()
다음 과 같이 구현 되었습니다 StatePush(x);
.
메모리 카드 처리는 실제로 많은 "작업"을 작업 대기열에 푸시했기 때문에 비슷했습니다 (LIFO가 아닌 FIFO와 마찬가지로 기능적으로 스택과 동일한 기능을 수행함). 일단 이런 종류의 구조를 사용하기 시작하면 ( "현재 일어나고있는 일이 있고, 그것이 끝나면 스스로 터진다") 코드의 모든 영역을 감염시키기 시작한다. AI조차도 이와 같은 것을 사용하기 시작했습니다. 플레이어가 소리를 냈지만 보이지 않았을 때 인공 지능은 "실마리가없는"다음 "경고"로 바뀌었다가 플레이어를 보았을 때 마지막으로 "활성"으로 올라갔습니다. 골판지 상자에 적을 당신을 잊게하십시오!
GameState.h :
enum GameState
{
k_frontend,
k_gameplay,
k_inGameMenu,
k_moviePlayback,
k_numStates
};
void GameStatePush(GameState);
void GameStatePop();
void GameStateUpdate();
GameState.cpp :
// k_maxNumStates could be bigger, but we don't need more than
// one of each state on the stack.
static const int k_maxNumStates = k_numStates;
static GameState s_states[k_maxNumStates] = { k_frontEnd };
static int s_numStates = 1;
static void (*s_startupFunctions)()[] =
{ FrontEndStart, GameplayStart, InGameMenuStart, MovieStart };
static void (*s_shutdownFunctions)()[] =
{ FrontEndStop, GameplayStop, InGameMenuStop, MovieStop };
static void (*s_updateFunctions)()[] =
{ FrontEndUpdate, GameplayUpdate, InGameMenuUpdate, MovieUpdate };
static void GameStateStart(GameState);
static void GameStateStop(GameState);
void GameStatePush(GameState gs)
{
Assert(s_numStates < k_maxNumStates);
GameStateStop(s_states[s_numStates - 1])
s_states[s_numStates] = gs;
s_numStates++;
GameStateStart(gs);
}
void GameStatePop()
{
Assert(s_numStates > 1); // can't pop last state
s_numStates--;
GameStateStop(s_states[s_numStates]);
GameStateStart(s_states[s_numStates - 1]);
}
void GameStateUpdate()
{
GameState current = s_states[s_numStates - 1];
s_updateFunctions[current]();
}
void GameStateStart(GameState gs)
{
s_startupFunctions[gs]();
}
void GameStateStop(GameState gs)
{
s_shutdownFunctions[gs]();
}