Quick-cocos2d-x game development [14] -- StateMachine state machine, quickcocos2d

Source: Internet
Author: User
Tags fsm

Quick-cocos2d-x game development [14] -- StateMachine state machine, quickcocos2d

The state machine is a highlight in quick. If we are playing an RPG Game, a role generally has idle, attack, walk, run, and death statuses, if the status of a game role is determined by the branching condition, it will be very large and difficult to maintain, but once the state machine mode is used, it will be simple and convenient.


For how the state machine is implemented in quick, we should first look at how to use it.

To sum up, if a class has a state machine, there are two main steps:

1. Create a state machine object

2. initialize the state machine, including events and callback functions.


1. Create a state machine component

self.fsm = {}cc.GameObject.extend(self.fsm):addComponent("components.behavior.StateMachine"):exportMethods()

In this way, a state machine object is created. Next we need to initialize the object, that is, set the logic of each State.


2. initialize the state machine (set the state logic)

The setupState method is rewritten to set the state logic, which includes the following field parameters,

  • Initial: the initial state of the state machine.
  • Terminal (final): end status
  • Events: The Event corresponding to the status change
  • Callbacks: the callback function when a transformation occurs.

We usually set initial, events, and callbacks.


First, let's look at events. In events, we need to clearly distinguish "Event" and "status". events adopts the table structure. For example, we can write

events = {      {name = "move", from = {"idle", "jump"}, to = "walk"},}

In this example, move is an event, just as if you touched event. name. name indicates the event name, while idle, jump, and walk following from and to indicate the status. So the above means that when the move event is executed, if the status is idle or jump, it will jump to the walk state.

The from state can be a single State or a set state, that is, several States, but the to state can only be unique, or the program will return you a random state? Certainly not.


So here we need to figure out the status of our protagonist and the status from which it changes to when an event occurs. For example,

events = {{name = "move", from = {"idle", "jump"}, to = "walk"},{name = "attack", from = {"idle", "walk"}, to = "jump"},{name = "normal", from = {"walk", "jump"}, to = "idle"},},

The normal event changes to idle regardless of whether the main character is walking or jumping to jump. Similarly.


The next focus is the callbacks parameter,

That is, the callback is triggered by an event and a series of functions are executed.

  • OnbeforeEVNET: activated before the EVENT starts
  • OnleaveSTATE: activated when the old STATE is left
  • OnenterSTATE or onSTATE: activated when entering the new STATE
  • OnafterEVENT or onEVENT: activated after the EVENT ends

For example

Callbacks = {onenteridle = function () -- or onidleprint ("idle") end ,},

There are also 5 types of general callbacks to capture changes in all events and statuses:
  • Onbeforeevent: activated before any event starts
  • Onleavestate: activated when you leave any status
  • Onenterstate: activated when it enters any State
  • Onafterevent: activated after any event ends
  • Onchangestate: activated when the status changes
The name cannot be modified. It is for any event and any status. So you can imagine how many event callbacks and status Callbacks are involved, and their order. We can print them separately to know the order of calls. We will not describe them here.
Finally, you can call these events through self. fsm: doEvent (event). The event parameter corresponds to the events parameter name. In addition,
  • Fsm: isReady (): returns whether the state machine is ready.
  • Fsm: getState (): returns the current status
  • Fsm: isState (state): determines whether the current state is the state parameter.
  • Fsm: canDoEvent (eventName): The current State. If the event state conversion corresponding to eventName can be completed, true is returned.
  • Fsm: cannotDoEvent (eventName): The current State. If the event state conversion corresponding to eventName cannot be completed, true is returned.
  • Fsm: isFinishedState (): returns true if the current status is final.
  • Fsm: doEventForce (name,...): force the current state to be switched

Next, we will create a Player class and add a state machine to it,
local Player = class("Player", function ()return display.newSprite("icon.png")end)function Player:ctor()self:addStateMachine()endfunction Player:doEvent(event)self.fsm:doEvent(event)endfunction 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,},})endreturn Player

It is relatively simple. The callback function only writes a callback that enters three States. Then, it adds a doEvent function to the Player and calls the doEvent function in the state machine.
Return to MyScene. lua,
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)      endreturn MyScene

Add the Player we just added. Remember to import or require. Here we use the menu button to separate doEvent.





Where is the Animation State Machine of unity3d?

Create an Animator Controller in the editor and double-click it!


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.