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

            天行健 君子當自強而不息

            游戲腳本的實現(6)

             

            本篇是游戲腳本的實現(5)的續篇。

             

            事實上,創建可接受腳本的游戲引擎對于大多數的游戲而言,將產生出一個非常開放的源代碼以及高效率的項目。


             

            Mad Lib Scripts的執行

            窗口設計:

            resouce.h:

            //{{NO_DEPENDENCIES}}
            // Microsoft Developer Studio generated include file.
            // Used by MlsDemo.rc
            //
            #define IDD_DEMO                        101
            #define IDC_LOAD                        1000
            #define IDC_EXECUTE                     1001
            #define IDC_SCRIPT                      1002
            #define IDC_TITLE                       1003

            // Next default values for new objects
            // 
            #ifdef APSTUDIO_INVOKED
            #ifndef APSTUDIO_READONLY_SYMBOLS
            #define _APS_NEXT_RESOURCE_VALUE        102
            #define _APS_NEXT_COMMAND_VALUE         40001
            #define _APS_NEXT_CONTROL_VALUE         1004
            #define _APS_NEXT_SYMED_VALUE           101
            #endif
            #endif

            MlsDemo.rc:

             
            // Microsoft Visual C++ generated resource script.
            //
            #include "resource.h"

            #define APSTUDIO_READONLY_SYMBOLS
            /////////////////////////////////////////////////////////////////////////////
            //
            // Generated from the TEXTINCLUDE 2 resource.
            //
            #include "afxres.h"

            /////////////////////////////////////////////////////////////////////////////
            #undef APSTUDIO_READONLY_SYMBOLS

            /////////////////////////////////////////////////////////////////////////////
            // English (U.S.) resources

            #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
            #ifdef _WIN32
            LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
            #pragma code_page(1252)
            #endif //_WIN32

            /////////////////////////////////////////////////////////////////////////////
            //
            // Dialog
            //

            IDD_DEMO DIALOGEX 0, 0, 356, 198
            STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
            CAPTION "MLS Demo"
            CLASS "MLSDEMO"
            FONT 12, "Segoe UI", 400, 0, 0x0
            BEGIN
                PUSHBUTTON      "Load Script",IDC_LOAD,254,173,43,14
                PUSHBUTTON      "Execute",IDC_EXECUTE,306,173,43,14
                LISTBOX         IDC_SCRIPT,7,5,342,162,NOT LBS_NOTIFY | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
                CONTROL         "",IDC_TITLE,"Static",SS_LEFTNOWORDWRAP,7,175,232,14
            END


            /////////////////////////////////////////////////////////////////////////////
            //
            // DESIGNINFO
            //

            #ifdef APSTUDIO_INVOKED
            GUIDELINES DESIGNINFO 
            BEGIN
                IDD_DEMO, DIALOG
                BEGIN
                    LEFTMARGIN, 7
                    RIGHTMARGIN, 349
                    TOPMARGIN, 7
                    BOTTOMMARGIN, 191
                END
            END
            #endif    // APSTUDIO_INVOKED


            #ifdef APSTUDIO_INVOKED
            /////////////////////////////////////////////////////////////////////////////
            //
            // TEXTINCLUDE
            //

            1 TEXTINCLUDE 
            BEGIN
                "resource.h\0"
            END

            2 TEXTINCLUDE 
            BEGIN
                "#include ""afxres.h""\r\n"
                "\0"
            END

            3 TEXTINCLUDE 
            BEGIN
                "\r\n"
                "\0"
            END

            #endif    // APSTUDIO_INVOKED

            #endif    // English (U.S.) resources
            /////////////////////////////////////////////////////////////////////////////



            #ifndef APSTUDIO_INVOKED
            /////////////////////////////////////////////////////////////////////////////
            //
            // Generated from the TEXTINCLUDE 3 resource.
            //


            /////////////////////////////////////////////////////////////////////////////
            #endif    // not APSTUDIO_INVOKED

            實現:

             
            /*************************************************************************
            PURPOSE:
                Mad Lib Scripting demo.
            *************************************************************************/


            #include <windows.h>
            #include <stdio.h>
            #include <memory.h>
            #include "resource.h"

            #pragma warning(disable : 4996)

            enum ENTRY_TYPE { ENTRY_NONE = 0, ENTRY_TEXT, ENTRY_BOOL, ENTRY_INT, ENTRY_FLOAT, ENTRY_CHOICE };

            //============================================================================
            // structure that store all entries fact information.
            //============================================================================
            typedef struct ENTRY
            {
                
            long    type;               // type of blank entry (ENTRY_TEXT, ENTRY_BOOL, )

                union
                {
                    
            long    io_value;       // used for saving/loading
                    long    length;         // length of text (0 terminator)
                    long    selection;      // selection in choice
                    BOOL    bool_value;     // BOOL value
                    long    long_value;     // long balue
                    float   float_value;    // float value
                };

                
            char*   text;               // entry text buffer

                ENTRY()
                {
                    memset(
            this, 0, sizeof(*this));
                }

                ~ENTRY()
                {
                    delete[] text;
                }
            } *ENTRY_PTR;

            //============================================================================
            // structure that store all 
            //============================================================================
            typedef struct SCRIPT
            {
                
            long        action_index;   // [0, number of actions - 1]

                
            long        num_entries;    // number of entries in this action
                ENTRY_PTR   entries;        // array of entries

                SCRIPT*     prev;           
            // previous in linked list
                SCRIPT*     next;           // next in linked list

                SCRIPT()
                {
                    memset(
            this, 0, sizeof(*this));
                }

                ~SCRIPT()
                {
                    delete[] entries;
                    delete next;
                }
            } *SCRIPT_PTR;

            ///////////////////////////////////// function declaration /////////////////////////////////////

            SCRIPT_PTR script_if_flag_then(SCRIPT_PTR script);
            SCRIPT_PTR script_else(SCRIPT_PTR script);
            SCRIPT_PTR script_endif(SCRIPT_PTR script);
            SCRIPT_PTR script_set_flag(SCRIPT_PTR script);
            SCRIPT_PTR script_print(SCRIPT_PTR script);
            SCRIPT_PTR script_move(SCRIPT_PTR script);
            SCRIPT_PTR script_gain_loss(SCRIPT_PTR script);
            SCRIPT_PTR script_battle(SCRIPT_PTR script);
            SCRIPT_PTR script_end(SCRIPT_PTR script);

            LRESULT CALLBACK window_proc(HWND hwnd, UINT msg_id, WPARAM word_param, LPARAM long_param);
            SCRIPT_PTR load_script_from_file(
            const char* filename);
            BOOL run_script();

            void reset_listbox(HWND listbox);
            LRESULT add_string_to_listbox(HWND listbox, 
            const charstring);

            ///////////////////////////////////// global variables /////////////////////////////////////

            HWND g_hwnd;

            SCRIPT_PTR      g_root_script;

            BOOL            g_flags[256];

            OPENFILENAME    g_ofn;
            char            g_script_file[MAX_PATH];

            typedef SCRIPT_PTR (*SCRIPT_FUNC)(SCRIPT_PTR script);

            SCRIPT_FUNC g_script_list[] =
            {
                 script_if_flag_then,
                 script_else,
                 script_endif,
                 script_set_flag,
                 script_print,
                 script_move,
                 script_gain_loss,
                 script_battle,
                 script_end,
            };

            //-----------------------------------------------------------------------------------
            // Routine entry.
            //-----------------------------------------------------------------------------------
            int WINAPI WinMain(HINSTANCE inst, HINSTANCE, LPSTR cmd_line, int cmd_show)
            {
                
            const char* class_name = "MLSDEMO";

                WNDCLASS win_class;

                
            // create window class and register it    
                win_class.style         = CS_HREDRAW | CS_VREDRAW;
                win_class.lpfnWndProc   = window_proc;
                win_class.cbClsExtra    = 0;
                win_class.cbWndExtra    = DLGWINDOWEXTRA;
                win_class.hInstance     = inst;
                win_class.hIcon         = LoadIcon(inst, IDI_APPLICATION);
                win_class.hCursor       = LoadCursor(NULL, IDC_ARROW);
                win_class.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
                win_class.lpszMenuName  = NULL;
                win_class.lpszClassName = class_name;    

                
            if(! RegisterClass(&win_class))
                    
            return FALSE;
               
                
            // The CreateDialog macro creates a modeless dialog box from a dialog box template resource. 
                // The CreateDialog macro uses the CreateDialogParam function.
                //
                // HWND CreateDialog(          
                //    HINSTANCE hInstance,
                //    LPCTSTR lpTemplate,
                //    HWND hWndParent,
                //    DLGPROC lpDialogFunc);
                //
                // hInstance:
                //        [in] Handle to the module whose executable file contains the dialog box template. 
                //
                // lpTemplate
                //        [in] Specifies the dialog box template. This parameter is either the pointer to a null-terminated 
                //        character string that specifies the name of the dialog box template or an integer value that 
                //        specifies the resource identifier of the dialog box template. If the parameter specifies a resource 
                //        identifier, its high-order word must be zero and its low-order word must contain the identifier. 
                //        You can use the MAKEINTRESOURCE macro to create this value. 
                //
                // hWndParent:
                //        [in] Handle to the window that owns the dialog box. 
                //
                // lpDialogFunc:
                //        [in] Pointer to the dialog box procedure. For more information about the dialog box procedure, 
                //        see DialogProc. 
                //
                // Return Value:
                //    If the function succeeds, the return value is the handle to the dialog box.
                //    If the function fails, the return value is NULL. To get extended error information, call GetLastError.

                // Create the dialog box window and show it

                g_hwnd = CreateDialog(inst, MAKEINTRESOURCE(IDD_DEMO), 0, NULL);

                ShowWindow(g_hwnd, cmd_show);
                UpdateWindow(g_hwnd);

                MSG msg;

                
            // message loop
                while(GetMessage(&msg, NULL, 0, 0))
                {
                    TranslateMessage(&msg);
                    DispatchMessage(&msg);
                }

                delete g_root_script;

                UnregisterClass(class_name, inst);

                
            return 0;
            }

            //------------------------------------------------------------------------------------------------
            // Main window procedure.
            //------------------------------------------------------------------------------------------------
            LRESULT CALLBACK window_proc(HWND hwnd, UINT msg_id, WPARAM word_param, LPARAM long_param)
            {
                
            switch(msg_id)
                {
                
            case WM_COMMAND:
                    
            switch(LOWORD(word_param))
                    {
                    
            case IDC_LOAD:  // load a script file
                        if(! GetOpenFileName(&g_ofn))
                            
            break;

                        
            // delete the current script
                        delete g_root_script;

                        
            if((g_root_script = load_script_from_file(g_script_file)) == NULL)
                            MessageBox(hwnd, g_script_file, "Unalbe to open file.", MB_OK);

                        
            // display script filename
                        SetWindowText(GetDlgItem(g_hwnd, IDC_TITLE), g_script_file);

                        
            break;

                    
            case IDC_EXECUTE:   // run a script file
                        run_script();
                        
            break;
                    }

                    
            break;

                
            case WM_CREATE:
                    
            // initialize the save/load dialog box information
                    ZeroMemory(&g_ofn, sizeof(OPENFILENAME));

                    g_ofn.lStructSize   = 
            sizeof(OPENFILENAME);
                    g_ofn.nMaxFile      = MAX_PATH;        
                    g_ofn.Flags         = OFN_HIDEREADONLY;
                    g_ofn.lpstrFile     = g_script_file;
                    g_ofn.lpstrTitle    = "Load Script File";
                    g_ofn.lpstrFilter   = "MLS Script Files (*.mls)\0*.mls\0All Files (*.*)\0*.*\0\0";
                    g_ofn.lpstrDefExt   = "mls";
                    g_ofn.nMaxFileTitle = MAX_PATH;

                    
            // set default open path
                    strcpy(g_script_file, "..\\data\\test.mls");

                    reset_listbox(GetDlgItem(g_hwnd, IDC_SCRIPT));

                    
            break;

                
            case WM_DESTROY:
                    PostQuitMessage(0);
                    
            break;

                
            default:
                    
            return DefWindowProc(hwnd, msg_id, word_param, long_param);
                }

                
            return 0;
            }

            //----------------------------------------------------------------------------------------
            // Load scripts from file and return root script.
            //----------------------------------------------------------------------------------------
            SCRIPT_PTR load_script_from_file(const char* filename)
            {
                FILE* fp;

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

                
            long num_script;
                fread(&num_script, 1, 
            sizeof(long), fp);

                SCRIPT_PTR root_script;
                SCRIPT_PTR script_ptr = NULL;

                
            // loop through each script
                for(long i = 0; i < num_script; i++)
                {
                    
            // allocate a script structure and link in

                    SCRIPT_PTR script = 
            new SCRIPT;
                    script->next = NULL;

                    
            if(script_ptr == NULL)
                        root_script = script;
                    
            else
                        script_ptr->next = script;

                    script_ptr = script;

                    fread(&script->action_index, 1, 
            sizeof(long), fp);
                    fread(&script->num_entries, 1, 
            sizeof(long), fp);

                    
            // get entry data (if any)
                    if(script->num_entries)
                    {
                        script->entries = 
            new ENTRY[script->num_entries];

                        
            // load in each entry
                        for(long j = 0; j < script->num_entries; j++)
                        {
                            fread(&script->entries[j].type, 1, 
            sizeof(long), fp);
                            fread(&script->entries[j].io_value, 1, 
            sizeof(long), fp);

                            
            // get text if any
                            if(script->entries[j].type == ENTRY_TEXT && script->entries[j].length)
                            {
                                script->entries[j].text = 
            new char[script->entries[j].length];
                                fread(script->entries[j].text, 1, script->entries[j].length, fp);
                            }
                        }
                    }
                }

                fclose(fp);

                
            return root_script;
            }

            //----------------------------------------------------------------------------------------
            // Execute all scripts.
            //----------------------------------------------------------------------------------------
            BOOL run_script()
            {
                
            // clear flags
                for(short i = 0; i < 256; i++)
                    g_flags[i] = FALSE;

                SCRIPT_PTR script_ptr;

                
            // start at beginning of script
                if((script_ptr = g_root_script) == NULL)
                    
            return FALSE;

                reset_listbox(GetDlgItem(g_hwnd, IDC_SCRIPT));

                
            // loop until no more scripts
                while(script_ptr)
                {
                    
            // Call script function and break on NULL return value,
                    // any other return type is the pointer to the next function.
                    script_ptr = g_script_list[script_ptr->action_index](script_ptr);
                }

                
            return TRUE;
            }

            //----------------------------------------------------------------------------------------
            // Handle 'if then' script statement.
            //----------------------------------------------------------------------------------------
            SCRIPT_PTR script_if_flag_then(SCRIPT_PTR script)
            {
                BOOL skipping;

                
            long flag_index = script->entries[0].long_value % 256;

                
            // see if a flag matches second entry
                if(g_flags[flag_index] == script->entries[1].bool_value)
                    skipping = FALSE;
                
            else
                    skipping = TRUE;

                script = script->next;

                
            while(script)
                {
                    
            // if 'else', flip skip mode
                    if(script->action_index == 1)
                        skipping = !skipping;

                    
            // break on 'end if'
                    if(script->action_index == 2)
                        
            return script->next;

                    
            // Process script function in conditional block, 
                    // making sure to skip actions when condition not met.
                    if(skipping)
                        script = script->next;
                    
            else
                    {
                        
            if((script = g_script_list[script->action_index](script)) == NULL)
                            
            break;
                    }
                }

                
            return NULL;
            }

            //----------------------------------------------------------------------------------------
            // Handle 'else' script statement.
            //----------------------------------------------------------------------------------------
            SCRIPT_PTR script_else(SCRIPT_PTR script)
            {
                
            return script->next;
            }

            //----------------------------------------------------------------------------------------
            // Handle 'endif' script statement.
            //----------------------------------------------------------------------------------------
            SCRIPT_PTR script_endif(SCRIPT_PTR script)
            {
                
            return script->next;
            }

            //----------------------------------------------------------------------------------------
            // Handle 'set flag' script statement.
            //----------------------------------------------------------------------------------------
            SCRIPT_PTR script_set_flag(SCRIPT_PTR script)
            {
                g_flags[script->entries[0].long_value % 256] = script->entries[1].bool_value;

                
            return script->next;
            }

            //----------------------------------------------------------------------------------------
            // Handle 'print' script statement.
            //----------------------------------------------------------------------------------------
            SCRIPT_PTR script_print(SCRIPT_PTR script)
            {
                HWND listbox = GetDlgItem(g_hwnd, IDC_SCRIPT);

                add_string_to_listbox(listbox, "Print string:");
                add_string_to_listbox(listbox, script->entries[0].text);
                add_string_to_listbox(listbox, "");

                
            return script->next;
            }

            //----------------------------------------------------------------------------------------
            // Handle 'Move character' script statement.
            //----------------------------------------------------------------------------------------
            SCRIPT_PTR script_move(SCRIPT_PTR script)
            {
                
            char text[256];

                HWND listbox = GetDlgItem(g_hwnd, IDC_SCRIPT);

                add_string_to_listbox(listbox, "Moving character to:");

                sprintf(text, "%lf, %lf, %lf", 
                        script->entries[0].float_value, 
                        script->entries[1].float_value, 
                        script->entries[2].float_value);

                add_string_to_listbox(listbox, text);
                add_string_to_listbox(listbox, "");

                
            return script->next;
            }

            //----------------------------------------------------------------------------------------
            // Handle 'gain loss' script statement.
            //----------------------------------------------------------------------------------------
            SCRIPT_PTR script_gain_loss(SCRIPT_PTR script)
            {
                
            char options[7][64] = 
                {
                    { "Main character" }, 
                    { "Caster"         },
                    { "Target"         },
                    { "Gains"          },
                    { "Looses"         },
                    { "Hit"            },
                    { "Magic"          }
                };

                
            char text[1024];

                sprintf(text, "%s %s %lu %s points",
                        options[script->entries[0].selection],
                        options[script->entries[1].selection + 3],
                        script->entries[2].long_value,
                        options[script->entries[3].selection + 5]);

                HWND listbox = GetDlgItem(g_hwnd, IDC_SCRIPT);

                add_string_to_listbox(listbox, text);
                add_string_to_listbox(listbox, "");

                
            return script->next;
            }

            //----------------------------------------------------------------------------------------
            // Handle 'engaging in battle' script statement.
            //----------------------------------------------------------------------------------------
            SCRIPT_PTR script_battle(SCRIPT_PTR script)
            {
                
            char text[256];

                sprintf(text, "Engaging in battle #%lu", script->entries[0].long_value);

                HWND listbox = GetDlgItem(g_hwnd, IDC_SCRIPT);

                add_string_to_listbox(listbox, text);
                add_string_to_listbox(listbox, "");

                
            return script->next;
            }

            //----------------------------------------------------------------------------------------
            // Handle for script end.
            //----------------------------------------------------------------------------------------
            SCRIPT_PTR script_end(SCRIPT_PTR script)
            {  
                HWND listbox = GetDlgItem(g_hwnd, IDC_SCRIPT);

                add_string_to_listbox(listbox, "End of Script");
                add_string_to_listbox(listbox, "");

                
            return NULL;
            }

            //-----------------------------------------------------------------------------------
            // Remove all items from list box.
            //-----------------------------------------------------------------------------------
            void reset_listbox(HWND listbox)
            {
                
            // An application sends an LB_RESETCONTENT message to remove all items from a list box. 
                //
                // To send this message, call the SendMessage function as follows. 
                //
                // lResult = SendMessage(       // returns LRESULT in lResult     
                //      (HWND) hWndControl,     // handle to destination control     
                //      (UINT) LB_RESETCONTENT, // message ID     
                //      (WPARAM) wParam,        // = (WPARAM) () wParam;    
                //      (LPARAM) lParam         // = (LPARAM) () lParam; );   
                //
                // wParam:
                //      Not used; must be zero. 
                //
                // lParam:
                //      Not used; must be zero. 
                //
                // This message does not return a value. 

                SendMessage(listbox, LB_RESETCONTENT, 0, 0);
            }

            //-----------------------------------------------------------------------------------
            // Add string to listbox.
            //-----------------------------------------------------------------------------------
            LRESULT add_string_to_listbox(HWND listbox, const charstring)
            {
                
            // An application sends an LB_ADDSTRING message to add a string to a list box. If the list box does not have 
                // the LBS_SORT style, the string is added to the end of the list. Otherwise, the string is inserted into 
                // the list and the list is sorted. 
                //
                // To send this message, call the SendMessage function as follows. 
                //
                // lResult = SendMessage(       // returns LRESULT in lResult     
                //      (HWND) hWndControl,     // handle to destination control     
                //      (UINT) LB_ADDSTRING,    // message ID     
                //      (WPARAM) wParam,        // = (WPARAM) () wParam;    
                //      (LPARAM) lParam         // = (LPARAM) () lParam; 
                //  );       
                //
                // wParam:
                //      This parameter is not used. 
                //
                // lParam:
                //      Pointer to the null-terminated string that is to be added. 
                //
                //      If you create the list box with an owner-drawn style but without the LBS_HASSTRINGS style, 
                //      this parameter is stored as item data instead of the string to which it would otherwise point. 
                //      You can send the LB_GETITEMDATA and LB_SETITEMDATA messages to retrieve or modify the item data.
                //
                // Return Value:    
                //      The return value is the zero-based index of the string in the list box. If an error occurs, 
                //      the return value is LB_ERR. If there is insufficient space to store the new string, the return value 
                //      is LB_ERRSPACE. 

                
            return SendMessage(listbox, LB_ADDSTRING, 0, (LPARAM)string);
            }

            截圖:

             

            下載源碼和工程

             

            posted on 2007-11-04 01:29 lovedday 閱讀(630) 評論(0)  編輯 收藏 引用

            公告

            導航

            統計

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關鏈接

            搜索

            最新評論

            久久线看观看精品香蕉国产| 四虎国产精品免费久久久| 秋霞久久国产精品电影院| 亚洲va久久久久| 久久国产一区二区| 91精品国产91久久久久久青草 | 亚洲va久久久噜噜噜久久狠狠| 99蜜桃臀久久久欧美精品网站| 欧美亚洲色综久久精品国产| 久久综合久久综合九色| 久久久高清免费视频| 国产精品久久久久久影院| 亚洲精品久久久www| 亚洲精品乱码久久久久久蜜桃图片 | 久久伊人精品青青草原高清| 精品久久久无码中文字幕| 欧美日韩精品久久久免费观看| 99久久综合狠狠综合久久止| 亚洲精品久久久www| 国产成人久久精品二区三区| 亚洲香蕉网久久综合影视| 国内精品久久久久久久亚洲| 精品国产一区二区三区久久久狼 | 色综合合久久天天给综看| 国产情侣久久久久aⅴ免费| 综合久久精品色| 国产日韩欧美久久| 91久久精品91久久性色| 久久人妻AV中文字幕| 久久久无码精品午夜| 国产成人AV综合久久| 久久福利青草精品资源站免费| 偷偷做久久久久网站| 伊人色综合久久天天人守人婷| 国产99久久久久久免费看| 久久综合久久综合九色| 国产精品天天影视久久综合网| 色综合久久久久无码专区| 亚洲精品乱码久久久久66| 国产激情久久久久久熟女老人| 久久久高清免费视频|