青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

天行健 君子當自強而不息

游戲程序流、狀態處理機、進程管理器、數據包系統的實現


要在游戲開發最初清楚地知道需要做些什么,就必須構造程序的操作流,并確保能夠很容易地對程序進行修改。
一個典型的程序,首先要初始化所有的系統和數據,然后進入主循環,大部分事情都出現在主循環中,根據游戲狀態(標題畫面,菜單畫面,游戲畫面等),需要對輸入和輸出進行不同的處理。

下面是一個標準游戲應用程序應該遵循的步驟:

1、初始化系統(Windows,圖形,輸入等)。
2、準備數據(加載配置文件)。
3、配置缺省狀態(一般是標題畫面)。
4、開始主循環。
5、判定狀態并通過獲取輸入、輸出并對之進行處理。
6、如果應用程序沒結束,則返回第5步,否則進行第7步。
7、清除數據(釋放內存資源等)。
8、釋放系統(Windows,圖形,輸入等)。

狀態處理機的實現

狀態是運行狀態的簡稱,表示正在運行的應用程序所包含的當前處理過程。

基于狀態的編程(state-based programming)本質上是根據狀態的一個棧分支執行,每個狀態表示一個對象或函數集,如果需要添加函數,只需要將它們加入到棧中。當用完函數后,再從棧中移除掉它們。

使用狀態管理器可以添加刪除處理狀態,當添加一個狀態時,這個狀態就被壓入棧中,這樣當管理器還在處理時,就獲得了當前的控制權,一旦狀態被彈出棧,最上面的狀態就被丟棄了,接著就會處理第二高的狀態。

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



因此需要實現一個接收指向函數(此函數表示狀態)指針的狀態管理器,壓入一個狀態也就變成了將函數指針加入到棧中,調用狀態管理器就會處理棧中最上面的狀態。

以下是一個簡單的實現:

