ts版本的有限状态机

最近做小游戏要做切换人物状态,花点时间写了一个有限状态机,使用语言为Ts,也可改成自己的语言

按照目前的逻辑,这个可以继续横向扩展,某些做流程管理

先上预览图

Fsm:状态机类

FsmBase:状态机基类

FsmManager:状态机管理类

FsmState:状态类

FsmIdle FsmRun角色Ctrl测试用状态机类

代码:FsmBase

//状态机基类 export default abstract class FsmBase { constructor(fsmid:number) {this.FsmId=fsmid } //状态机编号 public FsmId:number; //状态机拥有者 public Owner:any; //当前状态类型 public CurrStateType:number; //关闭状态机 public abstract ShutDown(); }

代码:FsmState

`

import Fsm from "./Fsm";

//状态类

export default abstract class FsmState

{

constructor() { }

//状态对应的状态机

public CurrFsm:Fsm

//进入状态

public abstract Enter()

//执行状态

public abstract Update()

//厉害状态

public abstract Leave()

//状态机销毁时调用

public abstract Destroy()

}

`

代码:Fsm

`

import FsmBase from "./FsmBase";

import FsmState from "./FsmState";

//状态机

export default class Fsmextends FsmBase {

private m_CurrState:FsmState<T>;

private m_StateDic:{[key:number]:FsmState<T>}={}

//初始化状态机

constructor(fsmid:number ,owner:T,states:FsmState[] )

{

super(fsmid);

this. m_StateDic={};

   this.Owner=owner;

   for (let i in states) {
let state=states[i];
state.CurrFsm=this;
this.m_StateDic[i]=state;
} this.CurrStateType=0;
this.m_CurrState=this.m_StateDic[this.CurrStateType];
this.m_CurrState.Enter();
}

//获取当前状态

public GetState(stateType:number):FsmState{

let state=null;

if (this.m_StateDic[stateType]) {

state=this.m_StateDic[stateType];

}

return state;

}

//执行当前状态

public Update(){

if (this.m_CurrState) {

this.m_CurrState.Update();

}

}

//切换当前状态

public ChangeState(newState:number){

if (this.CurrStateType==newState) {

return;

}

if (this.m_CurrState!=null) {

this.m_CurrState.Leave();

}

this.CurrStateType=newState;

this.m_CurrState=this.m_StateDic[this.CurrStateType];

    //进入新状态
this.m_CurrState.Enter();
}

//切换状态机

public ShutDown() {

if (this.m_CurrState!=null) {

this.m_CurrState.Leave();

}

for (let index in this.m_StateDic) {

this.m_StateDic[index].Destroy();

}

delete this.m_StateDic;

}

}

代码:FsmManager

import FsmBase from "./FsmBase";

import Fsm from "./Fsm";

import FsmState from "./FsmState";

//状态机管理类

export default class FsmManager {

constructor() { this.M_FsmDic= {}}
static _instance:any;
static getInstance() {
return this._instance || (this._instance = new FsmManager() )
} private M_FsmDic:{[key:number]:FsmBase};
private m_TemFsmId:number=0; //创建状态机
public Create<T>(owner:T,states:FsmState<T>[]):Fsm<T> {
this. m_TemFsmId+=1;
let fsm=new Fsm<T>(this.m_TemFsmId,owner,states)
this.M_FsmDic[this.m_TemFsmId]=fsm;
return fsm;
}
//销毁状态机
public DestroyFsm(fsmId:number){
let fsm=null;
if (this.M_FsmDic[fsmId]) {
fsm=this.M_FsmDic[fsmId];
fsm.ShutDown();
delete this.M_FsmDic[fsmId]
}
}

}

测试用代码:FsmIdle FsmRun RoleCtrl

import FsmState from "../Core/FSM/FsmState";

import RoleCtrl from "./RoleCtrl";

export default class FsmIdle extends FsmState {

constructor() { super(); }

public Enter() {
console.log("FsmIdle__Enter");
}
public Update() {
console.log("FsmIdle__Update");
}
public Leave() {
console.log("FsmIdle__Leave");
}
public Destroy() {
console.log("FsmIdle__Destroy");
}

}



import FsmState from "../Core/FSM/FsmState";

import RoleCtrl from "./RoleCtrl";

export default class FsmRun extends FsmState {

constructor() { super(); }

public Enter() {
console.log("FsmRun__Enter");
}
public Update() {
console.log("FsmRun__Update");
}
public Leave() {
console.log("FsmRun__Leave");
}
public Destroy() {
console.log("FsmRun__Destroy");
}

}

`

`

import Fsm from "../Core/FSM/Fsm";

import FsmState from "../Core/FSM/FsmState";

import FsmIdle from "./FsmIdle";

import FsmRun from "./FsmRun";

import FsmManager from "../Core/FSM/FsmManager";

enum RoleFsmState{Idle=0,Run=1}

export default class RoleCtrl extends Laya.Script {

/** @prop {name:myimage, tips:"图片", type:Node}*/
public myimage:Laya.Image; Index:number=0;
CurrFsm:Fsm<RoleCtrl>; constructor() { super();
let states:{[key:number]:FsmState<RoleCtrl>}={
0:new FsmIdle(),
1:new FsmRun()
};
this.CurrFsm= FsmManager.getInstance().Create(this,states);
}
onClick(){
this.change();
} change(): any {
this.CurrFsm.ChangeState((++this.Index)%2);
}
onUpdate(){
this.CurrFsm.Update();
}

}

`

