Ts有限状态机
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有限状态机的更多相关文章
- AKKA 笔记 - 有限状态机 -2
AKKA 笔记 - 有限状态机 -2 原文地址: http://rerun.me/2016/05/22/akka-notes-finite-state-machines-2/ 在上一节的Akka FS ...
- [翻译]AKKA笔记 - 有限状态机 -1
原文地址:http://rerun.me/2016/05/21/akka-notes-finite-state-machines-1/ 我最近有个机会在工作上使用了Akka FSM,是个非常有趣的例子 ...
- 基于Unity有限状态机框架
这个框架是Unity wiki上的框架.网址:http://wiki.unity3d.com/index.php/Finite_State_Machine 这就相当于是“模板”吧,自己写的代码,写啥都 ...
- ts 协议解析
pes : http://wenku.baidu.com/link?url=KjcA0qXqZ1bWVQTa8i1YOmygofldSQL7Pjj-zGRw1e_6_LFmVLo5DIWF0SNwVn ...
- 转载:《TypeScript 中文入门教程》 14、输入.d.ts文件
版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 介绍 当使用外部JavaScript库或新的宿主API时,你需要一个声明文件(.d.t ...
- ts 格式化日期输出
功能 像C#中DateTime的ToString的格式化输出一样,在js/ts中输出格式化的日期字符串 网上很多正则的,不加分隔符就不行了,和C#的格式也不一样 刚接触js/ts没两月,可能会有问题. ...
- TypeScript Writing .d.ts files(编写声明文件)
当使用扩展的JavaScript库或者插件API的时候,将需要使用声明文件(.d.ts)来描述库的类型.本文内容将包括如何编写声明文件相关的一些高级概念,然后用一些例子来展示如何将各式各样的概念与声明 ...
- AngularJs2 学习之路-笔记1-Atscript Ts ES6包含关系
Atscript 这门新的语言是由谷歌的Angular团队弄出来的 就是为了编写ng2.0 ng2是个极具前瞻性的尝试 这种激进的革新在于对未来标准的迎合 ng2的标准包括了如下:1 module 2 ...
- 有限状态机(FSM)
在游戏开发中,AI是个永恒不变的话题,如果你要的AI只是很简单的一个逻辑 那么有限状态机是一个很好的解决方案,尽管在实际开发中,AI的设计并不是一个简单的逻辑, 如果用有限状态机,维护起来会非常麻烦, ...
随机推荐
- 动态规划之经典数学期望和概率DP
起因:在一场训练赛上.有这么一题没做出来. 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6829 题目大意:有三个人,他们分别有\(X,Y,Z\)块钱 ...
- C++ 虚函数表与多态 —— 继承的虚函数表 & 内存布局
1. 使用继承的虚函数表: 如果不涉及多重继承,每个类只有1个虚函数表,当子类继承父类后,子类可以自己改写和新增虚函数,如下图所示: 子类重写 func_1 后,子函数的 func_1 将会有新的逻辑 ...
- DVWA各级文件包含漏洞
File Inclusion文件包含漏洞 漏洞分析 程序开发人员通常会把可重复使用的函数写入到单个文件中,在使用某些函数时,直接调用此文件,而无需再次编写,这种调用文件的过程被称为包含. 有时候由于网 ...
- ES6、ES7、ES8
ES6 https://es6.ruanyifeng.com/ ES7 1.Array.prototype.includes() includes()作用,是查找一个值在不在数组里,若是存在则返回 ...
- windows 上的MySQL默认字符集设置踩过的坑
前言: 前几天刚买了新电脑,装上MySQL有几天了,今天没事试了一下,发现默认字符集没有修改,还是默认的latin1,折腾了大半天,终于搞好了. 这是我成功设置后的结果图: 命令式直接在MySQL界面 ...
- 拒绝造轮子!如何移植并使用Linux内核的通用链表(附完整代码实现)
在实际的工作中,我们可能会经常使用链表结构来存储数据,特别是嵌入式开发,经常会使用linux内核最经典的双向链表 list_head.本篇文章详细介绍了Linux内核的通用链表是如何实现的,对于经常使 ...
- react第十一单元(受控组件和非受控组件-实现类似于vue双向绑定的功能)
第十一单元(受控组件和非受控组件-实现类似于vue双向绑定的功能) #课程目标 理解因为react的单向数据流 理解表单组件会因为react数据流变的不好维护 理解受控组件与非受控组件的实质区别 理解 ...
- 【JVM】类加载时机与过程
虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制.下面来总结梳理类加载的五个阶段. 类加载发生在 ...
- C# Wpf Shape类继承关系
Path派生于Shape namespace System.Windows.Shapes { public sealed class Path : Shape { // Path 派生于Shape } ...
- 安装篇四:安装NGINX(1.4.0版本)
#1.NGINX安装 1.安装文件上传软件 [root@TEST ~]# yum install lrzsz –y <---拖拽文件 2.检查软件安装的系统环境 [root@TEST ~]# c ...