/*******************************************************************************
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;
}

進程管理器的實現

如果正在使用單獨的模塊來處理所有的中間函數(稱為進程),比如輸入,網絡以及聲音處理過程,而不是一個一個單獨調用,就可以創建一個對象來一次全部處理。

下圖表示一個由頻繁調用的函數組成的進程棧,當調用時,添加到管理器的每個函數都是按序執行的。



如下是一個簡單的實現:

/*******************************************************************************
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;
}

這個對象PROCESS_MANAGER類似于STATE_MANAGER,但有點不同,PROCESS_MANAGER只添加進程而不刪除它們。

數據包系統的實現

處理應用程序數據,最容易的方法就是創建一個數據包系統,來處理保存和加載數據的工作。通過創建一個包含數據緩沖區的對象,就能添加一個新函數來保存和加載數據。

下圖形象的給出了數據存儲的方式,因為數據緩沖區足夠大,可以存儲每個人名實例。在這種情況下,存儲了兩個名字,每個名字使用32字節,加起來一共使用了64字節大小的緩沖區。



下面是一個簡單的實現:

/*******************************************************************************
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;
}

程序框架的實現

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

以下是一個簡單的實現:

/*****************************************************************************
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 閱讀(1016) 評論(0)  編輯 收藏 引用 所屬分類: ■ RPG Program

公告

導航

統計

常用鏈接

隨筆分類(178)

3D游戲編程相關鏈接

搜索

最新評論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            99亚洲一区二区| 欧美国产日韩一区二区在线观看 | 99re8这里有精品热视频免费 | 欧美激情综合在线| 欧美插天视频在线播放| 欧美久久久久久蜜桃| 欧美日韩一区二区在线播放| 欧美小视频在线观看| 国产美女精品视频免费观看| 国产亚洲福利社区一区| 亚洲第一精品电影| 亚洲一区二区三区精品在线观看| 欧美亚洲一区二区三区| 欧美粗暴jizz性欧美20| 一本色道久久综合狠狠躁篇的优点 | 中国成人黄色视屏| 欧美一区二区三区另类| 久久综合伊人77777| 亚洲人成高清| 亚洲天堂av综合网| 久久久久网站| 国产精品播放| 亚洲理论电影网| 欧美亚洲免费| 欧美激情小视频| 午夜精品影院在线观看| 你懂的视频欧美| 国产欧美视频一区二区三区| 亚洲精品久久久一区二区三区| 午夜宅男欧美| 亚洲国产精品悠悠久久琪琪| 亚洲综合好骚| 久久精品在线观看| 国产精品高精视频免费| 91久久精品美女高潮| 欧美伊人精品成人久久综合97| 亚洲黄色三级| 老司机67194精品线观看| 国产欧美精品日韩精品| 一本久久综合| 亚洲国产精品热久久| 久久国产乱子精品免费女| 欧美三日本三级三级在线播放| 黄色亚洲网站| 欧美中文在线观看| 中文国产成人精品| 欧美日韩国产一区二区| 亚洲精品在线免费| 欧美成人自拍视频| 久久久久一区二区三区| 国产日韩一区在线| 久久精品国产第一区二区三区最新章节| 亚洲国产婷婷| 欧美福利视频网站| 亚洲人成在线播放网站岛国| 免费看精品久久片| 久久精品亚洲热| 国产一区二区三区免费不卡| 亚洲欧美中日韩| 亚洲一区二区免费看| 国产精品成人一区二区三区夜夜夜| 亚洲乱码久久| 亚洲精品小视频在线观看| 欧美精品一区二区精品网| 亚洲国产欧美一区二区三区久久 | 久久精品青青大伊人av| 亚洲一区图片| 国产一区二区三区四区| 久久精品国产欧美激情| 性一交一乱一区二区洋洋av| 国产一区二三区| 免费视频一区| 欧美高清在线一区二区| 一区二区av在线| 一本色道婷婷久久欧美| 国产精品主播| 免费永久网站黄欧美| 免费h精品视频在线播放| 亚洲人成网站在线播| 欧美大片在线观看一区| 日韩亚洲精品视频| 日韩视频―中文字幕| 国产精品乱子久久久久| 久久久久国产一区二区| 另类天堂av| 一区二区三区高清在线| 亚洲一区二区三区777| 黑人一区二区三区四区五区| 欧美成人黄色小视频| 欧美人交a欧美精品| 亚洲欧美日韩精品在线| 久久精品夜夜夜夜久久| 这里只有精品视频| 欧美在线视频观看免费网站| 亚洲激情欧美激情| 亚洲自拍偷拍视频| 亚洲国产美国国产综合一区二区| 亚洲最新视频在线播放| 在线电影欧美日韩一区二区私密| 99在线热播精品免费| 亚洲成色777777在线观看影院| 亚洲精品一区二| 悠悠资源网亚洲青| 在线性视频日韩欧美| 亚洲国产91精品在线观看| 中日韩高清电影网| 黄色一区二区在线| 亚洲一区二区三区欧美| 亚洲三级免费电影| 午夜一级久久| 亚洲伊人伊色伊影伊综合网| 久久人人爽人人爽| 午夜精品在线视频| 欧美成人免费播放| 久久只有精品| 国产日韩欧美亚洲| 亚洲婷婷综合色高清在线| 日韩一区二区免费看| 久久视频一区二区| 久久久精品国产99久久精品芒果| 国产精品高潮在线| 一区二区三区三区在线| 一区二区三区日韩在线观看| 免费视频最近日韩| 欧美不卡福利| 伊人精品久久久久7777| 欧美专区在线观看一区| 欧美一区二区三区视频免费| 国产精品免费看片| 亚洲一区在线播放| 午夜电影亚洲| 国产日韩精品电影| 欧美在线999| 久久天堂av综合合色| 国产一区二区三区免费观看| 久久大综合网| 欧美成人第一页| 亚洲国产mv| 欧美阿v一级看视频| 亚洲高清视频在线| 日韩一区二区免费看| 欧美日韩1区2区| 99re6这里只有精品视频在线观看| 国产亚洲aⅴaaaaaa毛片| 亚洲视频一区二区| 欧美三级乱码| 亚洲无线一线二线三线区别av| 中文国产成人精品久久一| 欧美日韩一区二区在线| 一区二区三区回区在观看免费视频| 亚洲午夜91| 国产精品你懂的在线| 亚洲欧美另类国产| 久久久噜噜噜久久狠狠50岁| 亚洲高清视频在线| 欧美日韩一本到| 欧美一级一区| 亚洲电影在线观看| 欧美一级在线视频| 黄网站色欧美视频| 欧美裸体一区二区三区| 亚洲中无吗在线| 免费h精品视频在线播放| 亚洲精品美女在线观看播放| 国产精品久久久久久久一区探花| 亚久久调教视频| 亚洲国产精品va| 欧美一区免费视频| 亚洲国产欧美不卡在线观看| 欧美日韩一区二区三区免费看| 亚洲一区二区在线| 欧美顶级艳妇交换群宴| 亚洲欧美999| 亚洲高清在线播放| 国产精品普通话对白| 免费观看一级特黄欧美大片| 亚洲午夜精品国产| 亚洲国产精品ⅴa在线观看| 欧美在线亚洲综合一区| 亚洲精品视频二区| 国产亚洲欧美一区二区| 欧美日韩喷水| 蜜臀久久99精品久久久久久9 | 欧美中文在线观看| 亚洲欧洲精品一区二区精品久久久| 欧美无乱码久久久免费午夜一区| 久久国产综合精品| 亚洲色在线视频| 亚洲日本欧美日韩高观看| 久久久青草青青国产亚洲免观| 99亚洲视频| 亚洲肉体裸体xxxx137| 黄色成人av网| 国产欧美三级| 国产酒店精品激情| 国产精品videossex久久发布| 欧美国产日本| 美日韩精品免费| 久久久亚洲高清| 欧美在线免费|