FSM 浅谈
之前写过一篇关于状态机的,上一篇讲过的我也就不再罗嗦了,不知道欢迎去查看我的上一篇随笔,主要是感觉上次自己封装的还是不行,所以又进行修改了一番!
我本人是个菜鸟,最开始接触状态机的时候,状态机一个可厉害的东西! 因为自己只是知道其大概流程并不是很清楚其内部代码应该怎么去实现!所以之前在学校的时候也是纠结了很长时间(本人比较笨),现在知道了其内部具体是怎么运作的!所以可以自己能够封装出来Simple的小例子,自己封装的可能会有一些BUG,大神路过望指正!
下面先讲状态机的原理,有限状态机主要是解决了游戏中状态的更换,以及省去了更换时的If else或者是Switch的繁杂语句,主要是通过有限状态机内部添加状态和记录状态可以转换的路径(方便装换使用),循环来实现摆脱If else或者是Switch的语句!
下面是详细的代码,里面都有很详细的注释
先看状态类
/// <summary>
/// 状态类
/// </summary>
/// <typeparam name="T"></typeparam>
public class MyState<T>
{
private T myState;
private T fatherState; /// <summary>
/// 当前状态
/// </summary>
public T GetNowState
{
get
{
return myState;
}
} /// <summary>
/// 返回父状态
/// </summary>
public T GetFatherState
{
get
{
return fatherState;
}
set
{
if (fatherState == null)
{
fatherState = value;
} }
} //自己的状态 父状态
public MyState(T nowestate,T fathertate)
{
myState = nowestate; fatherState = fathertate; } /// <summary>
/// 转换状态之前触发的事件
/// </summary>
public event FsmEvent DoBeforeEntering;
public void DoEntery()
{
if (DoBeforeEntering != null)
{
DoBeforeEntering();
}
else
{
Debug.Log(myState.ToString() + "没有添加事件");
} } /// <summary>
/// 转换状态之后触发的事件
/// </summary>
public event FsmEvent DoBeforeLeaving;
public void DoLeave()
{
if (DoBeforeLeaving != null)
{
DoBeforeLeaving();
}
else
{
Debug.Log(myState.ToString() + "没有绑定事件");
} } /// <summary>
/// Act是表现当前状态行为的函数
/// </summary>
public event FsmEvent Act;
public void DoAction()
{
if (Act != null)
{
Act();
}
else
{
Debug.Log(myState.ToString() + "没有绑定事件");
}
}
}
然后是记录状态类的fsm类
public class MyFSM<T>
{
private Dictionary<T,List<MyState<T>>> TranslatList = new Dictionary<T,List<MyState<T>>>(); private Dictionary<T, MyState<T>> AllState = new Dictionary<T,MyState<T>>(); private T nowState; public void OnStart(T _t)
{
nowState = _t;
} /// <summary>
/// 添加装换状态列表
/// </summary>
/// <param name="t"></param>
/// <param name="_myStateList"></param>
public void AddTranslat(T t, List<MyState<T>> _myStateList)
{
if (TranslatList.ContainsKey(t))
{
TranslatList[t] = _myStateList;
Debug.Log("重置转换状态");
}
else
{
TranslatList.Add(t, _myStateList);
} } /// <summary>
/// 添加单独的装换状态
/// </summary>
/// <param name="t"></param>
/// <param name="_myState"></param>
public void AddTranslat(T t, MyState<T> _myState)
{
if (TranslatList.ContainsKey(t))
{
List<MyState<T>> _myStateList = new List<MyState<T>>();
_myStateList = TranslatList[t];
if (_myStateList.Contains(_myState))
{
return;
}
else
{
_myStateList.Add(_myState);
TranslatList[t] = _myStateList;
}
}
else
{
List<MyState<T>> _myStateList = new List<MyState<T>>();
_myStateList.Add(_myState);
}
} /// <summary>
/// 添加状态
/// </summary>
/// <param name="t"></param>
/// <param name="_state"></param>
public void AddState(T t, MyState<T> _state)
{
if (AllState.ContainsKey(t))
{
AllState[t] = _state;
Debug.Log("重置状态");
}
else
{
AllState.Add(t, _state);
}
} /// <summary>
/// 执行
/// </summary>
public void Execution()
{
AllState[nowState].DoAction();
} /// <summary>
/// 状态转换
/// </summary>
/// <param name="_nextT"></param>
/// <returns></returns>
public bool StateTranslat(T _nextT)
{
//判读是否是同一个状态
//是否可以进入
//执行本状态最后命令
//切换状态
//执行本状态的开始命令
if (!nowState.Equals(_nextT))
{
if (TranslatList[nowState].Contains(AllState[_nextT]))
//if (nowState.Equals(AllState[_nextT].GetFatherState))
{
MyState<T> state = AllState[nowState];
state.DoEntery();
nowState = _nextT;
state = AllState[nowState];
state.DoEntery();
return true;
}
else
{
return false;
}
}
else
{
return false;
}
} /// <summary>
/// 关闭FSM
/// </summary>
public void Close()
{
TranslatList.Clear();
AllState.Clear();
} }
以上就是自己封装的fsm,有什么不对的地方欢迎大家指正!
FSM 浅谈的更多相关文章
- 浅谈用ModelSim+Synplify+Quartus来实现Altera FPGA的仿真
浅谈用ModelSim+Synplify+Quartus来实现Altera FPGA的仿真 工作内容: Mentor公司的ModelSim是业界最优秀的HDL语言仿真软件,它能提供友好的仿真环境,是业 ...
- 浅谈 Fragment 生命周期
版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Fragment 文中如有纰漏,欢迎大家留言指出. Fragment 是在 Android 3.0 中 ...
- 浅谈 LayoutInflater
浅谈 LayoutInflater 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/View 文中如有纰漏,欢迎大家留言指出. 在 Android 的 ...
- 浅谈Java的throw与throws
转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...
- 浅谈SQL注入风险 - 一个Login拿下Server
前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...
- 浅谈WebService的版本兼容性设计
在现在大型的项目或者软件开发中,一般都会有很多种终端, PC端比如Winform.WebForm,移动端,比如各种Native客户端(iOS, Android, WP),Html5等,我们要满足以上所 ...
- 浅谈angular2+ionic2
浅谈angular2+ionic2 前言: 不要用angular的语法去写angular2,有人说二者就像Java和JavaScript的区别. 1. 项目所用:angular2+ionic2 ...
- iOS开发之浅谈MVVM的架构设计与团队协作
今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...
- Linux特殊符号浅谈
Linux特殊字符浅谈 我们经常跟键盘上面那些特殊符号比如(?.!.~...)打交道,其实在Linux有其独特的含义,大致可以分为三类:Linux特殊符号.通配符.正则表达式. Linux特殊符号又可 ...
随机推荐
- C# 文件操作 把文件读取到字节数组
string zipfile = "c:\\a.zip"; //方法1 FileStream fs = new FileStream(zipfile, FileMode.Open) ...
- Android 设置代理(验证用户名和密码)
这几天在研究在Android中,解析网页,但是公司内容,链接外网需要代理,并需要验证用户名和密码,十分头疼,网上查了下,没有头绪,最后总算在一个外国博客中看到类似的,记录下 URL url = new ...
- Python编写邮件群发(qq邮箱)
#电子邮件操作 import poplib import smtplib from email.header import decode_header from email.mime.text imp ...
- PD中将Comment 从Name复制值
PD中将Comment 从Name复制值, 将以下语句考到,pd 工具栏下的执行脚本中执行下就OK了 Option Explicit ValidationMode = True Interactive ...
- github中cesium-terrain-builder和cesium-terrain-server使用
cesium-terrain-builder的使用: 这个是用来把含有高程数据的tif图片切片成.terrain的小文件,是给cesium-terrain-server提供服务的. cesium-te ...
- 调用 WebService 浏览器提示 500 (Internal Server Error) 的原因及解决办法
在 ASP.NET 开发中,WebService部署成站点之后,如果在本地测试WebService可以运行,在远程却显示“测试窗体只能用于来自本地计算机的请求”或 者"The test fo ...
- 在 Linux 下将 PNG 和 JPG 批量互转的四种方法
计算机术语中,批处理指的是用一个非交互式的程序来执行一序列的任务[1]的方法.这篇教程里,我们会使用 Linux 命令行工具,并提供 4 种简单的处理方式来把一些 .PNG 格式的图像批量转换成 .J ...
- jQuery操作Table tr td常用的方法
虽然现在DIV+CSS进行页的布局大行其道,但是很多地方使用table还是有很多优势,用table展示数据是比较方便的,下面汇总了jQuery操作Table tr td常用的方法,熟记这些操作技巧,下 ...
- 一起买beta版PHP单元测试
一起买beta版PHP单元测试 测试目的 保证代码质量,对各个单元进行测试,可以有效地保证代码的可靠性,让模块在与别的模块整合时出现更少的错误. 单元描述 完成帖子接口 将"正在进行&q ...
- Linux下GDB调试
GDB 是一个强大的命令行调试工具.大家知道命令行的强大就是在于,其可以形成执行 序列,形成脚本.UNIX 下的软件全是命令行的,这给程序开发提供了极大的便利,命令行 软件的优势在于, 他们可以非常容 ...