-- 有限状态机
local M = cclass("StateMachine")
function M:ctor(smName)
self.name = smName
self.states = {}
self.locked = false
self.curState = nil
end
-- 初始化所有状态
function M:InitStates(tempStates)
if tempStates then
for k, v in pairs(tempStates) do
self.states[k] = v
end
tempStates = nil
end
end
-- 添加状态
function M:AddState(baseState)
self.states[baseState.stateName] = baseState
end
-- 获取状态
function M:GetState(stateName)
return self.states[stateName]
end
-- 更新当前状态
function M:Update()
if self.curState then
self.curState:Update()
end
end
-- 切换状态
function M:ChangeState(stateName)
local state = self:GetState(stateName)
if state == nil then
print('状态类型未注册'..stateName)
return
end
if self.curState then
if self.locked then
print('不允许在 OnLeave 方法中进入其它状态.')
return
end
self.locked = true
if self.curState.stateName ~= stateName then
self.curState:OnLeave()
end
self.locked = false
end
self.curState = state
self.curState:OnEnter()
end
-- 游戏暂停
function M:OnApplicationPause(pause)
if self.curState then
self.curState:OnApplicationPause(pause)
end
end
-- 游戏退出
function M:OnApplicationQuit()
if self.curState then
self.curState:OnApplicationQuit()
end
end
-- 状态机释放
function M:Release()
for k, v in pairs(self.states) do
if v then
v = nil
end
end
self.states = {}
self.locked = false
self.curState = nil
end
return M
-- 状态基类
local M = cclass("BaseState")
function M:ctor(stateName)
self.stateName = stateName
end
function M:OnEnter()
end
function M:OnLeave()
end
function M:Update()
end
function M:OnApplicationPause(pause)
end
function M:OnApplicationQuit()
end
return M
-- 主场景状态
local M = cclass("MainState", require "Base.BaseState")
function M:ctor(stateName)
super.ctor(self, stateName)
end
function M:OnEnter()
print('进入Main State')
end
function M:OnLeave()
print('退出Main State')
end
return M
状态机使用示例:
RunMgr = {}
require "Base.class"
local SM = require "Base.StateMachine"
local MainState = require "Logic.MainState"
local GameState = require "Logic.GameState"
local LauncherState = require "Logic.LauncherState"
local states = {}
function RunMgr.Init()
log("RunMgr.Init--->>");
RunMgr.InitData()
local sm = SM:new('SlotGame')
sm:InitStates(states)
sm:ChangeState('MainState')
sm:ChangeState('LauncherState')
sm:ChangeState('GameState')
end
function RunMgr.InitData()
states['MainState'] = MainState:new('MainState')
states['GameState'] = GameState:new('GameState')
states['LauncherState'] = LauncherState:new('LauncherState')
end