• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            3d Game Walkman

            3d圖形渲染,網絡引擎 — tonykee's Blog
            隨筆 - 45, 文章 - 0, 評論 - 309, 引用 - 0
            數據加載中……

            淺談狀態(tài)機FSM設計方法

            看了一晚上FSM方面的資料,頗有收獲,寫寫感悟:

            狀態(tài)機,在游戲里面是非常重要的,最簡單的狀態(tài)機,莫過于

            switch()
             case 1:
                if(not 反復執(zhí)行狀態(tài)1)
                   進入1狀態(tài)前要做的準備

                進入1狀態(tài)的過程

                if(not 反復執(zhí)行狀態(tài)1)
                   離開狀態(tài)1的過程

              case2:
            ...

            但這種方式不能很有效預定義所有的狀態(tài),也不能把這些狀態(tài)之間的切換過程合理的定義出來,“狀態(tài)”本身沒有一個合理的定義,幾乎是一種面向過程的方式,只過這種方式足夠簡單,也最容易讓人接受,缺點就沒有“狀態(tài)”的定義和指派功能,導致狀態(tài)的混亂,出現狀態(tài)處理重復代碼,甚至處理不一致的問題,按照OO的觀念,狀態(tài)描述本來就應該是一種實體

            比如“吃飯”這種狀態(tài),進入要做什么,進行時要做什么,退出時要做什么,需要進行一個描述,以下是我寫的狀態(tài)機管理策略:

            //狀態(tài)的定義
            class State
            {
            public:

             State();

             State(const char * name);

             //狀態(tài)的名字
             std::string statename;
             //比較兩個狀態(tài)是否相同
             inline bool operator ==(const State& other);
            };


            //狀態(tài)機基類
            class BaseFsm
            {

            public:

             //狀態(tài)機的狀態(tài)描述
             State state;

             //進入狀態(tài)
             virtual void Enter(FsmEntity *entity);

             //執(zhí)行狀態(tài)
             virtual void Execute(FsmEntity *entity);

             //離開狀態(tài)
             virtual void Exit(FsmEntity *entity);

             //比較兩個狀態(tài)機是否相同
             inline bool operator ==(const BaseFsm& other);
            };


            //狀態(tài)機實體
            class FsmEntity
            {

            protected:

              //當前所使用的狀態(tài)機
              BaseFsm *mCurrentFsm;

            public:

              //構造函數
              FsmEntity();

              //析構函數
              virtual ~FsmEntity();

              //設置開始狀態(tài)
              void InitState(BaseFsm *fsm);

              //狀態(tài)是否初始化了
              bool IsStateInited();

              //保持狀態(tài)的方法
              void KeepState();

              //返回當前的狀態(tài)機
              BaseFsm * GetCurrentFsm();

              //改變狀態(tài)
              void ChangeState(BaseFsm *newFsm);
            };


            //狀態(tài)機容器
            class FsmManager
            {

            private:

            //狀態(tài)機容器的名稱
             std::string name;

             //所有的狀態(tài)集合
             std::map<std::string, BaseFsm *> mStatusCollection;

            public:

             //命令一些實體去達到某個狀態(tài)
             void Transaction(std::vector<FsmEntity *> & entities, const char * stateName);

             //令某個實體達到某個狀態(tài)
             void Transaction(FsmEntity * entity, const char * stateName);

             //添加狀態(tài)機
             void AddFsm( BaseFsm * fsm);

             //刪除狀態(tài)機
             void RemoveFsm(const char * stateName);

             //獲取狀態(tài)機
             BaseFsm * FindFsm(const char * stateName);

                //構造
             FsmManager(const char *fsname);

             //析構
             virtual ~FsmManager();
            };




            State::State()
            {

            }

            State::State(const char * name)
            {
             statename = name;
            }


            //構造函數
            FsmEntity::FsmEntity()
            {
              mCurrentFsm = 0;
            }

            //析構函數
            FsmEntity::~FsmEntity()
            {
             
            }

            //返回當前的狀態(tài)機
            BaseFsm * FsmEntity::GetCurrentFsm()
            {
             return mCurrentFsm;
            }

            //狀態(tài)是否初始化了
            bool FsmEntity::IsStateInited()
            {
             if(mCurrentFsm)
               return true;
             else
               return false;
            }

            //設置當前狀態(tài)
            void FsmEntity::InitState(BaseFsm *fsm)
            {
             if(mCurrentFsm == 0)
             {
               mCurrentFsm = fsm;
             }
             else
             {
              LOG(0, WARN_LV, "初始狀態(tài)已經設定");
             }
            }

            //保持狀態(tài)的方法
            void FsmEntity::KeepState()
            {
             mCurrentFsm->Execute(this);
            }

            //改變狀態(tài)
            void FsmEntity::ChangeState(BaseFsm *newFsm)
            {
             if(mCurrentFsm)
                //離開原來的狀態(tài)
                mCurrentFsm->Exit(this);

             //設定現有狀態(tài)
             mCurrentFsm = newFsm;

             //進入現有狀態(tài)
             mCurrentFsm->Enter(this);

             //執(zhí)行現有的狀態(tài)
                mCurrentFsm->Execute(this);

            }


            //比較兩個狀態(tài)是否相同
            bool State::operator ==(const State& other)
            {
             return statename == other.statename;
            }

             

            //進入狀態(tài)
            void BaseFsm::Enter(FsmEntity *entity)
            {
              LOG(0, DEBUG_LV, "進入%s狀態(tài)", state.statename.c_str());
            }

            //執(zhí)行狀態(tài)
            void BaseFsm::Execute(FsmEntity *entity)
            {
              LOG(0, DEBUG_LV, "執(zhí)行%s狀態(tài)", state.statename.c_str());
            }

            //離開狀態(tài)
            void BaseFsm::Exit(FsmEntity *entity)
            {
              LOG(0, DEBUG_LV, "離開%s狀態(tài)", state.statename.c_str());
            }


            bool BaseFsm::operator ==(const BaseFsm& other)
            {
                return state == other.state;
            }

            //命令一些實體去達到某個狀態(tài)
            void FsmManager::Transaction(std::vector<FsmEntity *> & entities, const char * stateName)
            {
             for(size_t i = 0; i < entities.size(); i ++)
             {
              FsmEntity *entity = entities[i];
              Transaction(entity, stateName);
             }
            }

            //令某個實體達到某個狀態(tài)
            void FsmManager::Transaction(FsmEntity * entity, const char * stateName)
            {
             if(entity->GetCurrentFsm() && entity->GetCurrentFsm()->state.statename == stateName)
             {
              entity->KeepState(); //保持之前的狀態(tài)
             }
             else
             {
              BaseFsm * fsm = mStatusCollection[stateName];
              if(fsm)
              {
               //執(zhí)行狀態(tài)
               entity->ChangeState(fsm);
              }
              else
              {
                        LOG(0, ERROR_LV, "找不到%s狀態(tài)", stateName);
              }
             }
            }

             

            //添加狀態(tài)機
            void FsmManager::AddFsm( BaseFsm * fsm)
            {
              if(mStatusCollection.find(fsm->state.statename.c_str()) != mStatusCollection.end())
               return; //已經添加過了
              //添加
              mStatusCollection[fsm->state.statename] = fsm;
            }

            //刪除狀態(tài)機
            void FsmManager::RemoveFsm(const char * stateName)
            {
              std::map<std::string, BaseFsm *>::iterator it = 0;
              if((it = mStatusCollection.find(stateName)) != mStatusCollection.end())
              {
                 mStatusCollection.erase(it);
              }
            }

            //獲取狀態(tài)機
            BaseFsm * FsmManager::FindFsm(const char * stateName)
            {
             std::map<std::string, BaseFsm *>::iterator it = 0;
             if((it = mStatusCollection.find(stateName)) != mStatusCollection.end())
             {
               BaseFsm * fsm = it->second;
               return fsm;
             }
             return 0;
            }

             

            //構造
            FsmManager::FsmManager(const char *fsname)
            {
               name = fsname;
               LOG(0, DEBUG_LV, "構造狀態(tài)機容器 %s", fsname);
            }

            //析構
            FsmManager::~FsmManager()
            {

             //移出所有的狀態(tài)機
             for(std::map<std::string, BaseFsm *>::iterator it = mStatusCollection.begin(); it!= mStatusCollection.end(); it++)
             {
                   BaseFsm * fsm = it->second;
                if(fsm)
               delete fsm;
             }

            }






            posted on 2009-08-07 17:30 李侃 閱讀(5987) 評論(5)  編輯 收藏 引用 所屬分類: 設計思路

            評論

            # re: 淺談狀態(tài)機FSM設計方法[未登錄]  回復  更多評論   

            請問能不能介紹幾本關于這方面的書呢..謝謝!!
            2009-08-08 00:30 | vibilin

            # re: 淺談狀態(tài)機FSM設計方法[未登錄]  回復  更多評論   

            其實設計模式解決這個問題的最后也得使用配置文件才能解決問題,當時有C語言時,你要是使用配置文件,一樣是可以解決的
            2009-08-08 09:11 | Alex

            # re: 淺談狀態(tài)機FSM設計方法  回復  更多評論   

            全部是網上找的資料,GEM系列書上有介紹過,資料很零碎,具體上面的狀態(tài)機封裝形式還要結合腳本引擎,才能真正發(fā)揮它的威力,我已經這么做了,總之,就是一句話:很好很強大 o(∩_∩)o...
            2009-08-08 09:43 | 李侃

            # re: 淺談狀態(tài)機FSM設計方法  回復  更多評論   


            狀態(tài)機三個字足夠包含一切
            2009-08-08 17:11 | Vincent

            # re: 淺談狀態(tài)機FSM設計方法  回復  更多評論   

            第一個真不錯,三言兩語就解釋出來了,后面這個OO的,不知道寫起來維護會如何?幾千個狀態(tài)轉換起來。。。。
            2009-08-10 12:01 | j
            蜜桃麻豆www久久| 久久久久久亚洲Av无码精品专口 | 久久精品aⅴ无码中文字字幕重口| 色婷婷久久综合中文久久一本| 久久亚洲国产最新网站| 无码国内精品久久人妻| 国产精品成人精品久久久| 99久久免费国产精品特黄| 精品久久久久香蕉网| 综合久久久久久中文字幕亚洲国产国产综合一区首 | 久久精品一区二区影院| 国产精品亚洲综合久久| jizzjizz国产精品久久| 久久综合亚洲色HEZYO社区| 久久精品一区二区国产| 久久久久亚洲AV无码专区首JN | 欧美日韩精品久久久免费观看| 久久久久人妻一区精品色 | 狠狠88综合久久久久综合网| 天堂无码久久综合东京热| 国产精品青草久久久久婷婷| 777午夜精品久久av蜜臀| 久久久久黑人强伦姧人妻| 2021久久国自产拍精品| 午夜精品久久久久久中宇| 久久久久国产精品嫩草影院| 久久综合丁香激情久久| 国内精品伊人久久久久av一坑| 久久久精品国产免大香伊| 久久久久一本毛久久久| 久久精品成人免费观看97| 精品一区二区久久| 精品免费tv久久久久久久| 久久99精品久久久久子伦| 久久久久亚洲AV无码永不| 久久久久人妻精品一区二区三区| 日韩精品久久无码中文字幕| 亚洲AV无码久久精品色欲| 久久综合给合久久狠狠狠97色| 久久精品国产2020| 久久久精品2019免费观看|