• <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>
            隨筆 - 505  文章 - 1034  trackbacks - 0
            <2007年12月>
            2526272829301
            2345678
            9101112131415
            16171819202122
            23242526272829
            303112345


            子曾經曰過:編程無他,唯手熟爾!

            常用鏈接

            留言簿(94)

            隨筆分類(649)

            隨筆檔案(505)

            相冊

            BCB

            Crytek

            • crymod
            • Crytek's Offical Modding Portal

            Game Industry

            OGRE

            other

            Programmers

            Qt

            WOW Stuff

            搜索

            •  

            積分與排名

            • 積分 - 911346
            • 排名 - 14

            最新隨筆

            最新評論

            閱讀排行榜

            評論排行榜

            http://blog.csdn.net/tcxxs/category/148474.aspx


            1、這是我分析WOW原始UI代碼后,對一些比較關鍵的部分,記錄下來的
            2、文章里面如果有什么紕漏,希望大家毫不客氣的提出來,我一定查究!
            3、關于基礎問題可以參考
               WOW UI
            《UI制作入門》http://www.pcgames.com.cn/netgames/zhuanti/wow/expert/Ui.htm
            《WOW UI定制入門》http://202.113.13.169/site/mybbs/read.php?tid=33
            《WOW插件制作指南》http://www.cnblogs.com/bluefee/archive/2005/04/14/137217.html
            《ADDONS編寫普及》http://wowbbs.game.mop.com/viewthread.php?tid=216755&extra=page%3D1
            《動手寫個屬于自己的UI》http://wowbbs.game.mop.com/viewthread.php?tid=149814&fpage=1&highlight=
               XML
            《XML初學進階》http://www.chinausd.com/code/code.asp?id=173/5058
            《XMLSpy 2005 Enterprise Edition》http://www.altova.com/download_spy_enterprise.html
               Lua
            《Lua5.0參考手冊中文版》http://www.cnblogs.com/bluefee/archive/2005/04/15/138576.html
            《Lua 程序設計初步》http://bbs.battlecn.net/read.php?tid=541871&fpage=1
            《通過例子學習Lua》http://www.wowtc.com/bbs/read.php?tid=4999&fpage=2
            《Programming in LUA中文版》http://www.wowtc.com/bbs/read.php?tid=4998&fpage=2
            《LuaEdit v2.5》http://luaforge.net/projects/luaedit/
            4、關于如何提取MPQ文件,如何查看BLP圖像,可以參考
            《WoW Working Link》http://www.fukt.bth.se/%7Ek/wow/stuff/howto-extract-interface-files.txt
            《Win MPQ》http://wow.duowan.com/2005-05-16/007R/26857843.html
            《Win BLP Viewer》http://gamedown.yesky.com/game/108/108805.html
            5、關于查詢資料可以參考
            《WoW Wiki》http://www.wowwiki.com/Interface_Customization/
            《WOW APIs》http://www.cnblogs.com/bluefee/archive/2005/04/12/136270.html
            《UI&Macro Forum》http://forums.worldofwarcraft.com/board.aspx?fn=wow-interface-customization
            6、如果該問題是可以類推,或是從上下文能馬上理解,或是從字面就知道含義的我就不羅嗦了
            7、對于相同的問題我一般只分析一次,或是簡要的提示一下,具體內容可以參考我以前的分析
            8、如果你對自己查找資料的能力感到抱歉,可以E-mail向我詢問,我會努力幫助你
            9、聯系方式E-mail: asdic.xxs@gmail.com    Blog: blog.csdn.net/tcxxs     QQ: 35548917
            10、做人要厚道,轉載請注明出處!


            --------------------------------------------------


            正式開始:
            1、版本:1.7.1 (4659)
            2、這次我寫的是ActionbuttonTemplate.xml,ActionBarFrame.xml和ActionButton.lua
               他們是動作按鈕的基礎UI,也是大家比較關心的一部分,在Interface/FrameXML里面
            3、這次分析用到的名詞解釋:
            【模板】學過C++語言的人都知道虛函數,實際上是一個道理,只是作為子代繼承的規范,不可創建實例
            【柵格】一個用來放置圖標的格子,默認為無圖標時隱藏,當然你也可以顯示它
            【額外柵格】包括了戰士姿態,德魯依外形,盜賊潛行的柵格
            【柵格ID】每個柵格都有對應的ID,是該柵格的唯一標示
            【圖標】每個技能和物品,包括交易技能,食物,宏等都有一個可以拖動的圖標
            【動作鍵】當把圖標放置到柵格上時,這個整體就叫動作鍵
            【額外動作鍵】當把圖標放置到額外柵格上時,這個整體就叫額外動作鍵
            【動作條】一般12個柵格組成一排或者一列,稱這個為動作條
            【額外動作條】由12個額外柵格組成一排或者一列,稱這個為額外動作條
            【動作條ID】在默認動作條中每個動作條都有頁碼,是這個動作條的唯一標示
              這里解釋一下各個動作條的位置,主動作條包括1,2頁
              然后右邊1,右邊2,右下,左下依次為3到6頁,柵格ID排列如圖
              61-72(左下)49-60(右下)37    25
                    (右邊2) I     I (右邊1)
              1-12(主AB)13-24(2頁)  48    36
              這里注意一個問題,為什么有的UI可以實現96個(FB,DUF等)或者更多呢
              這是因為額外柵格的存在,這些UI把空閑的額外柵格加以利用罷了
              調用這些額外柵格的動作鍵應該用其對應的函數
            【閃動】當執行自動攻擊或者自動射擊技能時,改動作鍵就處于閃動狀態
            【CD】CoolDown的簡寫
            【信息提示】即GameTooltip,當鼠標指向某個東西時顯示的提示信息
            【光環】包括buff,debuff,物品附加屬性等
            【arg1..N】arg為事件觸發是傳入的參數,可以為0到多個


            --------------------------------------------

            源代碼及注釋

            -----------------------ActionButtonTemplate.xml


            <Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
            ..\FrameXML\UI.xsd">
            <CheckButton name="ActionButtonTemplate" virtual="true">
            【動作鍵】【模板】
              <Size>
               <AbsDimension x="36" y="36"/>
              </Size>
              <Layers>
               <Layer level="BACKGROUND">
                <Texture name="$parentIcon"/>
                背景層放置【圖標】
               </Layer>
               <Layer level="ARTWORK">
               層的從下到上為:BackGround,ArtWork,OverLay
                <Texture name="$parentFlash" file="Interface\Buttons\UI-QuickslotRed" hidden="true"/>
                【閃動】效果的紋理
                <FontString name="$parentHotKey" inherits="NumberFontNormalSmallGray" justifyH="RIGHT">
                該【動作鍵】的快捷鍵信息
                 <Size>
                  <AbsDimension x="32" y="10"/>
                 </Size>
                 <Anchors>
                  <Anchor point="TOPLEFT">
                   <Offset>
                    <AbsDimension x="2" y="-2"/>
                   </Offset>
                  </Anchor>
                 </Anchors>
                </FontString>
                <FontString name="$parentCount" inherits="NumberFontNormal" justifyH="RIGHT">
                該【動作鍵】數量信息
                 <Anchors>
                 注意,這里沒有Size標簽,所以它為自動大小
                  <Anchor point="BOTTOMRIGHT">
                   <Offset>
                    <AbsDimension x="-2" y="2"/>
                   </Offset>
                  </Anchor>
                 </Anchors>
                </FontString>
               </Layer>
               <Layer level="OVERLAY">
                <FontString name="$parentName" inherits="GameFontHighlightSmallOutline">
                該【動作鍵】名字,例如:宏的名字
                 <Size>
                  <AbsDimension x="36" y="10"/>
                 </Size>
                 <Anchors>
                  <Anchor point="BOTTOM">
                   <Offset>
                    <AbsDimension x="0" y="2"/>
                   </Offset>
                  </Anchor>
                 </Anchors>
                </FontString>
               </Layer>
              </Layers>
              <Frames>
               <Model name="$parentCooldown" inherits="CooldownFrameTemplate"/>
               直接應用【CD】模板,沒有測試過,還望高人賜教,或者等我以后試
              </Frames>
              <NormalTexture name="$parentNormalTexture" file="Interface\Buttons\UI-Quickslot2">
              【圖標】邊框紋理,如果該【柵格】已放置【圖標】,則顯示這個紋理
              若沒有放置,則顯示UI-Quickslot,它比UI-Quickslot2稍微小點
               <Size>
                <AbsDimension x="64" y="64"/>
               </Size>
               <Anchors>
                <Anchor point="CENTER">
                 <Offset>
                  <AbsDimension x="0" y="-1"/>
                  立體效果,而且UI-Quickslot的顯示位置也依賴UI-Quickslot2
                  但是【圖標】的實際放置位置卻并不依賴這個位置,由BackGround層決定
                 </Offset>
                </Anchor>
               </Anchors>
              </NormalTexture>
              <PushedTexture file="Interface\Buttons\UI-Quickslot-Depress"/>
              點擊【動作鍵】時的紋理
              <HighlightTexture alphaMode="ADD" file="Interface\Buttons\ButtonHilight-Square"/>
              鼠標經過【柵格】時的紋理
              <CheckedTexture alphaMode="ADD" file="Interface\Buttons\CheckButtonHilight"/>
              等待施法時【柵格】的紋理,例如:你點擊加血法術到選擇目標那段時間顯示
            </CheckButton>
            </Ui>


            ------------------------ActionBarFrame.xml


            <Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
            ..\FrameXML\UI.xsd">
            <Script file="ActionButton.lua"/>
            <CheckButton name="ActionBarButtonTemplate" inherits="ActionButtonTemplate" virtual="true">
              <Scripts>
               <OnLoad>
                ActionButton_OnLoad();
               </OnLoad>
               <OnEvent>
                ActionButton_OnEvent(event);
               </OnEvent>
               <OnClick>
                if ( IsShiftKeyDown() ) then
                安住shift再點【動作鍵】,即拖拉【圖標】
                 PickupAction(ActionButton_GetPagedID(this));
                 鼠標吸附該【圖標】
                else
                否則執行該【動作鍵】命令
                 MacroFrame_EditMacro();
                 UseAction(ActionButton_GetPagedID(this), 1);
                 UseAction(slot [,checkCursor] [,onSelf])函數
                 slot參數為該【動作鍵】ID號
                 checkCursor參數為是否在其他事件中返回是鼠標點擊,0或者1
                 onSelf參數為是否對自己施法,0或者1
                end
                ActionButton_UpdateState();
                點擊后應該更新【動作鍵】狀態
               </OnClick>
               <OnDragStart>
                if ( LOCK_ACTIONBAR ~= "1" ) then
                如果【動作鍵】并未設定為鎖定
                 PickupAction(ActionButton_GetPagedID(this));
                 ActionButton_UpdateState();
                end
               </OnDragStart>
               <OnReceiveDrag>
                if ( LOCK_ACTIONBAR ~= "1" ) then
                 PlaceAction(ActionButton_GetPagedID(this));
                 PlaceAction,放下鼠標上吸附的【動作鍵】
                 注意,這里并不要求一定要放在柵格上,因為你可以摧毀一個【動作鍵】
                 ActionButton_UpdateState();
                end
               </OnReceiveDrag>
               <OnEnter>
                ActionButton_SetTooltip();
                經過【動作鍵】時,顯示【信息提示】
               </OnEnter>
               <OnLeave>
                this.updateTooltip = nil;
                GameTooltip:Hide();
               </OnLeave>
               <OnUpdate>
                ActionButton_OnUpdate(arg1);
                更新【閃動】效果
               </OnUpdate>
              </Scripts>
            </CheckButton>
            下面定義了主【動作條】
            <CheckButton name="ActionButton1" inherits="ActionBarButtonTemplate" parent="MainMenuBarArtFrame" id="1">
            MainMenuBarArtFrame,即默認最下面的一條工具欄,包括了主【動作條】,人物工具條,背包
            但是注意,并不包括兩旁的2只鷹的紋理
              <Anchors>
               <Anchor point="BOTTOMLEFT">
                <Offset>
                 <AbsDimension x="8" y="4"/>
                 左下和右下的【動作條】都依據主【動作條】的位置
                 【信息提示】和【額外柵格】并不依據這個偏移,但是它會根據左下和右下【動作條】的出現而更改高度
                 若僅改變該偏移,則如果該人物有【額外柵格】,則人物的主【動作條】將會在原位又出現一個
                </Offset>
               </Anchor>
              </Anchors>
            </CheckButton>
            <CheckButton name="ActionButton2" inherits="ActionBarButtonTemplate" parent="MainMenuBarArtFrame" id="2">
              <Anchors>
               <Anchor point="LEFT" relativeTo="ActionButton1" relativePoint="RIGHT">
                <Offset>
                 <AbsDimension x="6" y="0"/>
                </Offset>
               </Anchor>
              </Anchors>
            </CheckButton>
            <CheckButton name="ActionButton3" inherits="ActionBarButtonTemplate" parent="MainMenuBarArtFrame" id="3">
              <Anchors>
               <Anchor point="LEFT" relativeTo="ActionButton2" relativePoint="RIGHT">
                <Offset>
                 <AbsDimension x="6" y="0"/>
                </Offset>
               </Anchor>
              </Anchors>
            </CheckButton>
            <CheckButton name="ActionButton4" inherits="ActionBarButtonTemplate" parent="MainMenuBarArtFrame" id="4">
              <Anchors>
               <Anchor point="LEFT" relativeTo="ActionButton3" relativePoint="RIGHT">
                <Offset>
                 <AbsDimension x="6" y="0"/>
                </Offset>
               </Anchor>
              </Anchors>
            </CheckButton>
            <CheckButton name="ActionButton5" inherits="ActionBarButtonTemplate" parent="MainMenuBarArtFrame" id="5">
              <Anchors>
               <Anchor point="LEFT" relativeTo="ActionButton4" relativePoint="RIGHT">
                <Offset>
                 <AbsDimension x="6" y="0"/>
                </Offset>
               </Anchor>
              </Anchors>
            </CheckButton>
            <CheckButton name="ActionButton6" inherits="ActionBarButtonTemplate" parent="MainMenuBarArtFrame" id="6">
              <Anchors>
               <Anchor point="LEFT" relativeTo="ActionButton5" relativePoint="RIGHT">
                <Offset>
                 <AbsDimension x="6" y="0"/>
                </Offset>
               </Anchor>
              </Anchors>
            </CheckButton>
            <CheckButton name="ActionButton7" inherits="ActionBarButtonTemplate" parent="MainMenuBarArtFrame" id="7">
              <Anchors>
               <Anchor point="LEFT" relativeTo="ActionButton6" relativePoint="RIGHT">
                <Offset>
                 <AbsDimension x="6" y="0"/>
                </Offset>
               </Anchor>
              </Anchors>
            </CheckButton>
            <CheckButton name="ActionButton8" inherits="ActionBarButtonTemplate" parent="MainMenuBarArtFrame" id="8">
              <Anchors>
               <Anchor point="LEFT" relativeTo="ActionButton7" relativePoint="RIGHT">
                <Offset>
                 <AbsDimension x="6" y="0"/>
                </Offset>
               </Anchor>
              </Anchors>
            </CheckButton>
            <CheckButton name="ActionButton9" inherits="ActionBarButtonTemplate" parent="MainMenuBarArtFrame" id="9">
              <Anchors>
               <Anchor point="LEFT" relativeTo="ActionButton8" relativePoint="RIGHT">
                <Offset>
                 <AbsDimension x="6" y="0"/>
                </Offset>
               </Anchor>
              </Anchors>
            </CheckButton>
            <CheckButton name="ActionButton10" inherits="ActionBarButtonTemplate" parent="MainMenuBarArtFrame" id="10">
              <Anchors>
               <Anchor point="LEFT" relativeTo="ActionButton9" relativePoint="RIGHT">
                <Offset>
                 <AbsDimension x="6" y="0"/>
                </Offset>
               </Anchor>
              </Anchors>
            </CheckButton>
            <CheckButton name="ActionButton11" inherits="ActionBarButtonTemplate" parent="MainMenuBarArtFrame" id="11">
              <Anchors>
               <Anchor point="LEFT" relativeTo="ActionButton10" relativePoint="RIGHT">
                <Offset>
                 <AbsDimension x="6" y="0"/>
                </Offset>
               </Anchor>
              </Anchors>
            </CheckButton>
            <CheckButton name="ActionButton12" inherits="ActionBarButtonTemplate" parent="MainMenuBarArtFrame" id="12">
              <Anchors>
               <Anchor point="LEFT" relativeTo="ActionButton11" relativePoint="RIGHT">
                <Offset>
                 <AbsDimension x="6" y="0"/>
                </Offset>
               </Anchor>
              </Anchors>
            </CheckButton>
            <Button name="ActionBarUpButton" parent="MainMenuBarArtFrame">
            主【動作條】位置上的上翻頁按鈕
              <Size>
               <AbsDimension x="32" y="32"/>
              </Size>
              <Anchors>
               <Anchor point="CENTER" relativeTo="MainMenuBarArtFrame" relativePoint="TOPLEFT">
                <Offset>
                 <AbsDimension x="522" y="-22"/>
                </Offset>
               </Anchor>
              </Anchors>
              <HitRectInsets>
               <AbsInset left="6" right="6" top="7" bottom="7"/>
               這個一直沒有測試成功,還望高人指點迷津
              </HitRectInsets>
              <Scripts>
               <OnLoad>
                MainMenuBarPageNumber:SetText(CURRENT_ACTIONBAR_PAGE);
                CURRENT_ACTIONBAR_PAGE,當前【動作條ID】
                當你顯示了其他【動作條】如:左下【動作條】,那么它將不會在翻頁中重復出現
                this:RegisterEvent("ACTIONBAR_PAGE_CHANGED");
                當主【動作條】的頁碼改變時觸發
               </OnLoad>
               <OnEvent>
                if ( event == "ACTIONBAR_PAGE_CHANGED" ) then
                 MainMenuBarPageNumber:SetText(CURRENT_ACTIONBAR_PAGE);
                end
               </OnEvent>
               <OnClick>
                ActionBar_PageUp();
                PlaySound("UChatScrollButton");
                PlaySound(SoundName),播放一個WOW內置的聲音
                SoundName為內置參數的名字,可以參考下面地址
                http://www.wowwiki.com/API_PlaySound
                注意,你不要試圖在MPQ文件中找到這個名字
               </OnClick>
              </Scripts>
              <NormalTexture file="Interface\MainMenuBar\UI-MainMenu-ScrollUpButton-Up"/>
              <PushedTexture file="Interface\MainMenuBar\UI-MainMenu-ScrollUpButton-Down"/>
              <DisabledTexture file="Interface\Buttons\UI-ScrollBar-ScrollUpButton-Disabled"/>
              被鎖定時的紋理,未測試成功,望高人指點一二
              <HighlightTexture alphaMode="ADD" file="Interface\MainMenuBar\UI-MainMenu-ScrollUpButton-Highlight"/>
            </Button>
            <Button name="ActionBarDownButton" parent="MainMenuBarArtFrame">
              <Size>
               <AbsDimension x="32" y="32"/>
              </Size>
              <Anchors>
               <Anchor point="CENTER" relativeTo="MainMenuBarArtFrame" relativePoint="TOPLEFT">
                <Offset>
                 <AbsDimension x="522" y="-42"/>
                </Offset>
               </Anchor>
              </Anchors>
              <HitRectInsets>
               <AbsInset left="6" right="6" top="7" bottom="7"/>
              </HitRectInsets>
              <Scripts>
              上翻中已經注冊并處理了事件,這里不重復
               <OnClick>
                ActionBar_PageDown();
                PlaySound("UChatScrollButton");
               </OnClick>
              </Scripts>
              <NormalTexture file="Interface\MainMenuBar\UI-MainMenu-ScrollDownButton-Up"/>
              <PushedTexture file="Interface\MainMenuBar\UI-MainMenu-ScrollDownButton-Down"/>
              <DisabledTexture file="Interface\Buttons\UI-ScrollBar-ScrollDownButton-Disabled"/>
              <HighlightTexture alphaMode="ADD" file="Interface\MainMenuBar\UI-MainMenu-ScrollDownButton-Highlight"/>
            </Button>
            </Ui>


            ------------------------ActionButton.lua

            CURRENT_ACTIONBAR_PAGE = 1;
            當前【動作條ID】
            NUM_ACTIONBAR_PAGES = 6;
            【動作條ID】總數
            NUM_ACTIONBAR_BUTTONS = 12;
            每個【動作條】的【動作鍵】數
            ATTACK_BUTTON_FLASH_TIME = 0.4;
            【閃動】效果時間間隔,為0.4S

            BOTTOMLEFT_ACTIONBAR_PAGE = 6;
            初始左下【動作條ID】
            BOTTOMRIGHT_ACTIONBAR_PAGE = 5;
            初始右下【動作條ID】
            LEFT_ACTIONBAR_PAGE = 4;
            初始右邊2【動作條ID】
            RIGHT_ACTIONBAR_PAGE = 3;
            初始右邊1【動作條ID】

            -- Table of actionbar pages and whether they're viewable or not
            VIEWABLE_ACTION_BAR_PAGES = {1, 1, 1, 1, 1, 1};
            初始化為每頁【動作條】都能夠顯示,0為隱藏

            function ActionButtonDown(id)
            實現按下【動作鍵】
            if ( BonusActionBarFrame:IsVisible() ) then
            如果是【額外動作鍵】
              local button = getglobal("BonusActionButton"..id);
              if ( button:GetButtonState() == "NORMAL" ) then
              若未按下
               button:SetButtonState("PUSHED");
              end
              return;
              該函數用if-else是同樣的
            end

            local button = getglobal("ActionButton"..id);
            if ( button:GetButtonState() == "NORMAL" ) then
              button:SetButtonState("PUSHED");
            end
            end

            由上下2個函數可以看出,暴雪對【動作鍵】和【額外動作鍵】同樣對待
            這個也是其他UI可以利用【額外柵格】的基礎

            function ActionButtonUp(id, onSelf)
            if ( BonusActionBarFrame:IsVisible() ) then
              local button = getglobal("BonusActionButton"..id);
              if ( button:GetButtonState() == "PUSHED" ) then
               button:SetButtonState("NORMAL");
               -- Used to save a macro
               MacroFrame_EditMacro();
               UseAction(ActionButton_GetPagedID(button), 0);
               if ( IsCurrentAction(ActionButton_GetPagedID(button)) ) then
               IsCurrentAction,等待施法,并不是正在吟唱
                button:SetChecked(1);
                設定該【動作鍵】正處于等待狀態
               else
                button:SetChecked(0);
               end
              end
              return;
            end

            local button = getglobal("ActionButton"..id);
            if ( button:GetButtonState() == "PUSHED" ) then
              button:SetButtonState("NORMAL");
              -- Used to save a macro
              MacroFrame_EditMacro();
              UseAction(ActionButton_GetPagedID(button), 0, onSelf);
              if ( IsCurrentAction(ActionButton_GetPagedID(button)) ) then
               button:SetChecked(1);
              else
               button:SetChecked(0);
              end
            end
            end

            function ActionBar_PageUp()
            CURRENT_ACTIONBAR_PAGE = CURRENT_ACTIONBAR_PAGE + 1;
            local nextPage;
            for i=CURRENT_ACTIONBAR_PAGE, NUM_ACTIONBAR_PAGES do
              if ( VIEWABLE_ACTION_BAR_PAGES[i] ) then
              如果該頁能顯示
               nextPage = i;
               break;
              end
            end

            if ( not nextPage ) then
            如果沒有找到能夠顯示的下一頁
              CURRENT_ACTIONBAR_PAGE = 1;
            else
              CURRENT_ACTIONBAR_PAGE = nextPage;
            end
            ChangeActionBarPage();
            這個函數變換將當主【動作條】變換到CURRENT_ACTIONBAR_PAGE指向的【動作條】
            end

            function ActionBar_PageDown()
            CURRENT_ACTIONBAR_PAGE = CURRENT_ACTIONBAR_PAGE - 1;
            local prevPage;
            for i=CURRENT_ACTIONBAR_PAGE, 1, -1 do
              if ( VIEWABLE_ACTION_BAR_PAGES[i] ) then
               prevPage = i;
               break;
              end
            end

            if ( not prevPage ) then
              for i=NUM_ACTIONBAR_PAGES, 1, -1 do
              把“1”換成“CURRENT_ACTIONBAR_PAGE+1”也是可以的
              把這個for循環對比ActionBar_PageUp的同一地方
              可見,暴雪員工相當的肯定在上翻的時候第1頁是可以顯示的
              而在下翻的時候顯得信心不足,還重復檢查了一次NUM_ACTIONBAR_PAGES到CURRENT_ACTIONBAR_PAGE
              這是因為左下、右下AB的出現只是修改5,6頁的可見性,并不影響1頁的可見性
              所以在下翻的時候需要對1到6頁均做可見性檢查
              但是,重復檢查的區間的確是多余的,估計是暴雪員工偷懶
              因為“1”比“CURRENT_ACTIONBAR_PAGE+1”要好寫得多
               if ( VIEWABLE_ACTION_BAR_PAGES[i] ) then
                prevPage = i;
                break;
               end
              end
            end
            CURRENT_ACTIONBAR_PAGE = prevPage;
            ChangeActionBarPage();
            end

            function ActionButton_OnLoad()
            this.showgrid = 0;
            顯示空【柵格】的標志
            this.flashing = 0;
            處于【閃動】的標志
            this.flashtime = 0;
            【閃動】時間間隔計算的中間量
            ActionButton_Update();
            this:RegisterForDrag("LeftButton", "RightButton");
            對this所指向的窗體注冊鼠標拖拉行為,參數至少一個,也可以注冊多個
            參數為LeftButton,RightButton,表示使用某個鼠標鍵執行
            this:RegisterForClicks("LeftButtonUp", "RightButtonUp");
            對this所指向的窗體注冊鼠標點擊行為,參數至少一個,也可以注冊多個
            參數為LeftButtonDown,LeftButtonUp,RightButtonDown,RightButtonUp
            注意,在OnClick標簽中傳入的arg1參數只返回LeftButton或者RightButton
            this:RegisterEvent("PLAYER_ENTERING_WORLD");
            this:RegisterEvent("UPDATE_BONUS_ACTIONBAR");
            當【額外柵格】更新時觸發
            this:RegisterEvent("ACTIONBAR_SHOWGRID");
            當拖拉【圖標】時觸發,arg1為LeftButton或者RightButton
            this:RegisterEvent("ACTIONBAR_HIDEGRID");
            當停止拖拉【圖標】時觸發
            this:RegisterEvent("ACTIONBAR_PAGE_CHANGED");
            this:RegisterEvent("ACTIONBAR_SLOT_CHANGED");
            當【柵格】內容變更時觸發,arg1為變更【柵格ID】
            this:RegisterEvent("ACTIONBAR_UPDATE_STATE");
            當【柵格】狀態更新時觸發,包括了【CD】和可用性鑒定
            但是不包括自動攻擊和自動射擊事件
            arg1為鼠標LeftButton,RightButton,也可能為nil
            this:RegisterEvent("ACTIONBAR_UPDATE_USABLE");
            當更新【圖標】可用性后觸發
            this:RegisterEvent("ACTIONBAR_UPDATE_COOLDOWN");
            當更新【CD】后觸發
            當【CD】開始的時候,arg1返回使用的鼠標按鈕LeftButton或者RightButton
            當【CD】結束的時候,arg1返回nil
            this:RegisterEvent("UPDATE_INVENTORY_ALERTS");
            當變更裝備時或者經過一定時間后觸發
            this:RegisterEvent("PLAYER_AURAS_CHANGED");
            當玩家【光環】改變時觸發,包括了【光環】的消失和出現
            注意,屬性完全相同【光環】重復釋放并不能觸發該事件
            this:RegisterEvent("PLAYER_TARGET_CHANGED");
            當玩家的目標變更時觸發,包括取消和選定目標
            arg1為該目標持續時間,單位分鐘,小數保留3位
            this:RegisterEvent("UNIT_AURASTATE");
            當某單位短時間【光環】改變時觸發,需進一步測試
            this:RegisterEvent("UNIT_INVENTORY_CHANGED");
            當玩家裝備變更時或者當觀察玩家裝備并發生裝備變更時觸發
            this:RegisterEvent("CRAFT_SHOW");
            this:RegisterEvent("CRAFT_CLOSE");
            工藝窗口的顯示與關閉,arg1為鼠標點擊鍵
            this:RegisterEvent("TRADE_SKILL_SHOW");
            this:RegisterEvent("TRADE_SKILL_CLOSE");
            交易技能制作物品窗口的顯示與關閉,arg1為鼠標點擊鍵
            this:RegisterEvent("UNIT_HEALTH");
            當任何一個單位的血量發生變化時觸發,arg1參數為該單位ID
            player,pet,target,mouseover,party1..4,partypet1..4,raid1..40,raidpet1..40,npc
            注意,該事件擁有很高的優先級,特別當參數為player時
            this:RegisterEvent("UNIT_MANA");
            當任何一個單位的魔法量發生變化時觸發,arg1參數為該單位ID
            this:RegisterEvent("UNIT_RAGE");
            當任何一個單位的怒氣值發生變化時觸發,arg1參數為該單位ID
            this:RegisterEvent("UNIT_FOCUS");
            當任何一個單位的焦距值發生變化時觸發,arg1參數為該單位ID
            注意,該事件實際上已經廢除,因為現在獵人使用MANA,而不是FOCUS
            this:RegisterEvent("UNIT_ENERGY");
            當任何一個單位的能量發生變化時觸發,arg1參數為該單位ID
            this:RegisterEvent("PLAYER_ENTER_COMBAT");
            當玩家進入自動攻擊狀態時觸發,自動射擊不包括在內
            注意,僅當你使用自動攻擊時觸發該事件
            使用其他任何技能或者攻擊行為都不可觸發
            this:RegisterEvent("PLAYER_LEAVE_COMBAT");
            離開自動攻擊狀態或者死亡時觸發
            this:RegisterEvent("PLAYER_COMBO_POINTS");
            當連擊點變更時觸發,arg1總返回player,而并不時連擊點數
            this:RegisterEvent("UPDATE_BINDINGS");
            當快捷鍵更改時觸發
            this:RegisterEvent("START_AUTOREPEAT_SPELL");
            當自動射擊開始時觸發,而不是自動攻擊
            this:RegisterEvent("STOP_AUTOREPEAT_SPELL");
            離開自動射擊狀態或者死亡時觸發
            ActionButton_UpdateHotkeys();
            end

            function ActionButton_UpdateHotkeys(actionButtonType)
            if ( not actionButtonType ) then
              actionButtonType = "ACTIONBUTTON";
            end
            local hotkey = getglobal(this:GetName().."HotKey");
            該對象在模板中為Fontstring
            local action = actionButtonType..this:GetID();
            actionButtonType,為該類命令的名字
            this:GetID,得到該命令在該類中的ID號
            注意,這2個字符串組成了最終的命令的名字
            如NUMPAD2,NUMPAD為類型,2為ID
            但是有些類型就一個命令無ID,如LEFT
            hotkey:SetText(KeyBindingFrame_GetLocalizedName(GetBindingKey(action), "KEY_"));
            GetBindingKey得到命令的快捷鍵名字,后面加上KEY_是為了顯示命令的字串
            例如:KEY_NUMPAD2就顯示為“數字鍵盤2”
            KeyBindingFrame_GetLocalizedName,由這個函數在快捷鍵窗口中顯示該命令的快捷鍵
            end

            function ActionButton_Update()
            -- Special case code for bonus bar buttons
            -- Prevents the button from updating if the bonusbar is still in an animation transition
            if ( this.isBonus and this.inTransition ) then
              ActionButton_UpdateUsable();
              ActionButton_UpdateCooldown();
              return;
            end

            local icon = getglobal(this:GetName().."Icon");
            local buttonCooldown = getglobal(this:GetName().."Cooldown");
            local texture = GetActionTexture(ActionButton_GetPagedID(this));
            if ( texture ) then
              icon:SetTexture(texture);
              icon:Show();
              如果該【柵格】有【圖標】,即若為【動作鍵】則顯示
              this.rangeTimer = TOOLTIP_UPDATE_TIME;
              每隔TOOLTIP_UPDATE_TIME事件間隔更新一次距離信息
              TOOLTIP_UPDATE_TIME為0.2S
              this:SetNormalTexture("Interface\\Buttons\\UI-Quickslot2");
              -- Save texture if the button is a bonus button, will be needed later
              if ( this.isBonus ) then
              判斷自己是否為【額外柵格】
               this.texture = texture;
              end
            else
              icon:Hide();
              buttonCooldown:Hide();
              this.rangeTimer = nil;
              this:SetNormalTexture("Interface\\Buttons\\UI-Quickslot");
              getglobal(this:GetName().."HotKey"):SetVertexColor(0.6, 0.6, 0.6);
            end
            ActionButton_UpdateCount();
            if ( HasAction(ActionButton_GetPagedID(this)) ) then
            判斷該【柵格】是否有【圖標】,即是否為【動作鍵】
              this:Show();
              ActionButton_UpdateState();
              ActionButton_UpdateUsable();
              ActionButton_UpdateCooldown();
              ActionButton_UpdateFlash();
            elseif ( this.showgrid == 0 ) then
              this:Hide();
            else
            這里表示,當該【柵格】沒有【圖標】
            但是顯示空【柵格】選項開啟時,不顯示公共CD效果
              buttonCooldown:Hide();
            end
            if ( GameTooltip:IsOwned(this) ) then
            判斷該【動作鍵】是否擁有【信息提示】
              ActionButton_SetTooltip();
            else
              this.updateTooltip = nil;
            end

            -- Update Macro Text
            local macroName = getglobal(this:GetName().."Name");
            macroName:SetText(GetActionText(ActionButton_GetPagedID(this)));
            GetActionText返回宏的名字
            end

            function ActionButton_ShowGrid(button)
            if ( not button ) then
              button = this;
            end
            button.showgrid = button.showgrid+1;
            getglobal(button:GetName().."NormalTexture"):SetVertexColor(1.0, 1.0, 1.0, 0.5);
            SetVertexColor(R,G,B)這個函數需要注意,可能學過3D的都知道,這個是頂點著色,取值0到1小數
            頂點著色并不是直接設置RGB的數值,而是在原有的RGB數值上乘以頂點著色指定的RGB百分比修正值
            例如:一個色塊RGB為50,100,30,如果你寫入SetVertexColor(0.5,0,1),結果RGB為25,0,30
            button:Show();
            end

            function ActionButton_HideGrid(button)
            if ( not button ) then
              button = this;
            end
            button.showgrid = button.showgrid-1;
            if ( button.showgrid == 0 and not HasAction(ActionButton_GetPagedID(button)) ) then
            把這里判斷showgrid變量為0和這一對函數對showgrid的操作聯系起來看
            就像是用堆棧實現括號配對一樣保證了顯示和隱藏的規范
              button:Hide();
            end
            end

            function ActionButton_UpdateState()
            if ( IsCurrentAction(ActionButton_GetPagedID(this)) or IsAutoRepeatAction(ActionButton_GetPagedID(this)) ) then
            IsAutoRepeatAction,自動射擊
            IsAttackAction,自動攻擊
              this:SetChecked(1);
            else
              this:SetChecked(0);
            end
            end

            function ActionButton_UpdateUsable()
            注意,這個函數的主體是個技能按鈕模板,所以針對的是一個【動作鍵】
            所以,當你拖動某個【圖標】時,其他【圖標】并不會跟著更新
            local icon = getglobal(this:GetName().."Icon");
            模板中定義
            local normalTexture = getglobal(this:GetName().."NormalTexture");
            local isUsable, notEnoughMana = IsUsableAction(ActionButton_GetPagedID(this));
            得到當前技能柵格的ID,這個是所有柵格ID號,包括73~96的
            if ( isUsable ) then
            是否在射程,當前在其他游戲規則中是否可用,是否在CD等
              icon:SetVertexColor(1.0, 1.0, 1.0);

              normalTexture:SetVertexColor(1.0, 1.0, 1.0);
            elseif ( notEnoughMana ) then
            是否足夠魔法、怒氣、能量
              icon:SetVertexColor(0.5, 0.5, 1.0);
              normalTexture:SetVertexColor(0.5, 0.5, 1.0);
            else
              icon:SetVertexColor(0.4, 0.4, 0.4);
              這個是灰色效果,當你拖拉【圖標】時,原【柵格】則為這個效果
              normalTexture:SetVertexColor(1.0, 1.0, 1.0);
            end
            end

            function ActionButton_UpdateCount()
            local text = getglobal(this:GetName().."Count");
            在模板中數量為Fontstring
            if ( IsConsumableAction(ActionButton_GetPagedID(this)) ) then
            判斷是否改【柵格】的物品為消費品
              text:SetText(GetActionCount(ActionButton_GetPagedID(this)));
            else
              text:SetText("");
            end
            end

            function ActionButton_UpdateCooldown()
            local cooldown = getglobal(this:GetName().."Cooldown");
            在模板中該【CD】定義為一個Model
            local start, duration, enable = GetActionCooldown(ActionButton_GetPagedID(this));
            CooldownFrame_SetTimer(cooldown, start, duration, enable);
            end

            function ActionButton_OnEvent(event)
            if ( event == "ACTIONBAR_SLOT_CHANGED" ) then
              if ( arg1 == -1 or arg1 == ActionButton_GetPagedID(this) ) then
              如果變更的【柵格】不明或者變更的【柵格】為自己則更新
               ActionButton_Update();
              end
              return;
            end
            if ( event == "PLAYER_ENTERING_WORLD" or event == "ACTIONBAR_PAGE_CHANGED" ) then
            總結起來是,當游戲環境有大的變化時,更新自己
              ActionButton_Update();
              return;
            end
            if ( event == "UPDATE_BONUS_ACTIONBAR" ) then
              if ( this.isBonus ) then
               ActionButton_Update();
              end
              return;
            end
            if ( event == "ACTIONBAR_SHOWGRID" ) then
              ActionButton_ShowGrid();
              return;
            end
            if ( event == "ACTIONBAR_HIDEGRID" ) then
              ActionButton_HideGrid();
              return;
            end
            if ( event == "UPDATE_BINDINGS" ) then
              ActionButton_UpdateHotkeys();
              return;
            end

            -- All event handlers below this line MUST only be valid when the button is visible
            if ( not this:IsVisible() ) then
            如果該【圖標】不可見,那么直接返回,即下面的所有事件均要求該【圖標】可見,即應該為一個【動作鍵】
              return;
            end

            if ( event == "UNIT_HEALTH" or event == "UNIT_MANA" or event == "UNIT_RAGE" or event == "UNIT_FOCUS" or event == "UNIT_ENERGY" ) then
              if ( arg1 == "player" ) then
              如果發生在玩家身上,應該判斷所有技能的可用性
               ActionButton_UpdateUsable();
              end
            elseif ( event == "PLAYER_TARGET_CHANGED" or event == "PLAYER_AURAS_CHANGED" ) then
              ActionButton_UpdateUsable();
            elseif ( event == "UNIT_AURASTATE" ) then
              if ( arg1 == "player" or arg1 == "target" ) then
               ActionButton_UpdateUsable();
              end
            elseif ( event == "UNIT_INVENTORY_CHANGED" ) then
              if ( arg1 == "player" ) then
               ActionButton_Update();
              end
            elseif ( event == "ACTIONBAR_UPDATE_STATE" ) then
              ActionButton_UpdateState();
            elseif ( event == "ACTIONBAR_UPDATE_USABLE" or event == "UPDATE_INVENTORY_ALERTS" or event == "ACTIONBAR_UPDATE_COOLDOWN" ) then
              ActionButton_UpdateUsable();
              ActionButton_UpdateCooldown();
            elseif ( event == "CRAFT_SHOW" or event == "CRAFT_CLOSE" or event == "TRADE_SKILL_SHOW" or event == "TRADE_SKILL_CLOSE" ) then
              ActionButton_UpdateState();
            elseif ( event == "PLAYER_ENTER_COMBAT" ) then
              if ( IsAttackAction(ActionButton_GetPagedID(this)) ) then
               ActionButton_StartFlash();
              end
            elseif ( event == "PLAYER_LEAVE_COMBAT" ) then
              if ( IsAttackAction(ActionButton_GetPagedID(this)) ) then
               ActionButton_StopFlash();
              end
            elseif ( event == "PLAYER_COMBO_POINTS" ) then
              ActionButton_UpdateUsable();
            elseif ( event == "START_AUTOREPEAT_SPELL" ) then
              if ( IsAutoRepeatAction(ActionButton_GetPagedID(this)) ) then
               ActionButton_StartFlash();
              end
            elseif ( event == "STOP_AUTOREPEAT_SPELL" ) then
              if ( ActionButton_IsFlashing() and not IsAttackAction(ActionButton_GetPagedID(this)) ) then
              如果該技能在【閃動】,并且不是自動攻擊
               ActionButton_StopFlash();
              end
            end
            end

            function ActionButton_SetTooltip()
            if ( GetCVar("UberTooltips") == "1" ) then
            Uber,乳房。。。。。
            這句應該是判斷是否屬于一般類型,母類型
            UberTooltips詳細信息提示
              GameTooltip_SetDefaultAnchor(GameTooltip, this);
              一般位于屏幕右下角,會根據【動作條】的多少自動改變位置
            else
            如果這個【柵格】的【信息提示】不屬于默認的形式則
              if ( this:GetParent() == MultiBarBottomRight or this:GetParent() == MultiBarRight or this:GetParent() == MultiBarLeft ) then
              【動作條】MultiBarBottomRight右下,MultiBarRight右方,MultiBarLeft左邊下
               GameTooltip:SetOwner(this, "ANCHOR_LEFT");
               這里解釋下SetOwner函數,GameTooltip:SetOwner(owner, anchor);
               其中owner是參照物,anchor是對齊方式,取值如下:
               ANCHOR_TOPRIGHT 相當于 SetPoint("BOTTOMRIGHT",object,"TOPRIGHT")
               ANCHOR_RIGHT 相當于 SetPoint("BOTTOMLEFT",object,"TOPRIGHT")
               ANCHOR_BOTTOMRIGHT 相當于 SetPoint("TOPLEFT",object,"BOTTOMRIGHT")
               ANCHOR_TOPLEFT 相當于 SetPoint("BOTTOMLEFT",object,"TOPLEFT")
               ANCHOR_LEFT 相當于 SetPoint("BOTTOMRIGHT",object,"TOPLEFT")
               ANCHOR_BOTTOMLEFT 相當于 SetPoint("TOPRIGHT",object,"BOTTOMLEFT")
              else
               GameTooltip:SetOwner(this, "ANCHOR_RIGHT");
              end
            end

            if ( GameTooltip:SetAction(ActionButton_GetPagedID(this)) ) then
            SetAction,返回值為該【信息提示】是否需要實時更新
              this.updateTooltip = TOOLTIP_UPDATE_TIME;
            else
              this.updateTooltip = nil;
            end
            end

            function ActionButton_OnUpdate(elapsed)
            if ( ActionButton_IsFlashing() ) then
              this.flashtime = this.flashtime - elapsed;
              if ( this.flashtime <= 0 ) then
              flashtime初始為0,即第一次flash的時間并不為0.4,而是第一個elapsed決定
               local overtime = -this.flashtime;
               overtime,該函數的一個中間量,用語變化符號
               if ( overtime >= ATTACK_BUTTON_FLASH_TIME ) then
               這個if為了下面給flashtime更新是不出現負數考慮
               注意,ERROR文本框的文本并不和這里的時間掛鉤
                overtime = 0;
               end
               this.flashtime = ATTACK_BUTTON_FLASH_TIME - overtime;
               更新flashtime,使得從第二次開始間隔一個ATTACK_BUTTON_FLASH_TIME

               local flashTexture = getglobal(this:GetName().."Flash");
               if ( flashTexture:IsVisible() ) then
               效果的實現即為反復顯示這個flash紋理
                flashTexture:Hide();
               else
                flashTexture:Show();
               end
              end
            end

            -- Handle range indicator
            if ( this.rangeTimer ) then
              if ( this.rangeTimer < 0 ) then
              
               local count = getglobal(this:GetName().."HotKey");
               if ( IsActionInRange( ActionButton_GetPagedID(this)) == 0 ) then
               IsActionInRange,返回指定【動作鍵】是否在距離之內
               返回nil表示該【柵格】無【圖標】,或者沒有選定目標
               返回0表示不在距離之內,返回1表示在距離之內
               注意,如果你沒有試圖釋放這個【動作鍵】在目標身上,它可能總返回1
                count:SetVertexColor(1.0, 0.1, 0.1);
               else
                count:SetVertexColor(0.6, 0.6, 0.6);
               end
               this.rangeTimer = TOOLTIP_UPDATE_TIME;
              else
               this.rangeTimer = this.rangeTimer - elapsed;
              end
            end

            if ( not this.updateTooltip ) then
              return;
            end

            this.updateTooltip = this.updateTooltip - elapsed;
            if ( this.updateTooltip > 0 ) then
              return;
            end

            if ( GameTooltip:IsOwned(this) ) then
              ActionButton_SetTooltip();
            else
              this.updateTooltip = nil;
            end
            end

            function ActionButton_GetPagedID(button)
            if( button == nil ) then
              message("nil button passed into ActionButton_GetPagedID(), contact Jeff");
              嚴重錯誤需要彈出消息框
              return 0;
            end
            if ( button.isBonus and CURRENT_ACTIONBAR_PAGE == 1 ) then
            如果是【額外動作條】并且當前【動作條ID】為1
              local offset = GetBonusBarOffset();
              GetBonusBarOffset,得到【額外動作條】的偏移量
              返回1到3,分別對應1到3號戰士姿態,或者德魯依外形,或者是盜賊狀態
              if ( offset == 0 and BonusActionBarFrame and BonusActionBarFrame.lastBonusBar ) then
              應該是判斷當意外失去【額外動作條】定位時,定位于最近一次改變的
              注意,如果該職業無【額外動作條】時,偏移量也為0
               offset = BonusActionBarFrame.lastBonusBar;
              end
              return (button:GetID() + ((NUM_ACTIONBAR_PAGES + offset - 1) * NUM_ACTIONBAR_BUTTONS));
              注意NUM_ACTIONBAR_PAGES + offset用的是加法,所以我們肯定暴雪偷偷藏了24個【額外柵格】
            elseif ( button:GetParent():GetName() == "MultiBarBottomLeft" ) then
              return (button:GetID() + ((BOTTOMLEFT_ACTIONBAR_PAGE - 1) * NUM_ACTIONBAR_BUTTONS));
            elseif ( button:GetParent():GetName() == "MultiBarBottomRight" ) then
              return (button:GetID() + ((BOTTOMRIGHT_ACTIONBAR_PAGE - 1) * NUM_ACTIONBAR_BUTTONS));
            elseif ( button:GetParent():GetName() == "MultiBarLeft" ) then
              return (button:GetID() + ((LEFT_ACTIONBAR_PAGE - 1) * NUM_ACTIONBAR_BUTTONS));
            elseif ( button:GetParent():GetName() == "MultiBarRight" ) then
              return (button:GetID() + ((RIGHT_ACTIONBAR_PAGE - 1) * NUM_ACTIONBAR_BUTTONS));
            else
              return (button:GetID() + ((CURRENT_ACTIONBAR_PAGE - 1) * NUM_ACTIONBAR_BUTTONS))
            end
            end

            function ActionButton_UpdateFlash()
            local pagedID = ActionButton_GetPagedID(this);
            if ( (IsAttackAction(pagedID) and IsCurrentAction(pagedID)) or IsAutoRepeatAction(pagedID) ) then
              ActionButton_StartFlash();
            else
              ActionButton_StopFlash();
            end
            end

            function ActionButton_StartFlash()
            this.flashing = 1;
            this.flashtime = 0;
            ActionButton_UpdateState();
            end

            function ActionButton_StopFlash()
            this.flashing = 0;
            getglobal(this:GetName().."Flash"):Hide();
            ActionButton_UpdateState();
            end

            function ActionButton_IsFlashing()
            if ( this.flashing == 1 ) then
              return 1;
            else
              return nil;
            end
            end


            ---------------------總結一下


            常量
            TOOLTIP_UPDATE_TIME         【信息提示】更新間隔
            CURRENT_ACTIONBAR_PAGE        當前【動作條ID】
            NUM_ACTIONBAR_PAGES         總頁碼
            NUM_ACTIONBAR_BUTTONS        一個【動作條】的【柵格】數
            ATTACK_BUTTON_FLASH_TIME       【閃動】間隔
            BOTTOMLEFT_ACTIONBAR_PAGE       左下【動作條ID】
            BOTTOMRIGHT_ACTIONBAR_PAGE       右下【動作條ID】
            LEFT_ACTIONBAR_PAGE         右邊2【動作條ID】
            RIGHT_ACTIONBAR_PAGE        右邊1【動作條ID】

            事件
            ACTIONBAR_PAGE_CHANGED        【動作條】翻頁
            UPDATE_BONUS_ACTIONBAR        【額外動作條】更新
            ACTIONBAR_SHOWGRID         顯示【柵格】
            ACTIONBAR_HIDEGRID         隱藏【柵格】
            ACTIONBAR_SLOT_CHANGED        【柵格】內容變更
            ACTIONBAR_UPDATE_STATE        【動作鍵】更新狀態
            ACTIONBAR_UPDATE_USABLE        【動作鍵】更新可用性
            ACTIONBAR_UPDATE_COOLDOWN       【動作鍵】更新【CD】
            UPDATE_INVENTORY_ALERTS        裝備警告
            PLAYER_AURAS_CHANGED        【光環】改變
            PLAYER_TARGET_CHANGED        目標改變
            UNIT_AURASTATE          單位【光環】改變
            UNIT_INVENTORY_CHANGED        單位裝備改變
            CRAFT_SHOW           工藝窗口顯示
            CRAFT_CLOSE           工藝窗口隱藏
            TRADE_SKILL_SHOW         交易技能窗口顯示
            TRADE_SKILL_CLOSE         交易技能窗口隱藏
            UNIT_HEALTH           單位血量改變(優先級極高)
            UNIT_MANA           單位魔法改變
            UNIT_RAGE           單位怒氣改變
            UNIT_FOCUS           單位焦距改變(已廢除)
            UNIT_ENERGY           單位能量改變
            PLAYER_ENTER_COMBAT         開始自動攻擊
            PLAYER_LEAVE_COMBAT         結束自動攻擊
            PLAYER_COMBO_POINTS         連擊點改變
            UPDATE_BINDINGS          快捷鍵更新
            START_AUTOREPEAT_SPELL        開始自動射擊
            STOP_AUTOREPEAT_SPELL        結束自動射擊

            函數
            IsShiftKeyDown          Shift鍵是否按下
            PickupAction          吸附【圖標】
            PlaceAction           放置【圖標】
            UseAction           使用【動作鍵】
            GetButtonState          得到【動作鍵】狀態
            SetButtonState          設置【動作鍵】狀態
            Frame:RegisterForDrag        注冊拖拉行為
            Frame:RegisterForClicks        注冊點擊行為
            GetBindingKey          得到快捷鍵
            HasAction           【柵格】是否放置了【圖標】
            Frame:SetVertexColor        頂點色彩修正
            IsAutoRepeatAction         是否正在自動射擊
            IsAttackAction          是否正在自動攻擊
            IsUsableAction          【動作鍵】是否可用
            IsConsumableAction         是否為消費品
            GetActionCooldown         得到【CD】
            GetCVar            有待測試
            GameTooltip:SetAction        設置【信息提示】
            Frame:IsVisible          是否可見
            IsActionInRange          是否在距離之內
            GetBonusBarOffset         得到【額外動作條】偏移量



            累死了。。。。。。明天再貼圖片和排版彩色

            http://wowbbs.game.mop.com/forumdisplay.php?fid=138

            這個帖子我已經貼了圖片
            posted on 2007-06-25 02:11 七星重劍 閱讀(3391) 評論(2)  編輯 收藏 引用 所屬分類: 亂七八糟

            FeedBack:
            # re: [轉]WOW原始UI代碼分析【ActionButton】 2008-11-20 17:09 小不點
            XML 怎么到游戲中的界面的?難道是用FLASH,不是Texture嘛?請高手請教,謝謝~~
            mail:amyvmiwei@126.com  回復  更多評論
              
            # re: [轉]WOW原始UI代碼分析【ActionButton】 2008-11-21 14:16 七星重劍
            @小不點
            xml是界面的配置文件,c++代碼根據配置來生成界面,看下cegui就知道了  回復  更多評論
              
            久久亚洲AV成人无码电影| 亚洲国产精品一区二区三区久久 | 69国产成人综合久久精品| 久久亚洲国产最新网站| 热久久国产欧美一区二区精品| 国产精品va久久久久久久| 亚洲精品高清久久| 久久99精品久久久久久9蜜桃| 久久av免费天堂小草播放| 久久久久人妻精品一区三寸蜜桃| 久久久久亚洲AV无码去区首| 久久只有这里有精品4| 性欧美丰满熟妇XXXX性久久久| 久久综合88熟人妻| 久久久精品一区二区三区| 国产成人久久777777| 欧美性猛交xxxx免费看久久久| 亚洲欧美一级久久精品| 免费无码国产欧美久久18| 久久精品国产AV一区二区三区| 国产V亚洲V天堂无码久久久| 久久九九全国免费| 亚洲国产成人久久综合区| 亚洲av日韩精品久久久久久a| 国产精品久久久福利| 久久亚洲av无码精品浪潮| 色综合久久中文字幕无码| 亚洲国产精品久久久久婷婷软件| 久久伊人影视| 久久国产乱子伦精品免费强| 亚洲欧美国产精品专区久久| 久久ZYZ资源站无码中文动漫| 国产精品一区二区久久精品无码| 久久久久国产精品人妻| 日本精品久久久久中文字幕| 久久人人爽人人爽人人爽| 免费观看久久精彩视频| 老男人久久青草av高清| 青青国产成人久久91网| 久久午夜羞羞影院免费观看| 色综合合久久天天给综看|