• <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>
            隨筆 - 96  文章 - 255  trackbacks - 0
            <2008年2月>
            272829303112
            3456789
            10111213141516
            17181920212223
            2425262728291
            2345678

            E-mail:zbln426@163.com QQ:85132383 長期尋找對戰略游戲感興趣的合作伙伴。

            常用鏈接

            留言簿(21)

            隨筆分類

            隨筆檔案

            SDL相關網站

            我的個人網頁

            我的小游戲

            資源下載

            搜索

            •  

            積分與排名

            • 積分 - 492164
            • 排名 - 38

            最新評論

            閱讀排行榜

            評論排行榜

            作者:龍飛

            1.1:為了按鈕做準備

                    按鈕是鼠標事件響應的象征,在PC游戲中起著十分重要的作用。這一章節,我們開始通過SDL提供的底層函數,自己來設計按鈕。
                    按鈕一般有這么幾種狀態:
            out: 鼠標不在按鈕上;
            over: 鼠標在按鈕上;
            down: 鼠標按下了;
            up: 鼠標松開了;
                    其中,down和up又可以細分為鼠標是在按鈕上按下松開的,還是在按鈕外按下松開的。
                    我們先從按鈕的表現形式——圖片來分析這些問題。
                    為了表現不同的狀態,我們需要多張圖片。至少的,out與over和down中的至少一張圖片應該是不一樣的,這樣才能給人以“按下了”的視覺效果。也就是說,如果我們構建按鈕類,這個類將會包含我們之前設計的SurfaceClass類。這樣,根據我們之前討論的一些C++細節問題,我們必須重新小心的設計SurfaceClass類。

            1.2:為SurfaceClass設計基類

                    我們之前使用DisplaySurface本身作為TextSurface的基類,這是因為我們希望通過基類本身引用派生類,從而不需要為基類和派生類分別寫函數。同樣的,我們希望在ButtonClass中直接使用基類作為成員數據,這樣,ButtonClass可以不需要為派生類重新構建。在之前的DisplaySurface中,我們可以看到,大部分方法,比如最為重要的blit()方法,所涉及到的成員數據僅僅就是SDL_Surface* pSurface,這一點,TextSurface類也是一樣的。DisplaySurface類通過圖片創建pSurface,TextSurface類通過字庫創建pSurface,他們的創建條件不盡相同,TextSurface需要打開TTF_Init(),還需要打開字庫TTF_OpenFont(),所以,他們的構造函數與析構函數是不一樣的。一種更加清晰的關系,是建立起他們的基類,然后把他們的區別點分開處理,而不是之前采用的if來判斷處理。
                    最清晰的辦法,是把BaseSurface設計成為抽象基類(ABC),但是ABC的問題在于,無法創建ABC本身的對象,也就是說,我們需要在ButtonClass中包含的BaseSurface對象無法建立,所以,我們不能把BaseSurface設計成為ABC。我想到的辦法,是將BaseSurface的默認構造函數僅僅提供給派生類使用,也就是說,因為BaseClass的默認構造函數本身是不能建立起必要的數據的,比如pSurface和pScreen,我們暫時都用空指針代替。這里的思想其實還是ABC的,讓基類僅僅提供算法,即使算法所需要的元素還尚不存在。但是,只要這些元素存在了,BaseSurface也就可以完成這些算法,所以,我們把BaseSurface的復制構造函數設計為公共的,這很重要,這樣才為我們通過派生類去初始化基類的構造函數初始化列表提供了可能。
                    我們把基類命名為BaseSurface,之前的DisplaySurface我們用更形象的名稱代替,叫PictureSurface,然后TextSurface不改名。

            1.3:如何深度復制SDL_Surface ?

                    因為PictureSurface和TextSurface的構造函數都涉及到了堆操作,也就是說,SDL_Surface是建立在堆上的。我們需要通過基類的復制構造函數復制SDL_Surface,必須找到合適的工具。具體來說,新對象的pSurface必須指像一個新建立起來的SDL_Surface對象,而非被復制的對象本身。
                    我最先想到的是用new...delete組合,但是失敗了。為什么呢?我們研究SDL_Surafce結構本身,發現在之中包含著一些其它的指針。比如SDL_PixelFormat *format和void *pixels。也就是說,SDL_Surface本身的構建也有堆操作,而且,因為SDL_Surafce是C風格的結構而不是類,它不能提供深度復制的操作,所以,即使我們用new為SDL_Surface申請了新空間,SDL_Surface本身也不會為format和pixels申請新的副本。當被釋放掉原本的時候,副本將尋找不到原本的format和pixels,從而產生錯誤。
                    我們另外能找到的可以深度復制SDL_Surface的函數,是:
            SDL_Surface *SDL_DisplayFormat(SDL_Surface *surface);
            SDL_Surface *SDL_ConvertSurface(SDL_Surface *src, SDL_PixelFormat *fmt, Uint32 flags);
                    這兩個函數貌似都是可行的。實際上,基本上也都是可行的。但是涉及到文字的時候,SDL_DisplayFormat將不能正確的轉換Blended和Shaded的文字,所以,最后只能使用SDL_ConvertSurafce()。
             新構建的SurfaceClass源代碼見:
            http://www.shnenglu.com/lf426/archive/2008/04/14/47038.html
            posted on 2008-04-17 12:37 lf426 閱讀(2267) 評論(0)  編輯 收藏 引用 所屬分類: SDL入門教程
            超级97碰碰碰碰久久久久最新| a高清免费毛片久久| 久久精品亚洲男人的天堂| 久久97久久97精品免视看秋霞| 亚洲精品乱码久久久久久不卡| 久久精品aⅴ无码中文字字幕不卡| 久久亚洲精品无码AV红樱桃| 精品久久久久久综合日本| 午夜视频久久久久一区 | 国产L精品国产亚洲区久久| 久久久久免费视频| 嫩草伊人久久精品少妇AV| 色噜噜狠狠先锋影音久久| 久久成人小视频| 国内精品久久久久国产盗摄| 色综合久久无码五十路人妻| 青青国产成人久久91网| 日韩精品无码久久久久久| 天天做夜夜做久久做狠狠| 麻豆精品久久精品色综合| 亚洲色婷婷综合久久| 久久综合五月丁香久久激情| 久久福利青草精品资源站免费| 久久精品国产乱子伦| 久久久WWW成人| 91久久精品无码一区二区毛片| 国产A三级久久精品| 国产一区二区精品久久凹凸| 久久亚洲AV成人无码| 久久久久久A亚洲欧洲AV冫| 久久精品国产亚洲综合色| 久久国产精品无码HDAV| 久久强奷乱码老熟女网站| 久久人人爽人人精品视频| 久久精品成人免费观看97| 91超碰碰碰碰久久久久久综合 | 国产精品久久99| 国产精品一区二区久久国产| 久久久久亚洲AV无码网站| 丰满少妇人妻久久久久久| 久久亚洲sm情趣捆绑调教|