• <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ǎo)航

            <2008年12月>
            30123456
            78910111213
            14151617181920
            21222324252627
            28293031123
            45678910

            統(tǒng)計

            常用鏈接

            留言簿(12)

            隨筆分類

            隨筆檔案

            Friends

            WebSites

            積分與排名

            最新隨筆

            最新評論

            閱讀排行榜

            評論排行榜

            HGE中的游戲GUI代碼閱讀

            作者 : Kevin Lynx
            BLOG: http://blog.csdn.net/kevinlynx


            第一部分:

            HGE helper類中的GUI:

            引擎版本:1.60release。



            文件:hgegui.h , hgegui.cpp, hgeguictrls.h , hgeguictrls.cpp

            大致類圖:



            其中,hgeGUIObject是抽象基類,具體的控件類如按鈕,文本標簽,都是從它派生而來。HgeGUI屬于整個GUI系統(tǒng)的manager,它會保存所有的控件。

            關(guān)于hgeGUIObject的8個成員變量,文檔里已經(jīng)有所描述:

            int id; //控件ID

            bool bStatic; //是否可以接受鍵盤焦點

            bool bVisible; //是否可見

            bool bEnabled; //是否有效

            hgeRect rect; //控件大小



            hgeGUI *gui; //其屬于的 manager ,相當(dāng)于父對象

            hgeGUIObject *next; //用于雙向鏈表,把所有控件連接在一起

            hgeGUIObject *prev;

            static HGE *hge; //方便使用HGE接口

            關(guān)于其部分接口的描述:

            Render: 用于渲染控件到屏幕上

            Update: 用于更新其動畫

            Enter: 控件剛顯示時的動畫

            Leave: 控件要消失時的動畫

            IsDone: 控件剛顯示和消失時的狀態(tài)查詢函數(shù)



            該類也就是提供了一個抽象而已,利用C++語言的多態(tài)機制來方便hgeGUI管理所有的控件。其他具體的控件繼承了hgeGUIObject后,必須實現(xiàn)構(gòu)造函數(shù)和Render函數(shù)。



            關(guān)于hgeGUI:

            這個類應(yīng)該屬于manager。它負責(zé)管理所有的控件。

            其數(shù)據(jù)成員:

            hgeGUIObject *ctrls; //保存所有控件

            hgeGUIObject *ctrlLock; //可能是用來保存當(dāng)前被鼠標操作的控件

            hgeGUIObject *ctrlFocus; //保存焦點控件

            hgeGUIObject *ctrlOver; //用來保存鼠標指針所指的控件



            int navmode;

            int nEnterLeave;

            hgeSprite *sprCursor; //渲染鼠標指針用的



            float mx,my; //鼠標坐標

            int nWheel; //滾輪偏移量

            bool bLPressed, bLLastPressed;//本幀左鍵狀態(tài),上一幀的左鍵狀態(tài)

            bool bRPressed, bRLastPressed;

            其Update方法會負責(zé)控件的進入和離開動畫,還會負責(zé)整體的狀態(tài)設(shè)置---哪些控件擁有焦點,哪些控件被鼠標正在操作,哪些控件正被鼠標指針指著,這些控件它都會保存起來。(也就是說,我們還是可以通過檢查控件的狀態(tài)來設(shè)置當(dāng)鼠標指針在其上時的新動畫。)



            總體而言,該引擎的GUI還是很簡單的。一個manager,負責(zé)管理所有的控件,然后一個抽象基類,用來協(xié)助manager管理---其他具體的控件都必須從那個抽象基類派生。



            下面具體看一個Button控件:

            Button類的定義如下:

            class hgeGUIButton : public hgeGUIObject

            {

            public:

            hgeGUIButton(int id, float x, float y, float w, float h, HTEXTURE tex, float tx, float ty);

            virtual ~hgeGUIButton();



            void SetMode(bool _bTrigger) { bTrigger=_bTrigger; }

            void SetState(bool _bPressed) { bPressed=_bPressed; }

            bool GetState() const { return bPressed; }



            virtual void Render();

            virtual bool MouseLButton(bool bDown);



            private:

            bool bTrigger;

            bool bPressed;

            bool bOldState;

            hgeSprite *sprUp, *sprDown;

            };

            其中bTrigger表示該按鈕的行為是否象一個RadioButton,bPressed表示當(dāng)前按鈕是否被按下,bOldState表示上一次按鈕狀態(tài),特別用來實現(xiàn)bTrigger的,sprUp,sprDown分別用來繪制彈起和按下時的按鈕外觀。這兩個精靈的創(chuàng)建都是從構(gòu)造函數(shù)的tex上創(chuàng)建而來的,它要求兩個狀態(tài)必須保存在一幅紋理上,且順序為從左至右。

            按鈕的實現(xiàn)代碼也很簡單:

            void hgeGUIButton::Render()

            {

            if(bPressed) sprDown->Render(rect.x1, rect.y1);

            else sprUp->Render(rect.x1, rect.y1);

            }



            bool hgeGUIButton::MouseLButton(bool bDown)

            {

            if(bDown)

            {

            bOldState=bPressed; bPressed=true;

            return false;

            }

            else

            {

            if(bTrigger) bPressed=!bOldState;

            else bPressed=false;

            return true;

            }

            }



            聯(lián)系起來,當(dāng)hgeGUI::Update里處理ProcessCtrl時,如果鼠標左鍵按下且其指針在按鈕范圍內(nèi),那么就調(diào)用hgeGUIButton::MouseLButton( true ),這個時候button的bPressed=true,那么在渲染的時候,自然就表現(xiàn)出被按下時的狀態(tài)。

            事實上對于這種類型的按鈕---如同windows下的窗體按鈕,我們一般不檢查其是否被按下,而是檢查其是否發(fā)生了clicked 這個事件,而這個事件是在先按下在彈起的情況下發(fā)生的。因此,判斷該事件發(fā)生的條件就為:上一幀狀態(tài)被按下,這一幀沒被按下。



            雖然HGE引擎的GUI很簡單,但是其擴展性很好。因為hgeGUI::Update基本上派發(fā)了所有控件需要的消息---鍵盤操作,以及鼠標操作;而hgeGUIObject基類的很多成員函數(shù)都會處理這些消息,我們只需要派生hgeGUIObject,然后重載我們需要的消息處理即可。

            第二部分:

            HGE擴展GUI庫,從HGE官方論壇下載(作者不明):

            工程結(jié)構(gòu):



            其中,guitest.cpp為測試文件。



            類結(jié)構(gòu):



            整個系統(tǒng)的工作原理:

            用戶繼承抽象基類GUIApp,實現(xiàn)具體的OnEvent函數(shù),然后該類會管理所有的GUIAppWindow對象,GUIAppWindow窗口對象會管理其上的所有子控件。



            相應(yīng)地,GUIApp派生類會直接得到鼠標和鍵盤消息,然后派發(fā)給所有窗口對象,然后窗口對象再把消息派發(fā)到具體的控件對象上。



            這種Parent-Child關(guān)系大致為:


            GUIAppWindow類保存有其所屬的GUIApp對象指針,每個具體的控件又保存有其所屬的GUIAppWindow 的對象指針。



            當(dāng)一個控件處理了某個事件后,例如按鈕處理了鼠標單擊事件,它就需要告訴外界用戶單擊了這個按鈕。這里采用的方法是:在基類GUIAppObject里定義了一個虛函數(shù)OnEvent( int id)

            ,然后在其派生類GUIAppWindow里把這個函數(shù)重載為純虛函數(shù),函數(shù)有一個參數(shù),那就是控件ID。當(dāng)一個控件處理了某個事件后,就通過其內(nèi)部保存的父窗口指針來調(diào)用OnEvent函數(shù),然后GUIAppWindow的派生類---如果該類能產(chǎn)生對象,那么其必然實現(xiàn)了OnEvent的具體代碼(這就是為什么在GUIAppWindow里要把OnEvent又重載為純虛函數(shù)的原因),然后在此代碼里,窗口根據(jù)傳進來的控件ID來得知哪個控件發(fā)生了事件!



            GUIAppWindow里有一個容器,它保存了所有該窗口上的控件。



            所有控件再創(chuàng)建時,都是以其父窗口為參考坐標系的,也就是相對坐標,但是其實際保存的坐標卻是絕對坐標—既相對于整個屏幕的坐標(如果是窗口程序,就相對于整個窗口)。大致過程為:在GUIAppWindow派生類中創(chuàng)建子控件時,給子控件指定的坐標為相對坐標,然后當(dāng) AddCtrl 時就會重新把子控件的坐標改變?yōu)榻^對坐標。



            GUIApp里直接有了BeginScene和EndScene的渲染代碼。



            要使用該擴展庫,大致步驟為:

            1. 繼承GUIAppWindow類,在這個派生類里重載具體的處理OnEvent的函數(shù),并創(chuàng)建所有該窗口上的子控件。

            2. 繼承GUIApp類,在這個派生類中創(chuàng)建窗口對象,并把窗口對象AddCtrl,在這里可以進行其他的初始化工作

            3. 在FrameFunc里調(diào)用GUIApp::FrameFunc函數(shù)。



            總體而言,這個擴展GUI主要是擴展了GUI Manager以及GUI Object,并且加入了Parent-Child機制。比較經(jīng)典的部分在于提供了一個 OnEvent 函數(shù),這樣就可以讓客戶程序員能夠得知窗體上的控件發(fā)生的事件。 ----其實這種方法的目的就跟Windows中的消息機制,Qt中的signal/slot機制一樣。

            posted on 2009-05-18 12:47 麒麟子 閱讀(1510) 評論(0)  編輯 收藏 引用 所屬分類: Game and Engine

            一本久久a久久精品综合香蕉 | 免费国产99久久久香蕉| 久久久久久亚洲精品成人| 国产精品九九九久久九九| 久久996热精品xxxx| 日韩av无码久久精品免费| 青青草国产精品久久| 久久人人爽人人爽人人片AV麻烦| 久久国产精品99精品国产987| 亚洲欧美日韩精品久久亚洲区| 精品一区二区久久| 一本一道久久综合狠狠老| 久久久久久A亚洲欧洲AV冫 | 人人狠狠综合88综合久久| 久久er99热精品一区二区| 亚洲欧美久久久久9999| 国产巨作麻豆欧美亚洲综合久久| 日日噜噜夜夜狠狠久久丁香五月| 久久99精品国产麻豆蜜芽| 精品国产91久久久久久久| 久久人妻少妇嫩草AV无码专区| 婷婷久久综合九色综合九七| 国产精品一区二区久久精品无码 | 久久毛片一区二区| 久久久91人妻无码精品蜜桃HD | 一本久久综合亚洲鲁鲁五月天亚洲欧美一区二区 | 国产激情久久久久影院老熟女免费| 亚洲狠狠婷婷综合久久久久| 亚洲一级Av无码毛片久久精品| 国产免费久久精品丫丫| 国产成人久久精品二区三区| 72种姿势欧美久久久久大黄蕉| 久久偷看各类wc女厕嘘嘘| 日韩人妻无码一区二区三区久久 | 久久99精品久久久久久噜噜| 成人国内精品久久久久影院VR| 日本三级久久网| 狠狠色伊人久久精品综合网| 久久精品国产99久久香蕉| 久久亚洲精品无码播放| 亚洲国产天堂久久久久久|