| 本帖最后由 犯困嫌疑人 于 2023-6-19 11:51 编辑 
 概述有限状态机是一种用来进行对象行为建模的工具,作用是描述对象在它的生命周期内所经历的状态序列,以及如何响应来自外界的各种事件。
 介绍意图:将业务流程状态化,划分状态和相应的触发事件与动作,利用生命周期事件进行控制与执行。
 主要解决:对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。
 何时使用:代码中存在大量的if else来判断对象的状态时;一个对象的状态越多、发生的事件越多,就越适合采用有限状态机的写法
 如何解决:将各种具体的状态抽象出来。
 优点:有限状态机的写法,逻辑清晰,表达力强,有利于封装事件,实现后易于阅读和理解。
 缺点:系统类和对象的个数增加;结构和实现都较为繁杂,使用不当会导致程序结构和代码混乱;对于新增的状态,往往需要修改负责状态转换的代码对"开闭原则"的支持不友好。
 使用场景:1.行为随状态改变而改变的场景下;2.行为受到状态约束的时候;
 特点:状态总数是有限的;任一时刻,只处在一种状态之中;某种条件下会转换状态。
 简单实现:
 
 存在的问题:每次在实现状态机的时候我们都要去写一遍有限状态实例,当前状态,状态切换。
 /**
 * 状态机
 */
 class StateMachine {
 /**当前状态 */
 private _currentState: StateBase;
 /**所有的状态 */
 private _allStates: StateBase[] = [];
 /**状态对象 */
 private _actor: Transform;
 constructor(actor: Transform) {
 this._actor = actor;
 //准备好所有的状态实例
 this._allStates = [new BornState(this, actor), new MoveForwardState(this, actor), new RollForwardState(this, actor)]
 this._currentState = this._allStates[0];
 this._currentState.onEnter();
 }
 /**切换到另一个状态 */
 public toState(name: string) {
 if (this._currentState.constructor.name == name) return;
 let nextState: StateBase = this._allStates.find(i => i.constructor.name == name);
 this._currentState.onExit();
 this._currentState = nextState;
 this._currentState.onEnter();
 }
 /**帧驱动,也算是对外接受条件的一个接口 */
 public update(dt: number) {
 this._currentState.onUpdate(dt);
 }
 }
 /**
 * 状态基类
 */
 class StateBase {
 //归属于哪个状态机
 protected _fsm: StateMachine;
 protected _actor: Transform;
 constructor(fsm: StateMachine, actor: Transform) {
 this._fsm = fsm;
 this._actor = actor;
 }
 /**进入状态 */
 onEnter() { }
 /**帧驱动 */
 onUpdate(dt: number) { }
 /**退出状态 */
 onExit() { }
 }
 /**
 * 向前行走
 */
 class MoveForwardState extends StateBase {
 private readonly speed: number = 1;
 override onUpdate(dt: number): void {
 this._actor.location.x += dt * this.speed;
 }
 }
 /**
 * 向前滚
 */
 class RollForwardState extends StateBase {
 private readonly moveSpeed: number = 1;
 private readonly rollSpeed: number = 1;
 override onUpdate(dt: number) {
 this._actor.location.x += dt * this.moveSpeed;
 this._actor.rotation.y += dt * this.rollSpeed;
 }
 }
 /**
 * 出生状态
 */
 class BornState extends StateBase {
 private readonly bornLocation: Vector = Vector.zero;
 override onEnter(): void {
 this._actor.location = this.bornLocation;
 }
 }
 
 let fsm = new StateMachine(new Transform());
 
 改造成泛型:
 
 
 
 /**
 * 泛型实现
 */
 class StateMachine<A> {
 /**当前状态 */
 private _currentState: StateBase<A>;
 /**所有的状态 */
 private _allStates: StateBase<A>[] = [];
 /**表现对象 */
 private _actor: A;
 constructor(actor: A, ...states: { new(fsm: StateMachine<A>, actor: A): StateBase<A> }[]) {
 this._actor = actor;
 //准备好所有的状态实例
 for (let i of states) {
 this._allStates.push(new i(this, this._actor));
 }
 this._currentState = this._allStates[0];
 this._currentState.onEnter();
 }
 /**切换到另一个状态 */
 public toState(state: new (target, machine) => StateBase<A>) {
 if (this._currentState.constructor.name == state.name) return;
 let nextState: StateBase<A> = this._allStates.find(i => i.constructor.name == state.name);
 this._currentState.onExit();
 this._currentState = nextState;
 this._currentState.onEnter();
 }
 /**帧驱动,也算是对外接受条件的一个接口 */
 public update(dt: number) {
 this._currentState.onUpdate(dt);
 }
 }
 /**
 * 状态基类
 */
 class StateBase<A> {
 //归属于哪个状态机
 protected _fsm: StateMachine<A>;
 protected _actor: A;
 constructor(fsm: StateMachine<A>, actor: A) {
 this._fsm = fsm;
 this._actor = actor;
 }
 /**进入状态 */
 onEnter() { }
 /**帧驱动 */
 onUpdate(dt: number) { }
 /**退出状态 */
 onExit() { }
 }
 
 使用:
 
 
 /**
 * 向前行走
 */
 class MoveForwardState extends StateBase<Transform> {
 private readonly speed: number = 1;
 override onUpdate(dt: number): void {
 this._actor.location.x += dt * this.speed;
 }
 }
 /**
 * 向前滚
 */
 class RollForwardState extends StateBase<Transform> {
 private readonly moveSpeed: number = 1;
 private readonly rollSpeed: number = 1;
 override onUpdate(dt: number) {
 this._actor.location.x += dt * this.moveSpeed;
 this._actor.rotation.y += dt * this.rollSpeed;
 }
 }
 /**
 * 出生状态
 */
 class BornState extends StateBase<Transform> {
 private readonly bornLocation: Vector = Vector.zero;
 override onEnter(): void {
 this._actor.location = this.bornLocation;
 }
 }
 let fsm = new StateMachine<Transform>(new Transform(), BornState, MoveForwardState, RollForwardState);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 |