Cocos Creator学习の有限状态机

Posted 空城机

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Cocos Creator学习の有限状态机相关的知识,希望对你有一定的参考价值。

有限状态机(Finite State Machine)

其在任意时刻都处于有限状态集合中的某一状态。当其获得一个改变信息时,将从当前状态转换到另一个状态,或者仍然保持在当前状态

拿游戏中的人物举例:就是人物无时无刻都是处于某种状态之中的

具体实现时,可以把角色不同的行为分成不同的状态,然后给某一状态写入方法。通过状态机去进行人物不同状态之间的切换

可参考学习:Cocos Creator有限状态机


使用状态机的理由

在实际开发中,人物可能会有很多状态动作,如果将这些状态动作都写着人物类当中,代码会非常冗杂,并且不好管理。一个对象的状态越多、发生的事件越多,就越适合采用有限状态机的写法


实例

实例结构

此结构也可以看完后面的步骤再回过来看

cocos creator页面中先拖放一个精灵节点,为这个精灵节点创建一些像站立、跑步、攻击之类的animation动画。 然后再在旁边设置一系列动作切换的按钮。

创建有限状态机的管理类FSMManager.ts和状态类FSMState.ts

首先在状态类中,定义StateID状态ID,以及stateComponent状态的拥有者,还有此状态所属的状态管理器fsmManager

export default class FSMState 
    // 状态ID
    StateID: number = -1;
    // 所属的状态拥有者
    stateComponent: cc.Component;
    // 所属的状态管理器
    fsmManager: FSMManager = null;

    constructor(StateID: number, stateComponent: cc.Component, fsmManager: FSMManager) 
        this.StateID = StateID;
        this.stateComponent = stateComponent;
        this.fsmManager = fsmManager;
    
    // 进入状态
    OnEnter()  
    // 状态更新
    OnUpdate()  

在管理类当中,需要定义状态列表stateList属性和当前的状态ID currentID属性,并且创建改变状态和更新调用方法

export default class FSMManager  
    // 状态列表
    stateList: FSMState[] = [];
    // 当前状态ID
    currentID: number = -1;

    // 改变状态
    changeState(stateID: number) 
        this.currentID = stateID;
        // 调用新状态id的enter方法
        this.stateList[this.currentID].OnEnter();
    
    // 更新调用
    OnUpdate() 
        if (this.currentID != -1)  this.stateList[this.currentID].OnUpdate(); 
    

按照以上两个步骤,FSM有限状态机的基础类就已经创建完毕了,接下来进行人物类personControl以及各个动作类的单独编写。 各个基础动作了都继承自状态类FSMState.ts

然后在站立、跑步、攻击各个类中重写OnEnter进入状态方法。

以下是跑步状态类,其他动作类都与其类似。

export default class runState extends FSMState 
    // 进入状态
    OnEnter() 
        this.stateComponent.getComponent(cc.Animation).play('heroRun');
    
    // 状态更新
    OnUpdate()  

personControl人物类中,生成一个状态机管理器的实例,将现有的动作类生成实例,然后加入在此实例中的状态列表stateList

然后为此人物类创建运动方法,运动方法中只需要调用状态管理类中的changeState改变状态方法,即可切换人物的状态

PS: 因为一个人物的动作状态可能会有很多,所以可以使用枚举和数组先存储好这些状态的编号以及类,然后在生成状态实例时使用for循环进行生成

// 创建状态枚举
enum PersonState 
    stand = 0,
    run,
    attack1,
    attack2,
    attack3


let stateClassArr = [
    standState,
    runState,
    attack1,
    attack2,
    attack3
]

@ccclass
export default class personControl extends cc.Component 
    // 动画
    ani: cc.Animation;
    // 状态机
    fsmManager: FSMManager;
    // onLoad () 
    start () 
        this.ani = this.node.getComponent(cc.Animation);
        this.fsmManager = new FSMManager();
        // 创建几个动作状态
        for(let i in PersonState) 
            let index = Number(i);
            if (!isNaN(index)) 
                this.fsmManager.stateList.push(new stateClassArr[index](index, this, this.fsmManager));
            
        
    

    // 站立
    stand() 
        this.fsmManager.changeState(PersonState.stand);
    
    // 跑步
    run() 
        this.fsmManager.changeState(PersonState.run);
    
    // 攻击
    attack1() 
        this.fsmManager.changeState(PersonState.attack1);
    
    attack2() 
        this.fsmManager.changeState(PersonState.attack2);
    
    attack3() 
        this.fsmManager.changeState(PersonState.attack3);
    
    update (dt)  


最后将人物类中各个运动方法绑定到界面的按钮上面,然后运行,发现可以做到人物动作改变了

效果:

以上是关于Cocos Creator学习の有限状态机的主要内容,如果未能解决你的问题,请参考以下文章

Cocos Creator学习のTiledMap

Cocos Creator学习のTiledMap

cocos creator学习01 关于cocos creator 通过get 和post连接node.js服务器的初步探索

将mobx作为cocos creator状态管理工具

将mobx作为cocos creator状态管理工具

将mobx作为cocos creator状态管理工具