首页 > 其他 > 详细

CocosCreator_项目中运用FSM的方式

时间:2021-01-21 21:16:28      阅读:86      评论:0      收藏:0      [点我收藏+]

FSM全称有限状态机,解释百度一堆资料,在Creator中的使用记录下,主要是用在了场景管理和npc状态切换,源码如下:

StateMachine

export type ForeachStateFun = (varState: State, varObj: object) => void;



/**
* Autor: Created by 李清风 on 2021-01-12.
* Desc: FSM状态机状态抽象类
*/
export abstract class State {
    private mName: string;
    protected mMachine: StateMachine;

    public get pMachine() {
        return this.mMachine;
    }
    public set pMachine(value: StateMachine) {
        this.mMachine = value;
    }

    public constructor(name: string) {
        this.mName = name;
    }

    public get pName() {
        return this.mName;
    }

    abstract update();

    abstract begin();

    abstract end();
}

/**
* Autor: Created by 李清风 on 2021-01-12.
* Desc: FSM-StateMachine-状态机
*/
export class StateMachine {

    private mStateCollect: { [name: string]: State } = {}; //状态集合
    protected mLastState: State;
    protected mCurrentState: State;
    protected mNextState: State;

    public constructor() {
        this.mStateCollect = {};
        this.mCurrentState = null;
        this.mNextState = null;
    }

    //更新状态
    public update(): void {
        if (this.mCurrentState != null) {
            this.mCurrentState.update();//更新状态
        }
        if (this.mNextState != null) {
            if (this.mCurrentState != null) {
                this.mCurrentState.end();//结束当前状态
            }
            this.mCurrentState = this.mNextState;
            this.mNextState = null;
            this.mCurrentState.begin();//新的状态开始执行
        }
    }

    //获取某个状态
    public getState(name: string) {
        let tempState = null;
        if (this.mStateCollect[name]) {
            return tempState = this.mStateCollect[name];
        }
        return null;
    }

    //注册状态
    public registerState(state: State): boolean {
        if (state == null) {
            return false;
        }
        let name: string = state.pName;
        if (this.mStateCollect[name]) {
            return false;
        }
        state.pMachine = this;
        this.mStateCollect[name] = state;
        return true;
    }

    //解除状态
    public unregisterState(name: string): boolean {
        let tempsState: State = null;
        if (!this.mStateCollect[name]) {
            return false;
        }
        if (this.mStateCollect[name]) {
            tempsState = this.mStateCollect[name];
            tempsState.pMachine = null;//解除状态机
            delete this.mStateCollect[name];
            return true;
        }
    }

    //设置下个状态
    public setNextState(name: string): boolean {
        let tatgetState = this.getState(name);
        if (tatgetState == null) {
            return false;
        }
        this.mLastState = this.mCurrentState;
        if (tatgetState == this.mNextState) {
            return false;
        }
        this.mNextState = tatgetState;
        return true;
    }


    //返回最近的马上就要执行的状态
    public getNextState(): State {
        return this.mNextState;
    }

    //返回当前正在执行的状态
    public getCurrentState(): State {
        return this.mCurrentState;
    }

    //返回当前状态的类型
    public getCurrentStateType(): string {
        let s = this.getCurrentState();
        if (s != null) {
            return s.pName;
        }
        return null;
    }

    //清理所有的状态
    protected destroyAllState(): void {
        this.mStateCollect = {};//清空所有状态
        this.mCurrentState = null;
    }
}

 抽象出一个继承于StateMachine的Game管理类,专为管理场景切换设计,这个类是单例模式,源码如下:

import { StateMachine } from "../FSM/StateMachine";
import { GameScene } from "./GameScene";


export class Game extends StateMachine {

    private static mInstace: Game = null;

    //单例模式
    public static GetSingle(): Game {
        if (!this.mInstace) {
            this.mInstace = new Game();
        }
        return this.mInstace;
    }

    //构造器创建相关数据集
    private constructor() {
        super();
    }


    //上一个游戏场景
    public static GetLastScene(): GameScene {
        return Game.GetSingle().mLastState as GameScene;
    }

    //当前游戏场景
    public static GetCurrentScene(): GameScene {
        return Game.GetSingle().getCurrentState() as GameScene;
    }

    public InitGame(): boolean {
        this.InitGameScene();
        return true;
    }

    private InitGameScene(): void {
        return;
    }

    public StartGame(): void {

    }
}

创建一个GameScene类继承之State,实现了State中的接口,源码如下:

import { State } from "../FSM/StateMachine";


/**
* Autor: Created by 李清风 on 2021-01-12.
* Desc: GameScene类,是所有场景的基类,也是场景状态的基类
*/
export class GameScene extends State {

    update() {
        //console.log("state update")
    }
    begin() {
        //console.log("state begin")
    }
    end() {
        //console.log("state end")
    }

}

接着创建LoginScene.ts、DownLoadScene.ts、CityScene.ts,源码如下:

import { GameObject, GMScene } from "../../GameObject";
import { GameScene } from "./GameScene";

export class LoginScene extends GameScene {

    public constructor() {
        super(GMScene.GM_LOGIN.toString())
    }

    public begin(): void {
        super.begin();
        cc.director.loadScene("LoginScene");
        //模拟异步网络、资源操作完毕,跳转CityScene
        setTimeout(() => {
            this.goLoginScene();
        }, 2500);
    }

    goLoginScene() {
        GameObject.GetSingleton().gotoSceneNoLoad(GMScene.GM_CITY);
    }


    public update(): void {
        super.update();
    }

    public end(): void {
        super.end();
    }
}
import { GameObject, GMScene } from "../../GameObject";
import { GameScene } from "./GameScene";


export class DownLoadScene extends GameScene {

    public constructor() {
        super(GMScene.GM_DOWNLOAD.toString())
    }

    public begin(): void {
        super.begin();
        cc.director.loadScene("DownLoadScene");
        //模拟异步网络、资源操作完毕,跳转loginScene
        setTimeout(() => {
            this.goLoginScene();
        }, 1300);

    }

    goLoginScene() {
        GameObject.GetSingleton().gotoSceneNoLoad(GMScene.GM_LOGIN);
    }

    public update(): void {
        super.update();
    }

    public end(): void {
        super.end();
    }
}
import { GMScene } from "../../GameObject";
import { GameScene } from "./GameScene";

export class CityScene extends GameScene {

    public constructor() {
        super(GMScene.GM_CITY.toString())
    }

    public begin(): void {
        super.begin();
        //进入主城场景
        cc.director.loadScene("CityScene");
    }

    public update(): void {
        super.update();
        console.log("city update")
    }

    public end(): void {
        super.end();
    }
}

 

CocosCreator_项目中运用FSM的方式

原文:https://www.cnblogs.com/makeamericagreatagain/p/14310146.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!