目前测试运行良好,如果有发现问题的话,会及时进行修改

Ts有限状态机的更多相关文章

  1. AKKA 笔记 - 有限状态机 -2

    AKKA 笔记 - 有限状态机 -2 原文地址: http://rerun.me/2016/05/22/akka-notes-finite-state-machines-2/ 在上一节的Akka FS ...

  2. [翻译]AKKA笔记 - 有限状态机 -1

    原文地址:http://rerun.me/2016/05/21/akka-notes-finite-state-machines-1/ 我最近有个机会在工作上使用了Akka FSM,是个非常有趣的例子 ...

  3. 基于Unity有限状态机框架

    这个框架是Unity wiki上的框架.网址:http://wiki.unity3d.com/index.php/Finite_State_Machine 这就相当于是“模板”吧,自己写的代码,写啥都 ...

  4. ts 协议解析

    pes : http://wenku.baidu.com/link?url=KjcA0qXqZ1bWVQTa8i1YOmygofldSQL7Pjj-zGRw1e_6_LFmVLo5DIWF0SNwVn ...

  5. 转载:《TypeScript 中文入门教程》 14、输入.d.ts文件

    版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 介绍 当使用外部JavaScript库或新的宿主API时,你需要一个声明文件(.d.t ...

  6. ts 格式化日期输出

    功能 像C#中DateTime的ToString的格式化输出一样,在js/ts中输出格式化的日期字符串 网上很多正则的,不加分隔符就不行了,和C#的格式也不一样 刚接触js/ts没两月,可能会有问题. ...

  7. TypeScript Writing .d.ts files(编写声明文件)

    当使用扩展的JavaScript库或者插件API的时候,将需要使用声明文件(.d.ts)来描述库的类型.本文内容将包括如何编写声明文件相关的一些高级概念,然后用一些例子来展示如何将各式各样的概念与声明 ...

  8. AngularJs2 学习之路-笔记1-Atscript Ts ES6包含关系

    Atscript 这门新的语言是由谷歌的Angular团队弄出来的 就是为了编写ng2.0 ng2是个极具前瞻性的尝试 这种激进的革新在于对未来标准的迎合 ng2的标准包括了如下:1 module 2 ...

  9. 有限状态机(FSM)

    在游戏开发中,AI是个永恒不变的话题,如果你要的AI只是很简单的一个逻辑 那么有限状态机是一个很好的解决方案,尽管在实际开发中,AI的设计并不是一个简单的逻辑, 如果用有限状态机,维护起来会非常麻烦, ...

随机推荐

  1. selenium模拟淘宝登陆,过所有验证

    淘宝模拟登陆实现 由于淘宝使用了滑动验证码,需要进行模糊手动滑动,因此考虑使用selenium+chromedriver进行模拟登陆. 淘宝的登陆网址:https://login.taobao.com ...

  2. REHの个人主页

    朝暮与年岁并往 然后与你一同行至天光. 简介 这是怎么做到的啊-- 把那些迷茫的浑浊的不可预知的,裁剪,变化,像个造物主一样,最终成为混沌而又分明的,除去一身的戾气和险恶,把那些复杂和晦涩都剖析成它精 ...

  3. AcWing 392. 会合

    一个思路不难,但是实现起来有点毒瘤的题. 显然题目给出的是基环树(内向树)森林. 把每一个基环抠出来. 大力分类讨论: 若 \(a, b\) 不在一个联通量里,显然是 \(-1, -1\) 若 \(a ...

  4. Java集合源码分析(十)——TreeSet

    简介 TreeSet就是一个集合,里面不能有重复的元素,但是元素是有序的. TreeSet其实就是调用了TreeMap实现的,所以,它也不是线程安全的.可以实现自然排序或者根据传入的Comparato ...

  5. 初入Nginx--配置篇

    Nginx的主配置文件为/path/to/nginx/nginx.conf.Nginx.conf的配置文件结构主要由以下几个部分组成: ..... events{ .... } http{ .... ...

  6. python爬虫--用xpath爬豆瓣电影

    步骤 将目标网站下的页面抓取下来 将抓取下来的数据根据一定规则进行提取   具体流程 将目标网站下的页面抓取下来 1. 倒库 import requests 2.头信息(有时候可不写) headers ...

  7. idea导入配置SSM项目,并进行打包

    idea确实是一个功能强大的开发工具,但是配置项目太复杂,每次都要花费很长的时间在配置上. 关于SSM项目导入,配置,打包,看这篇就够了,百试不爽.

  8. 在linux下使用Apache搭建文件服务器

    目录 一.关于文件服务器 二.使用Apache搭建文件服务器 三.测试文件服务器是否可用 一.关于文件服务器 ​ 在一个项目中,如果想把公共软件或者资料共享给项目组成员,可以搭建一个简易的文件服务器来 ...

  9. DRF终极封装ViewSet和Router附教程PDF源码

    在DRF官方教程的学习过程中,一个很明显的感受是框架在不断地进行封装,我们自己写框架/工具/脚本/平台也可以模仿模仿,先完成底层代码,再做多层封装,让使用者很容易就上手操作.本文是教程的最后一篇,介绍 ...

  10. Centos7.6上部署Supervisor来监控和操作各类服务

    supervisor    是用Python开发的一个client/server服务,是Linux/Unix系统下的一个进程管理工具,不支持Windows系统.它可以很方便的监听.启动.停止.重启一个 ...