• FSM 浅谈


    之前写过一篇关于状态机的,上一篇讲过的我也就不再罗嗦了,不知道欢迎去查看我的上一篇随笔,主要是感觉上次自己封装的还是不行,所以又进行修改了一番!

    我本人是个菜鸟,最开始接触状态机的时候,状态机一个可厉害的东西! 因为自己只是知道其大概流程并不是很清楚其内部代码应该怎么去实现!所以之前在学校的时候也是纠结了很长时间(本人比较笨),现在知道了其内部具体是怎么运作的!所以可以自己能够封装出来Simple的小例子,自己封装的可能会有一些BUG,大神路过望指正!

    下面先讲状态机的原理,有限状态机主要是解决了游戏中状态的更换,以及省去了更换时的If else或者是Switch的繁杂语句,主要是通过有限状态机内部添加状态和记录状态可以转换的路径(方便装换使用),循环来实现摆脱If else或者是Switch的语句!

    下面是详细的代码,里面都有很详细的注释

    先看状态类

      1     /// <summary>
      2     /// 状态类
      3     /// </summary>
      4     /// <typeparam name="T"></typeparam>
      5     public class MyState<T>
      6     {
      7         private T myState;
      8         private T fatherState;
      9 
     10         /// <summary>
     11         /// 当前状态
     12         /// </summary>
     13         public T GetNowState
     14         {
     15             get
     16             {
     17                 return myState;
     18             }
     19         }
     20 
     21 
     22         /// <summary>
     23         /// 返回父状态
     24         /// </summary>
     25         public T GetFatherState
     26         {
     27             get
     28             {
     29                 return fatherState;
     30             }
     31             set
     32             {
     33                 if (fatherState == null)
     34                 {
     35                     fatherState = value;
     36                 }
     37                
     38             }
     39         }
     40 
     41 
     42         //自己的状态   父状态
     43         public MyState(T nowestate,T fathertate)
     44         {
     45             myState = nowestate;
     46 
     47             fatherState = fathertate;
     48 
     49         }
     50 
     51 
     52         /// <summary>
     53         /// 转换状态之前触发的事件
     54         /// </summary>
     55         public event FsmEvent DoBeforeEntering;
     56         public void DoEntery()
     57         {
     58             if (DoBeforeEntering != null)
     59             {
     60                 DoBeforeEntering();
     61             }
     62             else
     63             {
     64                 Debug.Log(myState.ToString() + "没有添加事件");
     65             }
     66 
     67         }
     68 
     69 
     70         /// <summary>
     71         /// 转换状态之后触发的事件
     72         /// </summary>
     73         public event FsmEvent DoBeforeLeaving;
     74         public void DoLeave()
     75         {
     76             if (DoBeforeLeaving != null)
     77             {
     78                 DoBeforeLeaving();
     79             }
     80             else
     81             {
     82                 Debug.Log(myState.ToString() + "没有绑定事件");
     83             }
     84 
     85         }
     86 
     87 
     88         /// <summary>
     89         /// Act是表现当前状态行为的函数
     90         /// </summary>
     91         public event FsmEvent Act;
     92         public void DoAction()
     93         {
     94             if (Act != null)
     95             {
     96                 Act();
     97             }
     98             else
     99             {
    100                 Debug.Log(myState.ToString() + "没有绑定事件");
    101             }
    102         }
    103     }

    然后是记录状态类的fsm类

      1  public class MyFSM<T>
      2     { 
      3         private Dictionary<T,List<MyState<T>>> TranslatList = new Dictionary<T,List<MyState<T>>>();
      4 
      5         private Dictionary<T, MyState<T>> AllState = new Dictionary<T,MyState<T>>();
      6 
      7         private T nowState;
      8 
      9         public void OnStart(T _t)
     10         {
     11             nowState = _t;
     12         }
     13        
     14         /// <summary>
     15         /// 添加装换状态列表
     16         /// </summary>
     17         /// <param name="t"></param>
     18         /// <param name="_myStateList"></param>
     19         public void AddTranslat(T t, List<MyState<T>> _myStateList)
     20         {
     21             if (TranslatList.ContainsKey(t))
     22             {
     23                 TranslatList[t] = _myStateList;
     24                 Debug.Log("重置转换状态");
     25             }
     26             else
     27             {
     28                 TranslatList.Add(t, _myStateList);
     29             }
     30             
     31         }
     32 
     33         /// <summary>
     34         /// 添加单独的装换状态
     35         /// </summary>
     36         /// <param name="t"></param>
     37         /// <param name="_myState"></param>
     38         public void AddTranslat(T t, MyState<T> _myState)
     39         {
     40             if (TranslatList.ContainsKey(t))
     41             {
     42                 List<MyState<T>> _myStateList = new List<MyState<T>>();
     43                 _myStateList = TranslatList[t];
     44                 if (_myStateList.Contains(_myState))
     45                 {
     46                     return;
     47                 }
     48                 else
     49                 {
     50                     _myStateList.Add(_myState);
     51                     TranslatList[t] = _myStateList;
     52                 }
     53             }
     54             else
     55             {
     56                 List<MyState<T>> _myStateList = new List<MyState<T>>();
     57                 _myStateList.Add(_myState);
     58             }
     59         }
     60 
     61         /// <summary>
     62         /// 添加状态
     63         /// </summary>
     64         /// <param name="t"></param>
     65         /// <param name="_state"></param>
     66         public void AddState(T t, MyState<T> _state)
     67         {
     68             if (AllState.ContainsKey(t))
     69             {
     70                 AllState[t] = _state;
     71                 Debug.Log("重置状态");
     72             }
     73             else
     74             {
     75                 AllState.Add(t, _state);
     76             }
     77         }
     78 
     79         /// <summary>
     80         /// 执行
     81         /// </summary>
     82         public void Execution()
     83         { 
     84             AllState[nowState].DoAction();
     85         }
     86 
     87 
     88         /// <summary>
     89         /// 状态转换
     90         /// </summary>
     91         /// <param name="_nextT"></param>
     92         /// <returns></returns>
     93         public bool StateTranslat(T _nextT)
     94         {
     95              //判读是否是同一个状态
     96             //是否可以进入
     97             //执行本状态最后命令
     98             //切换状态
     99             //执行本状态的开始命令
    100             if (!nowState.Equals(_nextT))
    101             {
    102                 if (TranslatList[nowState].Contains(AllState[_nextT]))
    103                 //if (nowState.Equals(AllState[_nextT].GetFatherState))
    104                 {
    105                     MyState<T> state = AllState[nowState];
    106                     state.DoEntery();
    107                     nowState = _nextT;
    108                     state = AllState[nowState];
    109                     state.DoEntery();
    110                     return true;
    111                 }
    112                 else
    113                 {
    114                     return false;
    115                 }
    116             }
    117             else
    118             {
    119                 return false;
    120             }           
    121         }
    122 
    123 
    124         /// <summary>
    125         /// 关闭FSM
    126         /// </summary>
    127         public void Close()
    128         {
    129             TranslatList.Clear();
    130             AllState.Clear();
    131         }
    132 
    133     }

    以上就是自己封装的fsm,有什么不对的地方欢迎大家指正!

  • 相关阅读:
    大道至简读后感(第二章)
    大道至简读后感
    将课程中的所有动手动脑的问题以及课后实验性的问题,整理成一篇文档
    python之基础
    python之面向对象
    python之网络编程
    python之函数
    Managing SharePoint 2010 Farm Solutions with Windows PowerShell
    Oracle RMAN vs. Export?
    转帖在oracle中自动大批量生成测试数据
  • 原文地址:https://www.cnblogs.com/mawanli/p/5966080.html
Copyright © 2020-2023  润新知