quick-cocos2d-x 学习系列之十五 状态机
1. 代码
-- create Finite StateMachine
self.fsm_ = {}
cc.GameObject.extend(self.fsm_)
:addComponent("components.behavior.StateMachine")
:exportMethods()
self.fsm_:setupState({
events = {
{name = "start", from =
"none", to = "green" },
{name = "warn", from =
"green", to = "yellow"},
{name = "panic", from =
"green", to = "red" },
{name = "panic", from =
"yellow", to = "red" },
{name = "calm", from =
"red", to = "yellow"},
{name = "clear", from =
"red", to = "green" },
{name = "clear", from =
"yellow", to = "green" },
},
callbacks = {
onbeforestart = function(event)
self:log("[FSM] STARTING UP")
end,
onstart = function(event)
self:log("[FSM]READY")
end,
onbeforewarn = function(event)
self:log("[FSM]START EVENT: warn!",
true) end,
onbeforepanic = function(event)
self:log("[FSM] START EVENT: panic!",
true) end,
onbeforecalm = function(event)
self:log("[FSM]START EVENT: calm!",
true) end,
onbeforeclear = function(event)
self:log("[FSM] START EVENT: clear!",
true) end,
onwarn = function(event)
self:log("[FSM]FINISH EVENT: warn!")
end,
onpanic = function(event)
self:log("[FSM]FINISH EVENT: panic!")
end,
oncalm = function(event)
self:log("[FSM]FINISH EVENT: calm!")
end,
onclear = function(event)
self:log("[FSM]FINISH EVENT: clear!")
end,
onleavegreen = function(event)
self:log("[FSM]LEAVE STATE: green")
end,
onleaveyellow = function(event)
self:log("[FSM] LEAVE STATE: yellow")
end,
onleavered = function(event)
self:log("[FSM] LEAVE STATE: red")
self:pending(event,
3)
self:performWithDelay(function()
self:pending(event,
2)
self:performWithDelay(function()
self:pending(event,
1)
self:performWithDelay(function()
self.pendingLabel_:setString("")
event.transition()
end,
1)
end,
1)
end,
1)
return
"async"
end,
ongreen = function(event)
self:log("[FSM]ENTER STATE: green")
end,
onyellow = function(event)
self:log("[FSM]ENTER STATE: yellow")
end,
onred = function(event)
self:log("[FSM]ENTER STATE: red")
end,
onchangestate = function(event)
self:log("[FSM] CHANGED STATE: " ..
event.from .. " to " ..
event.to) end,
},
})
-- createUI
display.newColorLayer(cc.c4b(255,
255, 255,
255))
:addTo(self)
cc.ui.UILabel.new({
text = "Finite State Machine",
size = 32,
color = display.COLOR_BLACK
})
:align(display.CENTER, display.cx,display.top -
60)
:addTo(self)
self.pendingLabel_ =
cc.ui.UILabel.new({
text = "",
size = 32,
color = display.COLOR_BLACK,
x = display.cx,
y = display.top -
620,
})
:align(display.CENTER)
:addTo(self)
-- preloadtexture
self.stateImage_ =
display.newSprite("#GreenState.png")
:pos(display.cx, display.top-
300)
:scale(1.5)
:addTo(self)
self.clearButton_ =
cc.ui.UIPushButton.new()
:setButtonLabel(cc.ui.UILabel.new({text=
"clear", size = 32, color =
display.COLOR_BLACK}))
:onButtonClicked(function()
if
self.fsm_:canDoEvent("clear")
then
self.fsm_:doEvent("clear")
end
end)
:align(display.CENTER, display.cx-
150, display.top -
540)
:addTo(self)
self.calmButton_ =
cc.ui.UIPushButton.new()
:setButtonLabel(cc.ui.UILabel.new({text=
"calm", size = 32, color =
display.COLOR_BLACK}))
:onButtonClicked(function()
if
self.fsm_:canDoEvent("calm")
then
self.fsm_:doEvent("calm")
end
end)
:align(display.CENTER, display.cx-
50, display.top-
540)
:addTo(self)
self.warnButton_ =
cc.ui.UIPushButton.new()
:setButtonLabel(cc.ui.UILabel.new({text=
"warn", size = 32, color =
display.COLOR_BLACK}))
:onButtonClicked(function()
if
self.fsm_:canDoEvent("warn")
then
self.fsm_:doEvent("warn")
end
end)
:align(display.CENTER, display.cx+
50, display.top-
540)
:addTo(self)
self.panicButton_ =
cc.ui.UIPushButton.new()
:setButtonLabel(cc.ui.UILabel.new({text=
"panic", size = 32, color =
display.COLOR_BLACK}))
:onButtonClicked(function()
if
self.fsm_:canDoEvent("panic")
then
self.fsm_:doEvent("panic")
end
end)
:align(display.CENTER, display.cx+
150, display.top -
540)
:addTo(self)
-- debug
self.logCount_ =
0
程序开始时候设置状态为green.
1.1 函数log
打印信息,根据打印状态变化图片。
1.2 函数pengding
打印状态信息,并设置LABEL字符串。
2. 解释
创建有限状态机
-- createFinite State Machine
self.fsm_ = {}
cc.GameObject.extend(self.fsm_)
:addComponent("components.behavior.StateMachine")
:exportMethods()
设置有限状态机回调函数
self.fsm_:setupState({
events = {
{name = "start", from =
"none", to = "green" },
{name = "warn", from =
"green", to = "yellow"},
{name = "panic", from =
"green", to = "red" },
{name = "panic", from =
"yellow", to = "red" },
{name = "calm", from =
"red", to = "yellow"},
{name = "clear", from =
"red", to = "green" },
{name = "clear", from =
"yellow", to = "green" },
},
callbacks = {
onbeforestart = function(event)
self:log("[FSM] STARTING UP")
end,
onstart = function(event)
self:log("[FSM]READY")
end,
onbeforewarn = function(event)
self:log("[FSM]START EVENT: warn!",
true) end,
onbeforepanic = function(event)
self:log("[FSM] START EVENT: panic!",
true) end,
onbeforecalm = function(event)
self:log("[FSM]START EVENT: calm!",
true) end,
onbeforeclear = function(event)
self:log("[FSM] START EVENT: clear!",
true) end,
onwarn = function(event)
self:log("[FSM]FINISH EVENT: warn!")
end,
onpanic = function(event)
self:log("[FSM]FINISH EVENT: panic!")
end,
oncalm =function(event)
self:log("[FSM] FINISH EVENT: calm!")
end,
onclear = function(event)
self:log("[FSM]FINISH EVENT: clear!")
end,
onleavegreen = function(event)
self:log("[FSM]LEAVE STATE: green")
end,
onleaveyellow = function(event)
self:log("[FSM] LEAVE STATE: yellow")
end,
onleavered = function(event)
self:log("[FSM] LEAVE STATE: red")
self:pending(event,
3)
self:performWithDelay(function()
self:pending(event,
2)
self:performWithDelay(function()
self:pending(event,
1)
self:performWithDelay(function()
self.pendingLabel_:setString("")
event.transition()
end,
1)
end,
1)
end,
1)
return
"async"
end,
ongreen = function(event)
self:log("[FSM]ENTER STATE: green")
end,
onyellow = function(event)
self:log("[FSM]ENTER STATE: yellow")
end,
onred = function(event)
self:log("[FSM]ENTER STATE: red")
end,
onchangestate = function(event)
self:log("[FSM] CHANGED STATE: " ..
event.from .. " to " ..
event.to) end,
},
})
创建4个Button
分别是:clear,calm,warn,panic。
如clear按钮
self.clearButton_ =
cc.ui.UIPushButton.new()
:setButtonLabel(cc.ui.UILabel.new({text=
"clear", size = 32, color =
display.COLOR_BLACK}))
:onButtonClicked(function()
if
self.fsm_:canDoEvent("clear")
then
self.fsm_:doEvent("clear")
end
end)
:align(display.CENTER, display.cx-
150, display.top -
540)
:addTo(self)
是否可以调用clear时间,如果可以则调用。其他3个按钮类似。
点击panic按钮后
先调用函数onbeforepanic 输出 [FSM] START EVENT: panic!
然后调用
onleavegreen = function(event) self:log("[FSM]LEAVE STATE: green") end,
接着调用
onred = function(event)self:log("[FSM] ENTER STATE:red") end,
再调用
onchangestate = function(event)self:log("[FSM] CHANGED STATE: " .. event.from .. " to " ..event.to) end,
最后调用
onpanic = function(event) self:log("[FSM]FINISH EVENT: panic!") end,
完成一次状态变化。