• <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圖形渲染,網(wǎng)絡(luò)引擎 — tonykee's Blog
            隨筆 - 45, 文章 - 0, 評論 - 309, 引用 - 0
            數(shù)據(jù)加載中……

            淺談狀態(tài)機(jī)FSM設(shè)計(jì)方法

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

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

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

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

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

              case2:
            ...

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

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

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

             State();

             State(const char * name);

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


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

            public:

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

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

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

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

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


            //狀態(tài)機(jī)實(shí)體
            class FsmEntity
            {

            protected:

              //當(dāng)前所使用的狀態(tài)機(jī)
              BaseFsm *mCurrentFsm;

            public:

              //構(gòu)造函數(shù)
              FsmEntity();

              //析構(gòu)函數(shù)
              virtual ~FsmEntity();

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

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

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

              //返回當(dāng)前的狀態(tài)機(jī)
              BaseFsm * GetCurrentFsm();

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


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

            private:

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

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

            public:

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

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

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

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

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

                //構(gòu)造
             FsmManager(const char *fsname);

             //析構(gòu)
             virtual ~FsmManager();
            };




            State::State()
            {

            }

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


            //構(gòu)造函數(shù)
            FsmEntity::FsmEntity()
            {
              mCurrentFsm = 0;
            }

            //析構(gòu)函數(shù)
            FsmEntity::~FsmEntity()
            {
             
            }

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

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

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

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

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

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

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

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

            }


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

             

            //進(jìn)入狀態(tài)
            void BaseFsm::Enter(FsmEntity *entity)
            {
              LOG(0, DEBUG_LV, "進(jìn)入%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;
            }

            //命令一些實(shí)體去達(dá)到某個(gè)狀態(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);
             }
            }

            //令某個(gè)實(shí)體達(dá)到某個(gè)狀態(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)機(jī)
            void FsmManager::AddFsm( BaseFsm * fsm)
            {
              if(mStatusCollection.find(fsm->state.statename.c_str()) != mStatusCollection.end())
               return; //已經(jīng)添加過了
              //添加
              mStatusCollection[fsm->state.statename] = fsm;
            }

            //刪除狀態(tài)機(jī)
            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)機(jī)
            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;
            }

             

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

            //析構(gòu)
            FsmManager::~FsmManager()
            {

             //移出所有的狀態(tài)機(jī)
             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 李侃 閱讀(5970) 評論(5)  編輯 收藏 引用 所屬分類: 設(shè)計(jì)思路

            評論

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

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

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

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

            # re: 淺談狀態(tài)機(jī)FSM設(shè)計(jì)方法  回復(fù)  更多評論   

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

            # re: 淺談狀態(tài)機(jī)FSM設(shè)計(jì)方法  回復(fù)  更多評論   


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

            # re: 淺談狀態(tài)機(jī)FSM設(shè)計(jì)方法  回復(fù)  更多評論   

            第一個(gè)真不錯(cuò),三言兩語就解釋出來了,后面這個(gè)OO的,不知道寫起來維護(hù)會如何?幾千個(gè)狀態(tài)轉(zhuǎn)換起來。。。。
            2009-08-10 12:01 | j
            久久精品一区二区三区不卡| 久久久久九国产精品| 久久久久AV综合网成人| 国产午夜免费高清久久影院| 精品久久久久久国产| 久久se精品一区精品二区国产| 亚洲国产精品一区二区三区久久| 久久久久久亚洲精品无码| 久久精品国产一区二区电影| 伊人久久综合成人网| 四虎国产精品免费久久久| 久久人人爽人人爽人人片AV麻烦| 91久久精品91久久性色| 亚洲欧美成人久久综合中文网| 久久精品人人做人人妻人人玩| 久久国产视屏| 国产成人久久精品区一区二区| 午夜视频久久久久一区| 国产99久久久久久免费看| 亚洲精品国产美女久久久| 久久久久人妻一区精品| 国产午夜精品理论片久久影视| 亚洲国产综合久久天堂| 国产高潮久久免费观看| 国产精品99久久99久久久| 久久伊人精品一区二区三区| 国产国产成人久久精品| 欧美久久综合性欧美| AV色综合久久天堂AV色综合在| 久久中文字幕精品| 一级做a爰片久久毛片免费陪| 99久久国产综合精品五月天喷水| 2021精品国产综合久久| 亚洲AV日韩精品久久久久久| 亚洲伊人久久精品影院| 久久精品久久久久观看99水蜜桃| 日韩亚洲国产综合久久久| 日韩久久无码免费毛片软件| 国产精品成人无码久久久久久| 久久亚洲欧美日本精品| 中文字幕亚洲综合久久|