ฉันใช้ระบบนี้แน่นอนในหลาย ๆ ระบบ ตัวอย่างเมนูส่วนหน้าและในเกม (หรือที่รู้จักว่า "หยุด") มีสถานะกองซ้อนของตนเอง UI ในเกมใช้บางอย่างเช่นนี้แม้ว่าจะมีแง่มุม "ทั่วโลก" (เช่นเฮลธ์บาร์และแผนที่ / เรดาร์) ที่การสลับสถานะอาจแต้มสี แต่อัปเดตด้วยวิธีทั่วไปทั่วทั้งรัฐ
เมนูในเกมอาจ "ดีกว่า" ที่แสดงโดย DAG แต่ด้วยเครื่องจักรสถานะโดยนัย (ตัวเลือกเมนูแต่ละรายการที่ไปยังหน้าจออื่นรู้วิธีไปที่นั่นและการกดปุ่มย้อนกลับจะโผล่สถานะด้านบนเสมอ) ผลคือ เหมือนเดิมทุกประการ.
บางส่วนของระบบอื่น ๆ เหล่านี้ยังมี "แทนที่รัฐบน" การทำงาน แต่ที่ถูกนำมาใช้มักจะเป็นตามด้วยStatePop()
StatePush(x);
การจัดการการ์ดหน่วยความจำมีความคล้ายคลึงกันเนื่องจากจริง ๆ แล้วฉันได้ทำการ "การดำเนินการ" เข้าไปในคิวการดำเนินการ เมื่อคุณเริ่มใช้โครงสร้างแบบนี้ ("มีสิ่งหนึ่งเกิดขึ้นตอนนี้และเมื่อเสร็จแล้วก็ปรากฏตัวเอง") มันจะเริ่มติดทุกส่วนของรหัส แม้แต่ AI ก็เริ่มใช้สิ่งนี้ AI คือ "clueless" จากนั้นเปลี่ยนเป็น "ระวัง" เมื่อผู้เล่นทำเสียง แต่ไม่เห็นและในที่สุดก็ยกระดับเป็น "ใช้งาน" เมื่อพวกเขาเห็นผู้เล่น (และไม่เหมือนเกมที่มีเวลาน้อยกว่าคุณไม่สามารถซ่อนได้ ในกล่องกระดาษแข็งและทำให้ศัตรูลืมคุณ!
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]();
}