基本的に、この正確なシステムをいくつかのシステムで直交的に使用しました。たとえば、フロントエンドおよびゲーム内メニュー(別名「一時停止」)状態には、独自の状態スタックがありました。ゲーム内のUIもこのようなものを使用していましたが、状態の切り替えが色づくが状態間で共通の方法で更新される「グローバル」な側面(ヘルスバーやマップ/レーダーなど)がありました。
ゲーム内メニューはDAGによって「より良く」表現される場合がありますが、暗黙のステートマシン(別の画面に移動する各メニューオプションはそこへの行き方を知っており、戻るボタンを押すと常に一番上の状態になります)まったく同じ。
これらの他のシステムの一部には「トップステートの置換」機能もありましたが、通常、次のように実装されStatePop()
ていましたStatePush(x);
。
メモリカードの処理は、実際には大量の「操作」を操作キューにプッシュしたため、同様でした(LIFOではなくFIFOのように機能的にスタックと同じことを行いました)。この種の構造の使用を開始すると(「現在1つのことがあり、終了すると自動的にポップします」)、コードのすべての領域に感染し始めます。AIでさえ、このようなものを使用し始めました。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]();
}