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++基础-01
指针 - 指针的基本操作间接引用指针所指向的对象 - 机器一般按字节寻址,所以能够独立分配的最小空间是1字节,也就是说指针指向的 最小空间为1字节.特别地,对于bool变量,虽然实际需要的是1bit, ...
- 选择c3p0作为连接池
<hibernate-configuration> <session-factory> <property name="dialect& ...
- 转载:align
1. 原理 int a; int size = 8; <----> 1000(bin)计算a以size为倍数的下界数: 就让这个数(要计算的这个数)表示成二 ...
- @Repository、@Service、@Controller 和 @Component
转载:http://blog.csdn.net/ye1992/article/details/19971467 spring 自 2.0 版本开始,陆续引入了一些注解用于简化 Spring 的开发.@ ...
- 老男孩python自动化运维作业1
#!/usr/bin/env pthon #字典操作三级菜单 “b”返回上一级菜单,“q”退出. menu={"BJ":{"cp":{1:1,2:2,3:3}, ...
- 「脑洞」图片转HTML(支持动画)
也许是受到很久以前看到的这玩意儿的原因:The Shapes of CSS 现在开脑洞写了个自动转换,顺便支持了动画……嗯,纯 CSS (:з」∠) 主要步骤就是用 Python 读图片,然后把像素全 ...
- Oracle DBA常用查询
Oracle DBA常用查询 –1. 查询系统所有对象select owner, object_name, object_type, created, last_ddl_time, timestamp ...
- UI设计中px、pt、ppi、dpi、dp、sp之间的关系
UI设计中px.pt.ppi.dpi.dp.sp之间的关系 武汉AAA数字艺术教育 2015-07-24 14:19:50 职业教育 pi px 阅读(3398) 评论(0) 声明:本文由入驻搜狐公众 ...
- poj1014(还需要改动)
#include <stdio.h> int n[6]; int main() { freopen("in.txt","r",stdin); int ...
- IOS开发之网络图片处理
//图片压缩 UIImage* image=[UIImage imageWithData:data]; NSData *data1 = UIImageJPEGRepresentation(image, ...