是攻擊還是逃走?—— 狀態模式(State Pattern)簡介


摘要:

某游戲有以下規則:1.玩家距離敵人比較遠時,敵人會看不見玩家,按既定路線巡邏。2.玩家距離敵人比較近時,敵人會發現玩家並進行攻擊。
3.當敵人被殺得差不多,只剩下一兩個時,敵人會逃走。4.敵人可能會隱藏起來伏擊玩家。…… 請你用狀態模式設計這些敵人!

作者

張傳波
www.umlonline.org/school/

作者自述:
在高中時已經很喜歡coding,可惜沒有考上計算機相關的大學專業,但仍然偏執於寫程序,畢業后做了幾年的程序員,后來成為項目經理直到常務副總。熟悉的語言有Basic、VB、C#,一直遺憾的事情是沒有花時間去精通C++。很早就“看中”設計模式,但直到現在僅能在實際工作中實踐過其中幾種設計模式。所以,本文歡迎各位高手拍磚!

 

正文:

在游戲軟件中,有很多NPC。NPC是“Non-Player-Controlled Character”的縮寫,直接翻譯就是“非玩家控制角色”,也就是由程序所控制的角色。

某動作游戲NPC的行為如下:

狀態1.png



游戲有以下規則:
1.玩家距離敵人比較遠時,敵人會看不見玩家,按既定路線巡邏。
2.玩家距離敵人比較近時,敵人會發現玩家並進行攻擊。
3.當敵人被殺得差不多,只剩下一兩個時,敵人會逃走。
4.敵人可能會隱藏起來伏擊玩家。
5.……(省略號的意思是表示規則還會修改和增加)

你會怎樣設計這些NPC呢?

某設計方案如下:

狀態2.png



控制NPC行為的代碼如下:
//判斷當前狀態
.......
//根據不同狀態采取不同反應
switch(state)
case 攻擊
npc.Attack();
case 逃跑
npc.Escape();
......

以上設計辦法有什么問題呢?
最大問題就是如果修改或者增加規則,在NPC類及控制NPC行為的代碼都需要修改!

設計分析:
NPC的行為無非是攻擊、逃跑、隱藏、巡邏等,我們可以視作NPC在不同狀態下具有不同的行為,如果能把狀態抽離出來,並且可以讓NPC切換狀態從而具備不同的行為,這樣就完美了!

應用了狀態模式的設計如下:

狀態3.png



說明:
1.Attack、Escape等NPC行為不直接寫在NPC類中了。
2.Attack、Escape等行為被抽象成IState,NPC類含有各種狀態的引用,並且通過SetCurrentState()方法來設置當前狀態。
3.調用NPC.TakeAction(),NPC就會根據當前的狀態做出適當的行為。
4.增加一個狀態,只需要增加一個IState的實現便可。

問題:
NPC發動攻擊時,如果發現不夠打要逃跑,代碼應該如何寫?
回答:
Attack類含有對NPC的引用,以及由攻擊到逃跑狀態的判斷代碼,需要轉換狀態時,調用m_NPC.SetCurrentState(逃跑)便可。
各狀態類可各自實現由本狀態轉換為其它狀態的代碼,這樣可降低狀態轉換代碼的復雜度。

狀態模式的類圖如下:

狀態4.png



對象根據不同的狀態,需要有不同的行為,而狀態之間轉換判斷邏輯又異常復雜,可用狀態模式來解決這問題。

 

電子書《硬啃設計模式》下載

本書介紹了我對23種設計模式的粗淺理解,本文的內容來自書中,有時間再分享更多書中內容。

以下是封面和部分目錄:

封面.png



目錄.png


猛點以下鏈接直接下載電子書:
http://www.umlonline.org/school/attachment.php?aid=MTkxMXxlOWJlOTA2MHwxMzM2NjU2Mzc2fGQ0MDl4WWFwb1NUZU1EZWlMRzZmM1FTSW9MVWJWSnVYTGNid0ZnY24yYjM0Mmtn

 

如果本文對你有幫助,麻煩點擊一下“推薦”,謝謝!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM