状态机在quick中是一个亮点,如果我们做一款RPG游戏,一个角色一般会拥有idle,attack,walk,run,death这些状态,如果游戏角色的状态采用分支条件判断的话,会造成非常庞大而难以维护,但一旦使用了状态机这种模式,就会显得简单方便。
对于quick中的状态机是如何实现的咱们先不去了解,首先看看如何去使用它。
总结起来,如果让一个类拥有状态机,主要有两步:
1.创建状态机对象
2.初始化状态机,主要包括事件和回调函数
1.创建状态机组件
self.fsm = {} cc.GameObject.extend(self.fsm):addComponent("components.behavior.StateMachine"):exportMethods()
2.初始化状态机(设置状态逻辑)
设置状态逻辑是重写setupState方法,这其中有这么几个字段参数,
一般我们会设置initial,events和callbacks这三个。
先看events,在events中需要分清楚“事件”和“状态”,events采用table结构,例如我们来写一个
events = { {name = "move", from = {"idle", "jump"}, to = "walk"}, }
from的状态可以是单一状态,也可以使集合状态,就是几个状态,但to的状态只能唯一,不然程序还给你来个随机状态?肯定不行的。
所以这里需要想好我们的主角有哪些状态,当什么事件发生时,他会从什么状态变到什么状态上去。例如我简单这么写,
events = { {name = "move", from = {"idle", "jump"}, to = "walk"}, {name = "attack", from = {"idle", "walk"}, to = "jump"}, {name = "normal", from = {"walk", "jump"}, to = "idle"}, },
接下来一个重点是callbacks参数,
即所谓回调了,就是事件触发,会执行一系列的函数。
例如
callbacks = { onenteridle = function () --或者 onidle print("idle") end, },
local Player = class("Player", function () return display.newSprite("icon.png") end) function Player:ctor() self:addStateMachine() end function Player:doEvent(event) self.fsm:doEvent(event) end function Player:addStateMachine() self.fsm = {} cc.GameObject.extend(self.fsm):addComponent("components.behavior.StateMachine"):exportMethods() self.fsm:setupState({ initial = "idle", events = { {name = "move", from = {"idle", "jump"}, to = "walk"}, {name = "attack", from = {"idle", "walk"}, to = "jump"}, {name = "normal", from = {"walk", "jump"}, to = "idle"}, }, callbacks = { onenteridle = function () local scale = CCScaleBy:create(0.2, 1.2) self:runAction(CCRepeat:create(transition.sequence({scale, scale:reverse()}), 2)) end, onenterwalk = function () local move = CCMoveBy:create(0.2, ccp(100, 0)) self:runAction(CCRepeat:create(transition.sequence({move, move:reverse()}), 2)) end, onenterjump = function () local jump = CCJumpBy:create(0.5, ccp(0, 0), 100, 2) self:runAction(jump) end, }, }) end return Player
local Player = import("..views.Player") local MyScene = class("MyScene", function () return display.newScene("MyScene") end) function MyScene:ctor() local player = Player.new() player:setPosition(display.cx, display.cy) self:addChild(player) local function menuCallback(tag) if tag == 1 then player:doEvent("normal") elseif tag == 2 then player:doEvent("move") elseif tag == 3 then player:doEvent("attack") end end local mormalItem = ui.newTTFLabelMenuItem({text = "normal", x = display.width*0.3, y = display.height*0.2, listener = menuCallback, tag = 1}) local moveItem = ui.newTTFLabelMenuItem({text = "move", x = display.width*0.5, y = display.height*0.2, listener = menuCallback, tag = 2}) local attackItem = ui.newTTFLabelMenuItem({text = "attack", x = display.width*0.7, y = display.height*0.2, listener = menuCallback, tag = 3}) local menu = ui.newMenu({mormalItem, moveItem, attackItem}) self:addChild(menu) end return MyScene
quick-cocos2d-x游戏开发【14】——StateMachine状态机
原文地址:http://blog.csdn.net/w337198302/article/details/39430647