<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                ## 為什么用有限狀態機? ??之前做過一款跑酷游戲,跑酷角色有很多狀態:跑、跳、二段跳、死亡等等。一開始是使用if/switch來切換狀態,但是每次角色添加一個狀態(提前沒規劃好),所有狀態處理相關的代碼就會指數級增長,那樣就會嗅出代碼的壞味道了。在這種處理狀態并且狀態數量不是特別多的情況下,自然就想到了引入狀態機。 優點: ??1. 使代碼整潔,狀態容易擴展和管理。 ??2. 可復用。 ??3. 還沒想到..... 缺點: ??1. 也沒想到...... ## 什么是有限狀態機? 解釋不清楚,看了下百度百科。反正是一種數據結構,一個解決問題的工具。 從百度百科可以看到,有限狀態機最最最基礎的概念有兩個:狀態和轉移。 從剛才跑酷的例子來講,跑、跳、二段跳等這些就是角色的狀態。 如圖所示: ![image.png](http://file.liangxiegame.com/7a34c67a-935e-4818-b754-00455f1c3133.png) ? 主角從跑狀態切換到跳狀態,從跳狀態切換到二段跳狀態,這里的切換就是指狀態的轉移。狀態的轉移是有條件的,比如主角從跑狀態不可以直接切換到二段跳狀態。但是可以從二段跳狀態切換到跑狀態。<br> ??另外,一個基本的狀態有:進入狀態、退出狀態、接收輸入、轉移狀態等動作。但是僅僅作為跑酷的角色的狀態管理來說,只需要轉移狀態就足夠了。有興趣的同學可以自行擴展。 ## 如何實現? ??恰好之前看到過一個還算簡易的實現(簡易就是指我能看得懂- -,希望大家也是),原版是用lua實現的,我的跑酷游戲是用C#實現的,所以直接貼出C#代碼。 ```C# using UnityEngine; using System.Collections; using System.Collections.Generic; public class FSM { // 定義函數指針類型 public delegate void FSMTranslationCallfunc(); /// <summary> /// 狀態類 /// </summary> public class FSMState { public string name; public FSMState(string name) { this.name = name; } /// <summary> /// 存儲事件對應的條轉 /// </summary> public Dictionary <string,FSMTranslation> TranslationDict = new Dictionary<string,FSMTranslation>(); } /// <summary> /// 跳轉類 /// </summary> public class FSMTranslation { public FSMState fromState; public string name; public FSMState toState; public FSMTranslationCallfunc callfunc; // 回調函數 public FSMTranslation(FSMState fromState,string name, FSMState toState,FSMTranslationCallfunc callfunc) { this.fromState = fromState; this.toState = toState; this.name = name; this.callfunc = callfunc; } } // 當前狀態 private FSMState mCurState; Dictionary <string,FSMState> StateDict = new Dictionary<string,FSMState>(); /// <summary> /// 添加狀態 /// </summary> /// <param name="state">State.</param> public void AddState(FSMState state) { StateDict [state.name] = state; } /// <summary> /// 添加條轉 /// </summary> /// <param name="translation">Translation.</param> public void AddTranslation(FSMTranslation translation) { StateDict [translation.fromState.name].TranslationDict [translation.name] = translation; } /// <summary> /// 啟動狀態機 /// </summary> /// <param name="state">State.</param> public void Start(FSMState state) { mCurState = state; } /// <summary> /// 處理事件 /// </summary> /// <param name="name">Name.</param> public void HandleEvent(string name) { if (mCurState != null && mCurState.TranslationDict.ContainsKey(name)) { Debug.LogWarning ("fromState:" + mCurState.name); mCurState.TranslationDict [name].callfunc (); mCurState = mCurState.TranslationDict [name].toState; Debug.LogWarning ("toState:" + mCurState.name); } } } ``` 測試代碼(需自行修改): ```C# // Idle, 閑置 // Run, 跑 // Jump, 一段跳 // DoubleJump, 二段跳 // Die, 掛彩 // 創建狀態 FSM.FSMState idleState = new FSM.FSMState("idle"); FSM.FSMState runState = new FSM.FSMState("run"); FSM.FSMState jumpState = new FSM.FSMState("jump"); FSM.FSMState doubleJumpState = new FSM.FSMState("double_jump"); FSM.FSMState dieState = new FSM.FSMState("die"); // 創建跳轉 FSM.FSMTranslation touchTranslation1 = new FSM.FSMTranslation(runState,"touch_down",jumpState,Jump); FSM.FSMTranslation touchTranslation2 = new FSM.FSMTranslation(jumpState,"touch_down",doubleJumpState,DoubleJump); FSM.FSMTranslation landTranslation1 = new FSM.FSMTranslation(jumpState,"land",runState,Run); FSM.FSMTranslation landTranslation2 = new FSM.FSMTranslation(doubleJumpState,"land",runState,Run); // 添加狀態 PlayerModel.Instance ().fsm.AddState (idleState); PlayerModel.Instance ().fsm.AddState (runState); PlayerModel.Instance ().fsm.AddState (jumpState); PlayerModel.Instance ().fsm.AddState (doubleJumpState); PlayerModel.Instance ().fsm.AddState (dieState); // 添加跳轉 PlayerModel.Instance ().fsm.AddTranslation (touchTranslation1); PlayerModel.Instance ().fsm.AddTranslation (touchTranslation2); PlayerModel.Instance ().fsm.AddTranslation (landTranslation1); PlayerModel.Instance ().fsm.AddTranslation (landTranslation2); PlayerModel.Instance ().fsm.Start (runState); ``` ??就這些,想要進一步擴展的話,可以給 FSMState 類添加 EnterCallback 和 ExitCallback 等委托,然后在 FSM 的 HandleEvent 方法中進行調用。當時對跑酷的項目來說夠用了,接沒繼續擴展了,我好懶- -,懶的借口是:沒有最好的設計,只有最適合的設計,233333。 此篇的內容就這些。 轉載請注明地址:涼鞋的筆記:[liangxiegame.com](http://liangxiegame.com) ## 更多內容 * QFramework 地址:[https://github.com/liangxiegame/QFramework](https://github.com/liangxiegame/QFramework) * QQ 交流群:[623597263](http://shang.qq.com/wpa/qunwpa?idkey=706b8eef0fff3fe4be9ce27c8702ad7d8cc1bceabe3b7c0430ec9559b3a9ce66) * **Unity 進階小班**: * 主要訓練內容: * 框架搭建訓練(第一年) * 跟著案例學 Shader(第一年) * 副業的孵化(第二年、第三年) * 權益、授課形式等具體詳情請查看[《小班產品手冊》](https://liangxiegame.com/master/intro):https://liangxiegame.com/master/intro * 關注公眾號:liangxiegame 獲取第一時間更新通知及更多的免費內容。 ![](http://file.liangxiegame.com/38eccb55-40b2-4845-93d6-f5fb50ff9492.png)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看