遊戲設計模式 狀態模式

2022-01-10 17:38:02 字數 2879 閱讀 8968

前言:狀態機模式是乙個遊戲常用的經典設計模式,常被用作管理一種物體的各種狀態(例如管理人物的行走,站立,跳躍等狀態)。

(unity裡的animator就是一種典型的狀態機,用於控制動畫狀態之間的切換)

假如我們正在開發一款動作遊戲,當前的任務是實現根據輸入來控制主角的行為——當按下b鍵時,他應該跳躍。

直觀的**:

if (input ==press_b) 

}

站立時按下 ↓ 鍵 =》 蹲下。

蹲下時按下 ↓ 鍵 =》 站立。

站立時按下 b 鍵 =》 跳躍。

跳躍時按下 ↓ 鍵 =》觸發 俯衝。

if (input ==press_b) 

}else

if (input ==press_down)

//如果沒在跳躍

else

if(!m_isjumping)

//如果蹲下時,則站立

else}}

可以看到一堆if-else語句非常複雜,要是新增更多行為,其邏輯結構更加難以維護,而且主角的**又得重新編譯(耦合性大)

有限狀態:有限數量的狀態。

乙個可行的辦法是將這些狀態&狀態切換&狀態對應的行為封裝成類,

(如下圖)

這時候可以借助狀態機這個設計模式來美化這段**。

上面的場景中,只有4個狀態(跳躍/下蹲/站立/俯衝),這就是有限狀態。

於是我們設計出下面4個狀態類(加乙個狀態的介面類):

//

狀態介面類

class

state ;

//站立狀態

class standstate : public

state

else

if (input ==press_down)

}};//

跳躍狀態

class jumpstate : public

state

}};//

下蹲狀態

class sneakstate : public

state

}};//

俯衝狀態

class divestate : public

state

};

第一次進入遊戲時,給角色乙個初始狀態

player.setstate(new standstate());
然後每次接受輸入,讓角色當前的狀態物件去處理就可以了。

player.getstate().handleinput(player,input);
簡單小結:可以看到利用狀態類物件,我們把負責的條件邏輯封裝到各個狀態類裡,讓**變得優雅,而且還減少了幾個變數的使用(m_isjumping等)。此外由於有限狀態物件的屬性是固定不變的,這意味著所有角色都能共享同乙個狀態(當同種狀態時),

所以常見的狀態物件儲存方式是單例儲存或者靜態儲存(每種狀態只生成1個物件),避免了上文每次都要生成新狀態物件的開銷。

實際中,一些遊戲的類可能需要多個狀態(平行關係),於是可以寫出以下**

class

player;

然後便可以用下列方式處理狀態了

void player::handleinput(const input&input)
把主角的行為更加具象化以後,可能會包含大量相似的狀態,為了重用**,便衍生層次狀態機的概念。

層次狀態主要思想是狀態類繼承,從而產生層次關係的狀態。

例如,蹲下狀態和站立狀態 繼承於 在地面狀態。

class ongroundstate : public

state //

....跳躍}};

class standstate : public

ongroundstate //

...蹲下去的**...

else

}};class sneakstate : public

ongroundstate //

...站起來的**...

else

} };

下推狀態機,簡單來說,就是用棧結構儲存一系列狀態物件。

一般來說,乙個角色只需要乙個狀態物件,為什麼要用棧結構儲存一堆狀態物件?

假設有乙個射擊遊戲的角色,他現正在站立狀態,執行棧頂狀態中。

突然遇到敵人進行**,於是入棧乙個**狀態,並繼續執行新的棧頂狀態。

敵人被擊中死亡,**狀態結束。為了恢復到**前的上乙個狀態,於是去掉棧頂狀態。

這樣我們利用棧就完美模擬了乙個人**之後恢復成站立狀態的過程。

簡單來說,

下推自動機適用於需要記憶狀態的狀態機,這在一些遊戲ai是常用的手法。(不過現在更流行的遊戲ai是用行為樹實現)

遊戲架構&遊戲設計模式系列-其他文章:

設計模式 狀態模式

狀態模式 當乙個物件的內在狀態改變時允許改變其行為,這個物件看起來像是改變了其類。狀態模式主要解決的是當控制乙個物件狀態轉換的條件表示式過於複雜時的情況,把狀態的判斷邏輯轉移到表示不同狀態的一些列類當中,可以把複雜的判斷邏輯簡化。當乙個物件的行為取決於它的狀態,並且它必須在執行時刻根據狀態改變它的行...

設計模式 狀態模式

1.概述 當乙個物件的內在狀態改變時允許改變其行為,這個物件看起來像是改變了其類。2.解決的問題 主要解決的是當控制乙個物件狀態轉換的條件表示式過於複雜時的情況。把狀態的判斷邏輯轉移到表示不同的一系列類當中,可以把複雜的邏輯判斷簡單化。3.模式中的角色 3.1 上下文環境 context 它定義了客...

設計模式 狀態模式

描述 允許物件在內部狀態改變時改變它的行為,物件看起來好像修改了它的類。主要解決的是當控制乙個物件狀態轉換的條件表示式過於複雜時的情況。把狀態的判斷邏輯轉移到表示不同的一系列類當中,可以把複雜的邏輯判斷簡單化。通常應用在有好多狀態的流程中。類圖 以下程式模擬糖果機器投幣取糖果的狀態流程。1.定義狀態...