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 studio+ gradle+jacoco
在工程的oncreate()方法添加如下代码,目的是创建ec文件. String DEFAULT_COVERAGE_FILE_PATH = "/mnt/sdcard/coverage.ec& ...
- keepalived+mysql实现双主高可用
环境: DB1:centos6.8.mysql5.5.192.168.2.204 hostname:bogon DB2:centos6.8.mysql5.5.192.168.2.205 hostn ...
- python函数动态参数详解
Python的动态参数: 1,参数前一个"*":在函数中会把传的参数转成一个元组. def func (*args): print(args) func(123,1,2,'a') ...
- 我的Android笔记--我对安卓系统的一些了解
敲了这么长时间代码,记录一下我对Android的一些概念,下面大部分内容来源自网络资料和官方给的文档. 1,Android操作系统的核心属于Linux的一个分支,具有典型的Linux调度和功能 ...
- java实现调用ORACLE中的游标和包
今天把oracle中的包和游标学习了下,不废话,网上的的有些代码是错误的,抄来抄去,就自己实践了下,做个记录.直接上图,上代码 通过plsql创建自己的的包,包分为包头和包体. 1.包头如下: CRE ...
- 几个开源XMPP Android客户端简单比较
想做个基于xmpp的即时通讯工具,服务端已经基本成型了.当然需要客户端需要配合,PC端基于spark进行改造,手机端先从Android入手(IOS估计一个人是搞不过来了). 原本Android开发 ...
- rest-assured : Restful API 测试利器 - 真正的黑盒单元测试(跟Spring-Boot更配哦,更新至spring-boot1.4.1)
{ "Author":"tomcat and jerry", "URL" :"http://www.cnblogs.com/tom ...
- 动态加载jar包中的类(方式一)
嘛, 直接上代码 public static class TestClassLoader extends ClassLoader { @Override protected Class<?> ...
- VMware Linux Guest 增加磁盘无需重启的方法
摘要 常常需要需要给VMware Linux Guest增加磁盘适配一些测试场景,而又不想花费时间重启Guest,查找文档,发现一种简单的方法,记录一下操作步骤. 操作步骤 1 编辑Linux ...
- photoshopcc基础教程
web项目中,除了最基础的用java存取数据外,还有重要的h5+css排版以及图片的ps,排版多多看网上人家的好看的界面设计,至于图片,只能自己上手了,设计最终的目的是好看,好看,好看. 接下来,做个 ...