• <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)而不息

            Controlling Players and Characters(16)

             

            Creating a Derived Script Class

            I’m going to assume that you are comfortable working with action templates and
            scripts at this point. The following action template provides an example of using a
            derived script class:

            “End”
            “If flag ~ equals ~ then”
              INT 0 255
              BOOL
            “Else”
            “EndIf”
            “Set flag ~ to ~”
              INT 0 255
              BOOL
            “Print ~”
            TEXT

            Now, using the preceding action template, include the following
            script (I list it in text form here to make it easier to understand):

            If flag 0 equals TRUE then
              Print “Flag is TRUE”
              Set flag 0 to FALSE
            Else
              Print “Flag is FALSE”
              Set flag 0 to TRUE
            EndIf

            A brief reading shows that the preceding script displays the message “Flag is FALSE”
            first (because all script flags are reset to FALSE when initialized); when executed
            again, the script displays “Flag is TRUE”.

            CAUTION
            Remember that the example script shown here is in text form, but when used
            as a Mad Lib Script, the format is based on values. For example, the if...then
            action is represented by the value 1, whereas the EndIf action uses the value 3.

             

            The Derived Class
             

            The next step to processing the script is to derive a class from cScript:

            class cGameScript : public cScript
            {
            private:
              BOOL m_Flags[256]; // The internal flags

              // The script function prototypes
              sScript *Script_End(sScript*);
              sScript *Script_IfFlagThen(sScript*);
              sScript *Script_Else(sScript*);

              sScript *Script_EndIf(sScript*);
              sScript *Script_SetFlag(sScript*);
              sScript *Script_Print(sScript*);

              // The overloaded process function
              sScript *Process(sScript *Script);

            public:
              cGameScript();
            };

            The derived class shown here (cGameScript) uses an array of BOOL values that represents
            the internal flags the scripts can use. Following the single variable declaration
            is a list of function prototypes.


            The script function prototypes are the bread and butter of the script processor.
            Each script action has an associated function that is called during the Process function.
            The Process function is overridden to call upon those script functions, as you
            soon see in this section.

            Aside from those private function calls, there is the constructor, which clears the
            m_Flags array to all FALSE values.

            cGameScript::cGameScript()
            {
              // Clear all internal flags to FALSE
              for(short i=0;i<256;i++)
                m_Flags[i] = FALSE;
            }

            Jumping back a bit, take a look at the overridden Process function. As you can see
            from the following code, cGameScript::Process takes only the current script action
            type and jumps to the appropriate function. Upon the return of each action function,
            a pointer to the next script action is returned. If a value of NULL is returned,
            script execution halts.

            sScript *cGameScript::Process(sScript *Script)
            {
              // Jump to function based on action type
              switch(Script->Type) {
                case 0: return Script_End(Script);
                case 1: return Script_IfFlagThen(Script);
                case 2: return Script_Else(Script);
                case 3: return Script_EndIf(Script);
                case 4: return Script_SetFlag(Script);
                case 5: return Script_Print(Script);
              }

              return NULL; // Error executing
            }

            Now that you’ve overridden the Process function (and filled in the switch statement
            with the action’s function calls), you can continue by programming all of the actions’
            functions, as follows:

            sScript *cGameScript::Script_End(sScript *Script)
            {
              return NULL; // Force script to stop processing
            }

            sScript *cGameScript::Script_IfFlagThen(sScript *Script)
            {
              BOOL Skipping; // Flag for if...then condition

              // See if a flag matches second entry
              if(m_Flags[Script->Entries[0].lValue % 256] == Script->Entries[1].bValue)
                Skipping = FALSE; // Don’t skip following actions
              else
                Skipping = TRUE; // Skip following actions

              // At this point, Skipping states if the script actions
              // need to be skipped due to a conditional if..then statement.
              // Actions are further processed if skipped = FALSE, looking
              // for an else to flip the skip mode, or an endif to end
              // the conditional block.

              Script = Script->Next; // Go to next action to process

              while(Script != NULL) {
                // if else, flip skip mode
                if(Script->Type == 2)
                  Skipping = (Skipping == TRUE) ? FALSE : TRUE;

                // break on end if
                if(Script->Type == 3)
                  return Script->Next;

                // Process script function in conditional block
                // making sure to skip actions when condition not met.
                if(Skipping == TRUE)
                  Script = Script->Next;
                else {
                  if((Script = Process(Script)) == NULL)
                  return NULL;
                }
              }

              return NULL; // End of script reached
            }

            sScript *cGameScript::Script_Else(sScript *Script)
            {
              return Script->Next; // Go to next script action
            }

            sScript *cGameScript::Script_EndIf(sScript *Script)
            {
              return Script->Next; // Go to next script action
            }

            sScript *cGameScript::Script_SetFlag(sScript *Script)
            {
              // Set boolean value
              m_Flags[Script->Entries[0].lValue % 256] = Script->Entries[1].bValue;

              return Script->Next; // Go to next script action
            }

            sScript *cGameScript::Script_Print(sScript *Script)
            {
              // Display some text in a message box
              MessageBox(NULL, Script->Entries[0].Text, “Text”, MB_OK);

              return Script->Next; // Go to next script action
            }

             

            Using the Derived Class


            To test the cGameScript class, instance it and run the example script that I showed
            you earlier in the section “Creating a Derived Script Class.” Assuming that you
            saved that script to a file named test.mls, the following example shows the script
            class functionality:

            cGameScript Script;

            Script.Execute(“test.mls”); // Prints a Flag is FALSE message

            // At this point, the script’s internal flags are maintained,
            // so the next call would take the new flag states into account.
            Script.Execute(“test.mls”); // Prints a Flag is TRUE message

            Although this is a quick and dirty example of the derived cGameScript class, there really
            isn’t much difference between this class and a full-fledged script parser that uses a huge
            action template. You merely need to add each action-processing function into the class
            and call that function via the Parse function.


            posted on 2007-11-14 20:24 lovedday 閱讀(221) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            公告

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

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

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

            搜索

            最新評(píng)論

            97久久国产亚洲精品超碰热| 久久国产色AV免费观看| 久久激情五月丁香伊人| 久久精品一区二区三区中文字幕| 国产精久久一区二区三区| 亚洲精品视频久久久| 久久亚洲精品无码AV红樱桃| 99久久精品国产一区二区| 欧美一级久久久久久久大片| 久久久久久久97| 精品水蜜桃久久久久久久| 亚洲精品美女久久久久99| 久久成人18免费网站| 亚洲中文字幕无码久久精品1| 婷婷久久综合九色综合98| 久久精品综合网| 国产高潮久久免费观看| AV狠狠色丁香婷婷综合久久 | 狠狠色丁香久久综合五月| 久久久WWW免费人成精品| 国产一久久香蕉国产线看观看| 色综合久久中文字幕综合网| 四虎国产精品免费久久久| 日韩av无码久久精品免费| 久久99热这里只频精品6| 品成人欧美大片久久国产欧美...| 性欧美丰满熟妇XXXX性久久久| 亚洲а∨天堂久久精品| 久久精品国产99国产精品| 久久久91精品国产一区二区三区| 久久精品国产亚洲av麻豆蜜芽| 久久国产综合精品五月天| 国产成人综合久久精品尤物| 久久99国产精品二区不卡| 人妻少妇久久中文字幕一区二区 | 久久中文字幕人妻丝袜| 理论片午午伦夜理片久久 | 亚洲精品第一综合99久久| 日批日出水久久亚洲精品tv| 日韩欧美亚洲综合久久影院Ds| 久久精品18|