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开发学习---android下的数据持久化,保存数据到rom文件,android_data目录下文件访问的权限控制
一.需求 做一个类似QQ登录似的app,将数据写到ROM文件里,并对数据进行回显. 二.截图 登录界面: 文件浏览器,查看文件的保存路径:/data/data/com.amos.datasave/fi ...
- selenium-打开IE浏览器遇到问题记录
[使用selenium打开IE浏览器步骤]: 1.在IE浏览器上运行测试脚本,首先需要下载IEDriverServer.exe,放在IE浏览器的安装目录且同级目录下. 2.参考代码如下: import ...
- [ubuntu] adb devices出现no permissions
简书排版 http://www.jianshu.com/p/46e8848c6646 今天把一款测试的华为手机带回家,发现无法联机调试 笔者操作系统是 ubuntu 14.04 如果是windows找 ...
- java socket 网络编程常见异常
1.java.net.SocketTimeoutException 这个异常比较常见,socket超时.一般有2个地方会抛出这个,一个是connect的时候,这个超时参数由connect(Socket ...
- Http协议的常见参数
Requests部分 Header 解释 示例 Accept 指定客户端能够接收的内容类型 Accept: text/plain, text/html Accept-Charset 浏览器可以接受的字 ...
- adv联系题
http://www.cnblogs.com/kuangbin/archive/2011/07/29/2120667.html(新)
- LogNet4日志框架使用
.百度一下log4dll下载 .webconfig 里的<configSetions>节点中添加 <section name="log4net" type=&qu ...
- Jmeter在linux上运行(命令行运行Jmeter)
1.下载安装 http://jmeter.apache.org/download_jmeter.cgi Jmeter官网下载 linux下应使用tgz包,下载 Binaries apache-jme ...
- EasyUI DataGrid getChecked/getSelections 获取不到数据
今天使用getChecked获取选择的行,结果总是获取一行数据,于是换用getSelections,结果还是一样,想起之前做的项目,把idField换了下,之后getChecked/getSelect ...
- 简单的dp
有趣的数:(动态规划,状态转移) #include<stdio.h> ][]; int main() { int n,i; ; i<; i++) dp[i][]=; while(~s ...