何为简答?我看得懂就是简单
何为状态机? 状态机是有限状态自动机的简称。
好了不废话了,上代码
/** 状态 */
export class FSMState {
public name: string = null;
public translationMap: Map<string, FSMTranslation> = null; //<指令名,跳转>
constructor(name: string) {
this.name = name;
this.translationMap = new Map<string, FSMTranslation>();
}
}
/** 跳转 */
export class FSMTranslation {
public name: string = null; //指令名
public fromState: FSMState = null; //上一个状态
public toState: FSMState = null; //下一个状态
public callFunction: Function = null; //状态对应的回调,如果有需要可以自己添加 EnterCallback,ExitCallback,然后在handleEvent里面调用,这里我就只写一个回调了
public constructor(name: string, fromState: FSMState, toState: FSMState, callFunction: Function) {
this.name = name;
this.fromState = fromState;
this.toState = toState;
this.callFunction = callFunction;
}
}
/** 状态机 */
export class FSM {
private _currState: FSMState = null; // 当前状态
public get currState(): FSMState { return this._currState; }
public stateMap: Map<string, FSMState> = new Map<string, FSMState>();
public addState(state: FSMState): void {
this.stateMap.set(state.name, state);
}
public addTranslation(translation: FSMTranslation): void {
this.stateMap.get(translation.fromState.name).translationMap.set(translation.name, translation);
}
/** 启动状态机 */
public start(state: FSMState): void {
this._currState = state;
}
public handleEvent(name: string): void {
if (this._currState != null && this._currState.translationMap.has(name)) {
this._currState.translationMap.get(name).callFunction();
this._currState = this._currState.translationMap.get(name).toState;
}
}
}
好了,写完了。使用如下:
import { FSM, FSMState, FSMTranslation } from "../Core/FSM";
const { ccclass, property } = cc._decorator;
enum FSMStateType {
Idle = "Idle",
Jump = "Jump",
Die = "Die",
}
enum FSMTranslationType {
Touch_Jump = "Touch_Jump",
On_Idle = "On_Idle",
On_Idle_Die = "On_Idle_Die",
On_Jump_Die = "On_Jump_Die",
}
@ccclass
export default class Test extends cc.Component {
private _fsm: FSM = new FSM();
start() {
// 创建状态
let idleState: FSMState = new FSMState(FSMStateType.Idle);
let jumpState: FSMState = new FSMState(FSMStateType.Jump);
let dieState: FSMState = new FSMState(FSMStateType.Die);
// 创建跳转
let idleToJumpTranslation: FSMTranslation = new FSMTranslation(FSMTranslationType.Touch_Jump, idleState, jumpState, this.jump.bind(this));
let jumpToIdleTranslation: FSMTranslation = new FSMTranslation(FSMTranslationType.On_Idle, jumpState, idleState, this.idle.bind(this));
let idleToDieTranslation: FSMTranslation = new FSMTranslation(FSMTranslationType.On_Idle_Die, idleState, dieState, this.idleDie.bind(this));
let jumpToDieTranslation: FSMTranslation = new FSMTranslation(FSMTranslationType.On_Jump_Die, jumpState, dieState, this.jumpDie.bind(this));
// 添加状态
this._fsm.addState(idleState);
this._fsm.addState(jumpState);
this._fsm.addState(dieState);
// 添加跳转
this._fsm.addTranslation(idleToJumpTranslation);
this._fsm.addTranslation(jumpToIdleTranslation);
this._fsm.addTranslation(idleToDieTranslation);
this._fsm.addTranslation(jumpToDieTranslation);
this._fsm.start(idleState);
}
// ---------触发事件切换状态------------------------------------------------
/** 起跳 */
private onJumpBtn(): void {
if (this._fsm.currState.name != FSMStateType.Idle) return;
this._fsm.handleEvent(FSMTranslationType.Touch_Jump);
this.unscheduleAllCallbacks();
this.scheduleOnce(() => { this._fsm.handleEvent(FSMTranslationType.On_Idle); }, 0.5);
}
/** 嗝儿屁 */
private onDieBtn(): void {
if (this._fsm.currState.name == FSMStateType.Jump) {
this._fsm.handleEvent(FSMTranslationType.On_Jump_Die);
} else if (this._fsm.currState.name == FSMStateType.Idle) {
this._fsm.handleEvent(FSMTranslationType.On_Idle_Die);
}
}
// ---------------回调---------------------------------------------
private jump(): void { console.log("jumping"); }
private idle(): void { console.log("idle"); }
private jumpDie(): void { console.log("jumpDie"); }
private idleDie(): void { console.log("idleDie"); }
}