• 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,有什么不对的地方欢迎大家指正!

  • 相关阅读:
    【事件类】雅思口语
    【人物类】雅思口语
    【物品类】雅思口语
    Cassandra (二)Java | scala操作
    rpm安装在哪里了?
    用IDEA创建springboot项目遇到的问题Plugin 'org.springframework.boot:spring-boot-maven-plugin:' not found
    JDBC连接mysql出现The server time zone value '�й���׼ʱ��' is unrecognized
    Java反射、注解
    Junit单元测试
    Java-线程池、匿名内部类、Lambda表达式
  • 原文地址:https://www.cnblogs.com/mawanli/p/5966080.html
Copyright © 2020-2023  润新知