上壹篇文章寫完之後,我壹直在想做壹個遊戲示例,想將之前學到的狀態機模式運用在其中。然而壹直遇到各種奇怪的bug(之後寫出來),所以壹直沒有完成這件事。而且加之自己又犯懶了,所以我決定做壹件更簡單的事,以更容易接近的目標來引誘懶的不行的自己。
廢話說完,來說正經事了。前幾天認真看了壹篇 博客-遊戲狀態機 (侵立刪),覺得挺不錯的,建議盆友們認真看壹看。
讀完博客之後,之前計劃的示例貌似有了頭緒,(廢話型)總結出來,實現壹個遊戲狀態機結構需要進行如下幾步:
我要做壹個簡單的UI切換示例,所以簡述需求就是: 打開程序進入主界面,主界面中點擊開始遊戲,進入遊戲界面,遊戲界面中點擊結束遊戲,進入結算界面,結算界面可以點擊回到主界面,進入主界面,也可以點擊重新開始遊戲,再次進入遊戲界面。
從需求描述來看,狀態有三個:
事件有四個:
然後(裝模作樣的)畫了壹個狀態轉換表:
之前壹篇文章中有提到過的,在Cocos2d-x遊戲開發中,剛好使用Scene來作為控制器,由Scene來控制各層的出現和消失。
這裏貼出Scene的源碼(完整的源文件,包括了後續步驟才會出現的狀態基類,以及派生的狀態類):
QFLGameTwoScene.hpp
QFLGameTwoScene.cpp
上面可以看到,Scene中主要包含了:
包含了以上內容,本示例中的這個Scene就能起到控制器的作用了。
狀態基類是很有必要的,為了達到各個同級狀態都能通過同壹個控制器來進行狀態轉換的目標,各個狀態類進行切換時必須有壹套統壹的流程。
這裏貼出本示例中狀態基類的源碼:
QFLGameTwoStateBase.hpp
這個源文件中包含了:
所有的派生狀態類都會 include 這個文件,實現虛基類 GameTwoState 中的方法,所以所有的狀態類都有統壹的切換流程:
而且在完成某個事件,需要進行狀態轉換時,可以通過發送自定義事件來完成消息的傳遞,自定義事件名放在這裏也是為了方便起見。
這裏直接貼出幾個State的源碼了,其中包含註釋,廢話就不重復再寫了:
QFLGameTwoMainLayer.hpp
QFLGameTwoMainLayer.cpp
QFLGameTwoGameLayer.hpp
QFLGameTwoGameLayer.cpp
QFLGameTwoResultLayer.hpp
QFLGameTwoResultLayer.cpp
到這裏,上面所提到的步驟全部進行完了。這個UI切換的狀態機示例也就完成了。
在AppDelegate.cpp中,直接進入Scene中:
進入主界面 :
此時的Log:
點擊Start,進入遊戲界面 :
此時的Log:
<Exit> ->MainLayer
<Enter> ->GameLayer
<Execute> ->GameLayer
點擊Over,進入結算界面 :
此時的Log:
<Enter> ->GameLayer
<Execute> ->GameLayer
[Event]->Game_Over
<Exit> ->GameLayer
<Enter> ->ResultLayer
<Execute> ->ResultLayer
點擊Replay,重新進入遊戲界面 :
此時的Log:
<Enter> ->GameLayer
<Execute> ->GameLayer
[Event]->Game_Over
<Exit> ->GameLayer
<Enter> ->ResultLayer
<Execute> ->ResultLayer
[Event]->Result_Replay
<Exit> ->ResultLayer
<Enter> ->GameLayer
<Execute> ->GameLayer
點擊Over,再次進入結算界面,然後在結算界面點擊Home,回到主界面
上面的兩次操作完成後,Log如下:
<Enter> ->GameLayer
<Execute> ->GameLayer
[Event]->Game_Over
<Exit> ->GameLayer
<Enter> ->ResultLayer
<Execute> ->ResultLayer
[Event]->Result_Replay
<Exit> ->ResultLayer
<Enter> ->GameLayer
<Execute> ->GameLayer
[Event]->Game_Over
<Exit> ->GameLayer
<Enter> ->ResultLayer
<Execute> ->ResultLayer
[Event]->Result_Home
<Exit> ->ResultLayer
<Enter> ->MainLayer
<Execute> ->MainLayer
這裏用FSM實現UI切換示例只是眾多方法中的壹種,暫時還沒有去比較它們的優劣。(使用markdown編輯器的經驗值+1)
可能性多種多樣,如果有小夥伴比較過這些方法。求留言告知,求分享經驗。