• <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>
            posts - 3,  comments - 0,  trackbacks - 0

            以下摘自【設計模式精解(GoF 23種設計解析附C++實現源碼)】中關于狀態機模式的介紹

                  有限狀態自動機(FSM)也是一個典型的狀態不同,對輸入有不同的響應(狀態轉移)。通常我們在實現這類系統會使用到很多的Switch/Case語句,Case某種狀態,發生什么動作,Case另外一種狀態,則發生另外一種狀態。但是這種實現方式至少有以下兩個問題:
                  1)當狀態數目不是很多的時候,Switch/Case可能可以搞定。但是當狀態數目很多的時候(實際系統中也正是如此),維護一大組的Switch/Case語句將是一件異常困難并且容易出錯的事情。
                  2)狀態邏輯和動作實現沒有分離。在很多的系統實現中,動作的實現代碼直接寫在狀態的邏輯當中。這帶來的后果就是系統的擴展性和維護得不到保證。
            State模式就是被用來解決上面列出的兩個問題的,在State模式中我們將狀態邏輯和動作實現進行分離。當一個操作中要維護大量的case分支語句,并且這些分支依賴于對象的狀態。State模式將每一個分支都封裝到獨立的類中。

            在這里【設計模式精解(GoF 23種設計解析附C++實現源碼)】中的代碼那樣,我只是解釋一個模型,實現一個模型,用棧來管理游戲狀態。你可以稱呼它為游戲狀態管理棧等。
            說明:
            由于考慮到游戲中的狀態管理一般只有一個,故這里采用單鍵模式模型。
            由于考慮到會增加復雜度,這里不考慮模板(按道理應該采用模板,以增加代碼可重用性,當然,用了模板就不再是純單鍵模式了)

            好了,老樣子,上代碼

            先看看定義代碼
            頭文件STATEMANAGER.H
             1//********************************************************************
             2//    STATEMANAGER.H    文件注釋
             3//    文件名  :    STATEMANAGER.H
             4//    文件路徑:    J:\CODING\游戲引擎\STATEMANAGER\
             5//    作者    :    RIPPLE
             6//    創建時間:    2009/10/3 13:44
             7//    文件描述:    游戲狀態管理棧類聲明
             8//*********************************************************************
             9
            10#ifndef _H_STATEMANGER_H_
            11#define _H_STATEMANGER_H_
            12namespace ripple
            13{
            14    //********************************************************************
            15    //    CStateManager    類注釋
            16    //    類名    :    CStateManager
            17    //  基類名稱:    NULL
            18    //  命名空間:    ripple
            19    //    作者    :    RIPPLE
            20    //    創建時間:    2009/10/3 13:45
            21    //    類描述  :    游戲狀態管理類。一般游戲只會有一個狀態管理,故采用單鍵模式管理
            22    //*********************************************************************
            23
            24    class CStateManager
            25    {
            26    public:    
            27        static CStateManager& getSingleton();        //返回引用,這步至關重要。
            28        static CStateManager* getSingletonPtr();    //返回單鍵指針
            29        
            30        virtual ~CStateManager();
            31
            32        //定義狀態調用函數指針類型
            33        typedef void (*StateCallFunc)();
            34
            35        //定義狀態結構
            36        typedef struct tagState
            37        {    
            38            tagState()                
            39            {
            40                this->Update = NULL;
            41                this->Next = NULL;
            42            }

            43            StateCallFunc Update;    //各個狀態調用的函數指針
            44            tagState* Next;            //下個函數狀態的地址(如果有的話)
            45        }
            STATE;
            46
            47        void Push(StateCallFunc func);    //插入一個狀態
            48        BOOL Pop();                        //彈出一個狀態
            49        BOOL Process();                    //執行棧頂狀態的更新函數
            50
            51    private:
            52        CStateManager();
            53        STATE* mp_TopState;
            54        static CStateManager* ms_Singleton; 
            55    }
            ;
            56
            57}

            58#endif

            對應的實現,源文件STATEMANAGER.CPP
             1//********************************************************************
             2//    STATEMANAGER.CPP    文件注釋
             3//    文件名  :    STATEMANAGER.CPP
             4//    文件路徑:    J:\CODING\游戲引擎\STATEMANAGER\
             5//    作者    :    RIPPLE
             6//    創建時間:    2009/10/3 13:47
             7//    文件描述:    CSteteManager游戲狀態管理類實現
             8//*********************************************************************
             9
            10#include <windows.h>
            11#include "StateManager.h"
            12//引用ripple命名空間
            13using namespace ripple;
            14//初始化靜態指針
            15CStateManager* CStateManager::ms_Singleton = NULL;
            16//返回單鍵引用,必須返回引用,否則,會在返回時復制一次對象,將導致出錯
            17CStateManager& CStateManager::getSingleton()
            18{
            19    if (NULL == CStateManager::ms_Singleton)
            20    {
            21        new CStateManager();
            22    }

            23    return *CStateManager::ms_Singleton;
            24}

            25//返回單鍵指針
            26CStateManager* CStateManager::getSingletonPtr()
            27{
            28    if (NULL == CStateManager::ms_Singleton)
            29    {
            30        new CStateManager();
            31    }

            32    return CStateManager::ms_Singleton;
            33}

            34//構造函數
            35CStateManager::CStateManager()
            36{
            37    this->mp_TopState = NULL;
            38    CStateManager::ms_Singleton = this;
            39}

            40//析構函數
            41CStateManager::~CStateManager()
            42{
            43    STATE* tmp;
            44    while ((tmp = this->mp_TopState) != NULL)
            45    {
            46        this->mp_TopState = this->mp_TopState->Next;
            47        delete tmp;
            48    }

            49    if (NULL != CStateManager::ms_Singleton)
            50    {
            51        delete CStateManager::ms_Singleton;
            52        CStateManager::ms_Singleton = NULL;
            53    }

            54}

            55//插入一個狀態
            56void CStateManager::Push(StateCallFunc func)
            57{
            58    if(NULL != func)
            59    {
            60        STATE* tmp = new STATE;
            61        tmp->Next = this->mp_TopState;
            62        tmp->Update = func;
            63        this->mp_TopState = tmp;
            64    }

            65}

            66//彈出一個狀態
            67BOOL CStateManager::Pop()
            68{
            69    STATE* tmp = this->mp_TopState;
            70    if (NULL != tmp)
            71    {
            72        this->mp_TopState = this->mp_TopState->Next;
            73        delete tmp;
            74    }

            75
            76    if (NULL == this->mp_TopState)
            77    {
            78        return FALSE;
            79    }

            80
            81    return TRUE;
            82}

            83//執行棧頂狀態的更新函數
            84BOOL CStateManager::Process()
            85{
            86    if (NULL != this->mp_TopState)
            87    {
            88        this->mp_TopState->Update();
            89        return TRUE;
            90    }

            91    return FALSE;
            92}
            測試代碼 TEST.CPP

             1//********************************************************************
             2//    TEST.CPP    文件注釋
             3//    文件名  :    TEST.CPP
             4//    文件路徑:    J:\CODING\游戲引擎\STATEMANAGER\
             5//    作者    :    RIPPLE
             6//    創建時間:    2009/10/3 13:59
             7//    文件描述:    測試CStateManager類是否可以正常使用
             8//*********************************************************************
             9
            10#include <iostream>
            11#include <Windows.h>
            12#include "StateManager.h"
            13using namespace std;
            14using namespace ripple;
            15//分別定義三個函數,在具體實現時,可以是個狀態對象之類的。
            16//每個函數中都會將自己彈出,已使得其他函數有機會執行
            17void fun1()
            18{
            19    cout<<"call fun1"<<endl;
            20    CStateManager::getSingleton().Pop();
            21}

            22void fun2()
            23{
            24    cout<<"call fun2"<<endl;
            25    CStateManager::getSingleton().Pop();
            26}

            27
            28void fun3()
            29{
            30    cout<<"call fun3"<<endl;
            31    CStateManager::getSingleton().Pop();
            32}

            33
            34
            35int main()
            36{
            37    //將三個函數壓入棧內
            38    //使用指針
            39    CStateManager::getSingletonPtr()->Push(fun1);
            40    //使用引用
            41    CStateManager::getSingleton().Push(fun2);
            42    //使用指針
            43    CStateManager::getSingletonPtr()->Push(fun3);
            44    //循環調用,當棧空是返回FALSE
            45    while (FALSE != CStateManager::getSingleton().Process())
            46    {
            47    }

            48    return 0;
            49}

            運行結果:
            1call fun3
            2call fun2
            3call fun1
            4請按任意鍵繼續. .

            這只是個模型,大家可以在此基礎上,編寫更多更靈活的代碼。

            版權所有,轉載請注明出處!
            如果對本文有不解之處,可以聯系本人(yeduwu@163.com)。或在此博客留言。
            有不同見解者,亦可以通過上述通道聯系本人。。歡迎指教。
            posted on 2009-10-03 14:07 賴建全 閱讀(230) 評論(0)  編輯 收藏 引用 所屬分類: 【游戲框架基礎】
            <2025年5月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            本博客所有文章,均為本人所著!版權所有,轉載請注明出處! 如果對本文有不解之處,可以聯系本人(yeduwu@163.com)。或在此博客留言。 有不同見解者,亦可以通過上述通道聯系本人。。歡迎指教。

            留言簿

            隨筆檔案(3)

            文章分類(2)

            文章檔案(2)

            最新隨筆

            搜索

            •  

            積分與排名

            • 積分 - 2986
            • 排名 - 1839

            最新評論

            閱讀排行榜

            評論排行榜

            一本综合久久国产二区| 国产精品中文久久久久久久| 99久久无色码中文字幕| 久久精品中文无码资源站| 亚洲成色WWW久久网站| 亚洲级αV无码毛片久久精品| 日韩亚洲国产综合久久久| 最新久久免费视频| 久久99热国产这有精品| 久久最新精品国产| 综合人妻久久一区二区精品| 2021国产精品久久精品| 久久久av波多野一区二区| 久久婷婷综合中文字幕| 久久天天日天天操综合伊人av| 午夜精品久久影院蜜桃| 久久亚洲AV成人无码电影| 99久久国产综合精品网成人影院| 日韩久久久久中文字幕人妻 | 久久国产欧美日韩精品| 97精品依人久久久大香线蕉97 | 蜜桃麻豆www久久| 色综合久久中文字幕无码| 国产午夜精品久久久久九九电影| 亚洲另类欧美综合久久图片区| 国产偷久久久精品专区| 久久精品成人一区二区三区| 久久久久久久久久免免费精品| 精品久久久久中文字幕日本| 久久精品国产亚洲麻豆| 一本色道久久88精品综合| 久久国产香蕉视频| 国产免费久久精品丫丫| 亚洲综合伊人久久大杳蕉| 日韩精品国产自在久久现线拍| 久久久久精品国产亚洲AV无码| 99久久婷婷国产一区二区| 精品久久久噜噜噜久久久| 亚洲人成伊人成综合网久久久 | 久久久久久国产a免费观看黄色大片| 国内精品久久人妻互换|