【遊戲_忍者六道】狀態機設計與應用之lua篇
一 前言
上一篇圖文描述了C++實現遊戲中應用的狀態機,C++中的三大特性:封裝,繼承,多型得以應用,封裝資料引擎訪問的增,刪,查,改,狀態機基類以及多種狀態子類實現私有private或者公共public繼承它,但是發揮更大的作用是多型的使用,子類繼承實現基類的virtual虛擬函式,在不同的事件機制觸發下,遷移變換執行不同的狀態,雖然毫無標準順序可言,卻是按照指定規則軌道正確行使,這是狀態機設計的正確使用的最妙之處,起碼是當前使用是這樣,不同的需求會設計出不同高效的狀態機。
那麼,lua在狀態機方面是如何應用的呢?
眾所周知,lua是遊戲開發中效率頗高的指令碼語言,其設計目的是為了嵌入應用程式中,從而為應用程式提供靈活的擴充套件和定製功能。Lua由標準C編寫而成,幾乎在所有作業系統和平臺上都可以編譯,執行。Lua指令碼可以很容易的被C/C++程式碼呼叫,也可以反過來呼叫C/C++的函式。不僅僅作為擴充套件指令碼,也可以作為普通的配置檔案,代替XML,ini等檔案格式,並且更容易理解和維護。在目前所有指令碼引擎中,Lua的速度是最快的。這一切都決定了Lua是作為嵌入式指令碼的最佳選擇。現在很多遊戲(無論手遊,還是端遊),都為它的強大所折服,ps和魔獸都有使用lua,不得不承認,lua這方面做得確實很不錯,雖然lua是程式導向和函數語言程式設計,但是它的閉包和table特性使得它像C++一樣,很完美的實現OO——物件導向。
二 狀態機實現
這裡簡單的說下一個遊戲中,lua指令碼實現一個功能的場景:
舉個栗子,這是十一的活動,很多遊戲會選擇在傳統佳節,做一些活動,引起玩家的關注和參與,從而贏得訪問和流量,十一活動流程很簡單,玩家登陸游戲客戶端之後,如果當前時間不到十月一日,那麼就不會有一些玩法的Npc或者圖示之類,會選擇玩其他的一些活動或者打怪,即使如此,此時已經處在設計的狀態機中了,只是當前為“檢查活動開啟狀態”,這就有點像,不知不覺就進來套路一樣;當時間到來時,一般活動開始事件會設定為:2016年10月1日00:00:00,不得有絲毫時間的馬虎,那麼自然可以想到,結束時間為:2016年年10月5日24點了。
lua語法中,使用table儲存資料,我們在StateManagerByLua在活動開始時,事先new呼叫建構函式,使用tCurrentState的一個table將EDoing_Sate(進行狀態)和ECheckStart_Start(檢查是否開始狀態)作為Key,儲存AstateByLua,BstateByLua…狀態的物件。
在此活動自然會在“進行狀態”,釋出活動開始的一些廣播抑或一些郵件通知User知道,BginTime=< NowTime
tCurrentState[EDoing_Sate] = AstateByLua:new{ p_Object = self}
兩種狀態被儲存下來之後,時間的檢查需要使用timer定時器,可以自己封裝相關的定時器和相關回撥,當時間到達10.1,那麼活動開始了,此時開始的狀態可以參看如下用例:
品嚐到十一活動的樂趣之後,可不曾曉得,事件過得會如此之快,升級的也升了,高階裝備也拿了,錢也賺了,活動時間>10.5到0點就End了,npc或者活動圖示就會隨之消失。
三 lua原始碼實現狀態機
狀態機類圖先睹為快:
下面簡單寫一些此次活動的程式碼結構:
----------------------------------------
--- Title: 管理器相關 StateManagerByLua
--- desc: 負責 管理各種狀態
---------------------------------------
//管理器屬性
StateManagerByLua = new{
m_CurrentState = nil,// 當前狀態
tCurrentState = {}, //儲存所有狀態的table
}
// 管理器 構造
// dest: 將所有狀態都儲存起來
function StateManagerByLua:ManagerConstructor()
tCurrentState[EA_Sate] = AstateByLua:new{ p_Object = self}
tCurrentState[EB_Sate] = BstateByLua:new{ p_Object = self}
...
end
// 狀態切換
function StateManagerByLua:GotoState(nState)
// 離開當前狀態
...
self.m_CurrentState:LeaveState()
...
// 進入其他狀態
self.m_CurrentState = tCurrentState[nState]
self.m_CurrentState:EnterState()
end
// 檢測活動是否開啟
function StateManagerByLua:CheckState()
if 10.1 =< time and time < 10.5 then
self:GotoState(EBeginState)// 進入開始狀態
else
self:GotoState(ECheckActivityState) // 進入檢測狀態
end
end
由此,可清晰的解構出,活動管理其實並沒有那麼複雜,manager耦合各個狀態物件和自身屬性,發揮著重要作用。
接下來看看開始狀態的程式碼結構:
---------------------------------------
-- Title:活動開始狀態
-- desc:活動開啟 - 事件xxx- 做法xxx-
----------------------------------------
BeginState = new{
m_pobj = nil, // 訪問管理器屬性
...
}
// 進入活動開始狀態
function BeginState:EnterState()
...
//打怪
//領取獎勵
// 自定義活動邏輯
...
end
//離開狀態
function BeginState:LeaveState()
...
end
so, 結束狀態也是同理,自己可以合理安排各個狀態所需的邏輯和玩法,異曲同工。
相關文章
- 狀態機設計
- 系統設計架構:有狀態與無狀態架構
- 前端狀態管理與有限狀態機前端
- 《JavaScript設計模式與開發實踐》模式篇(13)—— 狀態模式JavaScript設計模式
- 服務端指南 | 狀態機設計服務端
- JavaScript與有限狀態機JavaScript
- 設計模式應用之Observer模式(2)設計模式Server
- 設計模式應用之Observer模式(1)設計模式Server
- 設計模式應用之Template method模式設計模式
- 【架構設計】無狀態狀態機在程式碼中的實踐架構
- Redis 設計與實現 (九)--LuaRedis
- 設計模式-狀態模式設計模式
- 設計模式:狀態模式設計模式
- 探索FSM (有限狀態機)應用
- 【Android_忍者六道】近百android程式原始碼貢獻(收藏)Android原始碼
- 計算機理論在實際程式設計中的應用之我見計算機程式設計
- 從任務中心看狀態機功能元件設計元件
- iptables應用之動態DNS(轉)DNS
- 也談應用之“基石”——資料庫設計資料庫
- 設計模式(十五)狀態模式設計模式
- 設計模式之——狀態模式設計模式
- javascript設計模式狀態模式JavaScript設計模式
- 設計模式(六):狀態模式設計模式
- Redis與Lua及Redis-py應用LuaRedis
- 狀態機
- 鴻蒙程式設計江湖:ArkUI 的宣告式 UI 程式設計與狀態管理鴻蒙程式設計UI
- 23種設計模式(七)-狀態設計模式設計模式
- Lua設計與實現--讀書筆記筆記
- [因為我不懂啊]-什麼是狀態機程式設計(設計模式)(0)程式設計設計模式
- 關於設計業務應答狀態碼的一點思考
- PHP 設計模式之狀態模式PHP設計模式
- 簡說設計模式——狀態模式設計模式
- 設計模式之狀態模式(State)設計模式
- 設計模式-狀態模式(State Pattern)設計模式
- python設計模式狀態模式Python設計模式
- 設計模式20之狀態模式設計模式
- 極簡設計模式-狀態模式設計模式
- GoLang設計模式14 - 狀態模式Golang設計模式