前面花了4篇文章废话了那么多却没有提到传说中的状态机,那么这一篇就来讲讲那个
传说中的状态机到底是个长什么样的东东,前面几篇主要是做铺垫用,下面总结下:
1.状态切换由事件驱动,如调用onIdle()进入待机状态,调用onWalk()进入行走状态
2.状态有进入,也有退出,如调用onFrozen()进入冰冻状态,调用onFrozenEnd()退出冰冻状态
3.状态之间的切换是有限制条件的,如处于冰冻状态不能切换到攻击状态或行走状态
流程:事件--->状态机--->匹配状态切换规则--->可切换,新状态进入,旧状态退出
简单说下代码逻辑,兵种类中提供事件接口,如onWalk(),onAttack()等
实现一个状态机,将状态机绑定到兵种对象上,将状态切换规则提取出,
绑定到状态机上,实现一个状态创建器用来创建状态,绑定到状态机中,
从结构上看就是兵种身上有一个状态机,状态机里有状态切换规则和状态
创建器,下面来看代码:
StateId.lua,首先定义状态id,这个比较简单,不多说,下面的name不是必要的,只是方便调试
local StateId = {}
StateId.unKnown = -1
StateId.idle = 1 --待机
StateId.walk = 2 --行走
StateId.attack = 3 --攻击
StateId.frozen = 4 --冰冻
StateId.vertigo = 5 --眩晕
StateId.name = {}
StateId.name[StateId.idle] = "待机状态"
StateId.name[StateId.walk] = "行走状态"
StateId.name[StateId.attack] = "攻击状态"
StateId.name[StateId.frozen] = "冰冻状态"
StateId.name[StateId.vertigo] = "眩晕状态"
return StateId
Soldier.lua,兵种类,定义了事件接口,绑定状态机,将状态切换委托给状态机去处理:
local StateId = require("app.edition5.state.StateId")
local Soldier = class("Soldier")
function Soldier:ctor()
end
--绑定状态机
function Soldier:bindStateMachine(stateMachine)
self.stateMachine = stateMachine
self.stateMachine:bindSoldier(self)
end
--待机
function Soldier:onIdle()
self:toggleState(StateId.idle)
end
--行走
function Soldier:onWalk()
self:toggleState(StateId.walk)
end
--攻击
function Soldier:onAttack()
self:toggleState(StateId.attack)
end
--冰冻
function Soldier:onFrozen()
self:toggleState(StateId.frozen)
end
--冰冻结束
function Soldier:onFrozenEnd()
self:onIdle()
end
--眩晕
function Soldier:onVertigo()
self:toggleState(StateId.vertigo)
end
--切换状态
function Soldier:toggleState(iStateId)
self.stateMachine:toggleState(iStateId)
end
--切换状态失败
function Soldier:toggleStateFail(iCurrentStateId, iNewStateId)
print("无法从状态 ( " .. StateId.name[iCurrentStateId] .. " ) 切换到状态 ( " .. StateId.name[iNewStateId] .. " )")
end
return Soldier
StateRuleConfig.lua: