• <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>

            天行健 君子當(dāng)自強(qiáng)而不息

            游戲程序流、狀態(tài)處理機(jī)、進(jìn)程管理器、數(shù)據(jù)包系統(tǒng)的實(shí)現(xiàn)


            要在游戲開(kāi)發(fā)最初清楚地知道需要做些什么,就必須構(gòu)造程序的操作流,并確保能夠很容易地對(duì)程序進(jìn)行修改。
            一個(gè)典型的程序,首先要初始化所有的系統(tǒng)和數(shù)據(jù),然后進(jìn)入主循環(huán),大部分事情都出現(xiàn)在主循環(huán)中,根據(jù)游戲狀態(tài)(標(biāo)題畫(huà)面,菜單畫(huà)面,游戲畫(huà)面等),需要對(duì)輸入和輸出進(jìn)行不同的處理。

            下面是一個(gè)標(biāo)準(zhǔn)游戲應(yīng)用程序應(yīng)該遵循的步驟:

            1、初始化系統(tǒng)(Windows,圖形,輸入等)。
            2、準(zhǔn)備數(shù)據(jù)(加載配置文件)。
            3、配置缺省狀態(tài)(一般是標(biāo)題畫(huà)面)。
            4、開(kāi)始主循環(huán)。
            5、判定狀態(tài)并通過(guò)獲取輸入、輸出并對(duì)之進(jìn)行處理。
            6、如果應(yīng)用程序沒(méi)結(jié)束,則返回第5步,否則進(jìn)行第7步。
            7、清除數(shù)據(jù)(釋放內(nèi)存資源等)。
            8、釋放系統(tǒng)(Windows,圖形,輸入等)。

            狀態(tài)處理機(jī)的實(shí)現(xiàn)

            狀態(tài)是運(yùn)行狀態(tài)的簡(jiǎn)稱(chēng),表示正在運(yùn)行的應(yīng)用程序所包含的當(dāng)前處理過(guò)程。

            基于狀態(tài)的編程(state-based programming)本質(zhì)上是根據(jù)狀態(tài)的一個(gè)棧分支執(zhí)行,每個(gè)狀態(tài)表示一個(gè)對(duì)象或函數(shù)集,如果需要添加函數(shù),只需要將它們加入到棧中。當(dāng)用完函數(shù)后,再?gòu)臈V幸瞥羲鼈儭?br>
            使用狀態(tài)管理器可以添加刪除處理狀態(tài),當(dāng)添加一個(gè)狀態(tài)時(shí),這個(gè)狀態(tài)就被壓入棧中,這樣當(dāng)管理器還在處理時(shí),就獲得了當(dāng)前的控制權(quán),一旦狀態(tài)被彈出棧,最上面的狀態(tài)就被丟棄了,接著就會(huì)處理第二高的狀態(tài)。

            如下如所示:這是一個(gè)可以在需要時(shí)將狀態(tài)壓入(push)和彈出(pop)的棧



            因此需要實(shí)現(xiàn)一個(gè)接收指向函數(shù)(此函數(shù)表示狀態(tài))指針的狀態(tài)管理器,壓入一個(gè)狀態(tài)也就變成了將函數(shù)指針加入到棧中,調(diào)用狀態(tài)管理器就會(huì)處理?xiàng)V凶钌厦娴臓顟B(tài)。

            以下是一個(gè)簡(jiǎn)單的實(shí)現(xiàn):

            /*******************************************************************************
            PURPOSE:
                State-based processing Demo.
            ******************************************************************************
            */

            #include 
            <windows.h>
            #include 
            <stdio.h>

            class STATE_MANAGER
            {
            private:
                typedef 
            void (*STATE_FUNC_PTR)();

                
            // A structure that stores a function pointer and linker list
                struct STATE
                {
                    STATE_FUNC_PTR  func;
                    STATE
            * next;
                };

            protected:
                STATE
            * _state_parent;        // the top state in the stack (the head of the stack)

            public:
                STATE_MANAGER()
                {
                    _state_parent 
            = NULL;
                }

                
            ~STATE_MANAGER()
                {
                    STATE
            * state_ptr;

                    
            // remove all states from the stack
                    while((state_ptr = _state_parent) != NULL)
                    {
                        _state_parent 
            = state_ptr->next;
                        delete state_ptr;
                    }
                }

                
            // push a function on to the stack
                void Push(STATE_FUNC_PTR func)
                {
                    
            // do not push a null value
                    if(func == NULL)
                        
            return;

                    
            // allocate a new state and push it on stack

                    STATE
            * state_ptr = new STATE;

                    state_ptr
            ->next  = _state_parent;
                    state_ptr
            ->func  = func;

                    _state_parent    
            = state_ptr;        
                }

                BOOL Pop()
                {
                    STATE
            * state_ptr = _state_parent;

                    
            // remove the head of statck (if any)
                    if(state_ptr != NULL)
                    {
                        _state_parent 
            = state_ptr->next;
                        delete state_ptr;
                    }

                    
            // return TRUE if more states exist, FALSE otherwise.
                    return (_state_parent != NULL);
                }

                BOOL Process()
                {
                    
            // return an error if no more states
                    if(_state_parent == NULL)
                        
            return FALSE;

                    
            // process the top-most state (if any)
                    _state_parent->func();

                    
            return TRUE;
                }
            };

            STATE_MANAGER g_state_manager;

            // macro to ease the use of MessageBox function
            #define MB(s) MessageBox(NULL, s, s, MB_OK);

            // state function prototypes - must follow this protytype!

            void Func1()
            {
                MB(
            "1");
                g_state_manager.Pop();
            }

            void Func2()
            {
                MB(
            "2");
                g_state_manager.Pop();
            }

            void Func3()
            {
                MB(
            "3");
                g_state_manager.Pop();
            }

            int PASCAL WinMain(HINSTANCE inst, HINSTANCE, LPSTR cmd_line, int cmd_show)
            {
                g_state_manager.Push(Func1);
                g_state_manager.Push(Func2);
                g_state_manager.Push(Func3);

                
            while(g_state_manager.Process() == TRUE)
                    ;

                
            return 0;
            }

            進(jìn)程管理器的實(shí)現(xiàn)

            如果正在使用單獨(dú)的模塊來(lái)處理所有的中間函數(shù)(稱(chēng)為進(jìn)程),比如輸入,網(wǎng)絡(luò)以及聲音處理過(guò)程,而不是一個(gè)一個(gè)單獨(dú)調(diào)用,就可以創(chuàng)建一個(gè)對(duì)象來(lái)一次全部處理。

            下圖表示一個(gè)由頻繁調(diào)用的函數(shù)組成的進(jìn)程棧,當(dāng)調(diào)用時(shí),添加到管理器的每個(gè)函數(shù)都是按序執(zhí)行的。



            如下是一個(gè)簡(jiǎn)單的實(shí)現(xiàn):

            /*******************************************************************************
            PURPOSE:
                Stack Process Demo.
            ******************************************************************************
            */

            #include 
            <windows.h>
            #include 
            <stdio.h>

            class PROCESS_MANAGER
            {
            private:
                typedef 
            void (*PROCESS_FUNC_PTR)();

                
            // A structure that stores a function pointer and linked list
                struct PROCESS
                {
                    PROCESS_FUNC_PTR func;
                    PROCESS
            * next;
                };

            protected:
                PROCESS
            * process_parent;    // the top process in the stack (the head of the stack)

            public:
                PROCESS_MANAGER()
                {
                    process_parent 
            = NULL;
                }

                
            ~PROCESS_MANAGER()
                {
                    PROCESS
            * process_ptr;

                    
            // remove all processes from the stack
                    while((process_ptr = process_parent) != NULL)
                    {
                        process_parent 
            = process_ptr->next;
                        delete process_ptr;
                    }
                }

                
            // add function on to the stack
                void Add(PROCESS_FUNC_PTR process)
                {
                    
            // do not push a NULL value
                    if(process == NULL)
                        
            return;

                    
            // allocate a new process and push it onto stack
                    PROCESS* process_ptr = new PROCESS;

                    process_ptr
            ->func = process;
                    process_ptr
            ->next = process_parent;

                    process_parent  
            = process_ptr;
                }

                
            // process all functions
                void Process()
                {
                    PROCESS
            * process_ptr = process_parent;

                    
            while(process_ptr != NULL)
                    {
                        process_ptr
            ->func();
                        process_ptr 
            = process_ptr->next;
                    }
                }
            };

            PROCESS_MANAGER g_process_manager;


            // Macro to ease the use of MessageBox function
            #define MB(s) MessageBox(NULL, s, s, MB_OK);

            // Processfunction prototypes - must follow this prototype!
            void Func1() { MB("1"); }
            void Func2() { MB("2"); }
            void Func3() { MB("3"); }

            int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR cmdLine, int cmdShow)
            {
                g_process_manager.Add(Func1);
                g_process_manager.Add(Func2);
                g_process_manager.Add(Func3);

                g_process_manager.Process();
                g_process_manager.Process();

                
            return 0;
            }

            這個(gè)對(duì)象PROCESS_MANAGER類(lèi)似于STATE_MANAGER,但有點(diǎn)不同,PROCESS_MANAGER只添加進(jìn)程而不刪除它們。

            數(shù)據(jù)包系統(tǒng)的實(shí)現(xiàn)

            處理應(yīng)用程序數(shù)據(jù),最容易的方法就是創(chuàng)建一個(gè)數(shù)據(jù)包系統(tǒng),來(lái)處理保存和加載數(shù)據(jù)的工作。通過(guò)創(chuàng)建一個(gè)包含數(shù)據(jù)緩沖區(qū)的對(duì)象,就能添加一個(gè)新函數(shù)來(lái)保存和加載數(shù)據(jù)。

            下圖形象的給出了數(shù)據(jù)存儲(chǔ)的方式,因?yàn)閿?shù)據(jù)緩沖區(qū)足夠大,可以存儲(chǔ)每個(gè)人名實(shí)例。在這種情況下,存儲(chǔ)了兩個(gè)名字,每個(gè)名字使用32字節(jié),加起來(lái)一共使用了64字節(jié)大小的緩沖區(qū)。



            下面是一個(gè)簡(jiǎn)單的實(shí)現(xiàn):

            /*******************************************************************************
            PURPOSE:
                Data Storage Demo.
            ******************************************************************************
            */

            #include 
            <windows.h>
            #include 
            <stdio.h>

            #pragma warning(disable : 
            4996)

            class DATA_PACKAGE
            {
            protected:
                
            // data buffer and size
                void* _buf;
                unsigned 
            long _size;

            public:
                DATA_PACKAGE()
                {
                    _buf  
            = NULL;
                    _size 
            = 0;
                }

                
            ~DATA_PACKAGE()
                {
                    Free();
                }

                
            void* Create(unsigned long size)
                {
                    
            // free a previous created buffer
                    Free();

                    
            // allocate some memory and return a pointer
                    _size = size;

                    
            if((_buf = (void*new char[size]) == NULL)
                        
            return NULL;

                    memset(_buf, 
            0, size);
                    
            return _buf;
                }

                
            // free the allocated memory
                void Free()
                {
                    delete _buf; _buf 
            = NULL;
                    _size 
            = 0;
                }

                BOOL Save(
            const char* filename)
                {
                    FILE
            * fp;

                    
            // make sure there is something to write
                    if(_buf == NULL || _size == 0)
                        
            return FALSE;

                    
            // open file, write size and data.
                    if((fp = fopen(filename, "wb")) == NULL)
                        
            return FALSE;

                    fwrite(
            &_size, 14, fp);
                    fwrite(_buf, 
            1, _size, fp);

                    fclose(fp);
                    
            return TRUE;
                }

                
            void* Load(const char* filename, unsigned long* size)
                {
                    FILE
            * fp;

                    
            // free a prior buffer
                    Free();

                    
            if((fp = fopen(filename, "rb")) == NULL)
                        
            return NULL;

                    
            // read in size and data
                    fread(&_size, 14, fp);

                    
            if((_buf = (void*new char[_size]) == NULL)
                        
            return NULL;

                    fread(_buf, 
            1, _size, fp);
                    fclose(fp);

                    
            // store size to return
                    if(size != NULL)
                        
            *size = _size;

                    
            // return pointer
                    return _buf;
                }
            };

            // a structure to contain a name
            struct NAME
            {
                
            char name[32];
            };

            int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR cmdLine, int cmdShow)
            {
                DATA_PACKAGE data_package;
                DWORD size;

                
            // create the data package (w/64 bytes) and get the pointer, casting it to an NAME structure type.
                NAME* names = (NAME*) data_package.Create(64);

                
            // since there are 64 bytes total, and each name uses 32 bytes, then I can have 2 names stored.
                strcpy(names[0].name, "Jim");
                strcpy(names[
            1].name, "Adams");

                
            const char* filename = "names.data";

                
            // save the names to disk
                data_package.Save(filename);    
                
            // load the names from disk, size will equal 64 when the load function returns.
                names = (NAME*) data_package.Load(filename, &size);

                
            // display the names
                MessageBox(NULL, names[0].name, "1st name", MB_OK);
                MessageBox(NULL, names[
            1].name, "2nd name", MB_OK);

                
            return 0;
            }

            程序框架的實(shí)現(xiàn)

            從最基本的層面而言,框架應(yīng)該包含初始化應(yīng)用程序窗口的代碼,各種引擎(圖形,輸入,網(wǎng)絡(luò),聲音),處理初始化,每幀渲染,以及退出清理函數(shù)。

            以下是一個(gè)簡(jiǎn)單的實(shí)現(xiàn):

            /*****************************************************************************
            PURPOSE:
                Shell Application.
             ****************************************************************************
            */

            #include 
            <windows.h>
            #include 
            <stdio.h>

            #define WINDOW_WIDTH    400
            #define WINDOW_HEIGHT   400

            // window handles, class and caption text.
            HWND        g_hwnd;
            HINSTANCE    g_inst;
            static char g_classname[] = "ShellClass";
            static char g_caption[]   = "Shell Application";

            long FAR PASCAL Window_Proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
            BOOL Do_Init();
            BOOL Do_Shutdown();
            BOOL Do_Frame();

            int PASCAL WinMain(HINSTANCE inst, HINSTANCE, LPSTR cmd_line, int cmd_show)
            {
                WNDCLASSEX wnd_class;
                MSG msg;

                g_inst 
            = inst;

                
            // create the window class here and register it
                wnd_class.cbSize        = sizeof(wnd_class);
                wnd_class.style            
            = CS_CLASSDC;
                wnd_class.lpfnWndProc    
            = Window_Proc;
                wnd_class.cbClsExtra    
            = 0;
                wnd_class.cbWndExtra    
            = 0;
                wnd_class.hInstance        
            = inst;
                wnd_class.hIcon            
            = LoadIcon(NULL, IDI_APPLICATION);
                wnd_class.hCursor        
            = LoadCursor(NULL, IDC_ARROW);
                wnd_class.hbrBackground    
            = NULL;
                wnd_class.lpszMenuName    
            = NULL;
                wnd_class.lpszClassName 
            = g_classname;
                wnd_class.hIconSm        
            = LoadIcon(NULL, IDI_APPLICATION);

                
            if(! RegisterClassEx(&wnd_class))
                    
            return FALSE;

                
            // create the main window
                g_hwnd = CreateWindow(g_classname, g_caption, WS_CAPTION | WS_SYSMENU, 
                                      
            00, WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, inst, NULL);

                
            if(! g_hwnd)
                    
            return FALSE;

                ShowWindow(g_hwnd, SW_NORMAL);
                UpdateWindow(g_hwnd);

                
            // run init function and return on error
                if(! Do_Init())
                    
            return FALSE;

                
            // start message pump, waiting for singal to quit.
                ZeroMemory(&msg, sizeof(MSG));

                
            while(msg.message != WM_QUIT)
                {
                    
            if(PeekMessage(&msg, NULL, 00, PM_REMOVE))
                    {
                        TranslateMessage(
            &msg);
                        DispatchMessage(
            &msg);
                    }

                    
            if(! Do_Frame())
                        
            break;
                }
                
                
            // run shutdown function
                Do_Shutdown();

                UnregisterClass(g_classname, inst);

                
            return int(msg.wParam);
            }

            long FAR PASCAL Window_Proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
            {
                
            switch(msg)
                {
                
            case WM_DESTROY:
                    PostQuitMessage(
            0);
                    
            return 0;
                }

                
            return long(DefWindowProc(hWnd, msg, wParam, lParam));
            }

            BOOL Do_Init()
            {
                
            return TRUE;
            }

            BOOL Do_Shutdown()
            {
                
            return TRUE;
            }

            BOOL Do_Frame()
            {
                
            return TRUE;
            }

            posted on 2007-06-10 21:23 lovedday 閱讀(1000) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): ■ RPG Program

            公告

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            隨筆分類(lèi)(178)

            3D游戲編程相關(guān)鏈接

            搜索

            最新評(píng)論

            综合久久给合久久狠狠狠97色 | 日产精品久久久久久久| 一级女性全黄久久生活片免费 | 亚洲国产精品久久久天堂| 一级做a爰片久久毛片人呢| 国产A三级久久精品| 久久夜色精品国产www| 日本精品久久久久中文字幕| 亚洲级αV无码毛片久久精品| www久久久天天com| 久久无码人妻一区二区三区| 国内精品综合久久久40p| 97久久超碰国产精品旧版| 久久国产精品无码HDAV| 亚洲综合伊人久久综合| 香蕉久久夜色精品国产小说| 2021最新久久久视精品爱| 精品久久久久久亚洲精品| 久久综合鬼色88久久精品综合自在自线噜噜 | 久久精品极品盛宴观看| 久久久国产精品福利免费| 久久人人爽人人爽人人片av麻烦| 久久国产免费| 久久这里有精品| 久久久久女教师免费一区| 久久精品国产精品青草app| www亚洲欲色成人久久精品| 久久精品二区| www亚洲欲色成人久久精品| 精品国产福利久久久| 国内精品久久久久久99| 亚洲AV无码久久精品狠狠爱浪潮| 亚洲国产成人乱码精品女人久久久不卡| 91久久精一区二区三区大全| 99久久国产宗和精品1上映| 久久99国产精品久久99小说| 亚洲午夜福利精品久久| 亚洲欧美精品一区久久中文字幕| 久久久久亚洲?V成人无码| 久久亚洲2019中文字幕| 久久精品中文字幕有码|