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特殊符号又可 ...
随机推荐
- Android学习---ListView的点击事件,simpleAdapter和arrayadapter,SimpleCursoAdapter的原理和使用
如题,本文将介绍 listview的点击事件,simpleAdapter和arrayadapter的原理和使用. 1.ListView的注册点击事件 //注册点击事件 personListView.s ...
- Java浮点数float,bigdecimal和double精确计算的精度误差问题总结
(转)Java浮点数float,bigdecimal和double精确计算的精度误差问题总结 1.float整数计算误差 案例:会员积分字段采用float类型,导致计算会员积分时,7位整数的数据计算结 ...
- iOS判断数组不为空
用([array count]==0 )来判断是否为空,都是坑,如果array为空的话,执行count就会直接报错,程序崩溃退出. 正确判断NSArray是否为空的方法: if(array != ni ...
- (转)linux下cp目录时排除一个或者多个目录的实现方法
原文链接:http://www.jb51.net/LINUXjishu/88971.html 说明:/home目录里面有data目录,data目录里面有a.b.c.d.e五个目录,现在要把data目录 ...
- js校验输入字符串的字节长度
//检查输入字符串字节长度 function fucCheckLength(strTemp) { var i,sum; sum=0; var length = strTemp.length ; for ...
- Ubuntu16.04下安装.NET Core
以下为控制台输入代码序列一.sudo sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet ...
- Javascript日期比较
var date1=Date.parse("2014-9-3 11:40:14".replace(/-/g,"/")); var date2=Date.pars ...
- 关于git(分布式版本控制系统)的一些操作和命令
很久没上博客写东西了,今天闲着无聊就不想敲代码,所以看了看有没有一些好玩的东西,这不让我发现了git这个源代码版本控制工具,话不多说,就让我来简单的分享一下它的一些操作和命令以及命令所执行的含义吧! ...
- IIS出现 分析器错误消息: 在应用程序级别之外使用注册为 allowDefinition='MachineToApplication' 的节是错误的
这是因为发布的时候按了“生成部署包”
- IE全屏浏览代码
以前做过一个网络版的商场导购触摸屏系统,用ASP写的,就是要在运行的时候全屏浏览而不能出现标题栏.工具栏.状态栏等.解决方法是用JS弹出全屏窗口,建立html文件,代码如下: <script l ...