• <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年3月>
            2425262728291
            2345678
            9101112131415
            16171819202122
            23242526272829
            303112345

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

            常用鏈接

            留言簿(21)

            隨筆分類

            隨筆檔案

            SDL相關網站

            我的個人網頁

            我的小游戲

            資源下載

            搜索

            •  

            積分與排名

            • 積分 - 494279
            • 排名 - 39

            最新評論

            閱讀排行榜

            評論排行榜

            作者:龍飛

            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 閱讀(2279) 評論(0)  編輯 收藏 引用 所屬分類: SDL入門教程
            狠狠色综合久久久久尤物| 久久99精品久久久久久久久久| 天天久久狠狠色综合| 精品久久久久久中文字幕| 国产成人精品综合久久久| 香港aa三级久久三级老师2021国产三级精品三级在 | 一级做a爰片久久毛片人呢| 精品国产综合区久久久久久| 国产精品久久久久a影院| 国产精品一久久香蕉国产线看观看| 国产精品视频久久久| 久久精品久久久久观看99水蜜桃| 久久久久久国产精品无码超碰| 国产免费久久久久久无码| 久久综合给合久久狠狠狠97色| 久久精品成人免费观看97| 成人国内精品久久久久影院| 婷婷久久五月天| 美女久久久久久| 国产精自产拍久久久久久蜜| 久久婷婷五月综合色高清| 伊人久久大香线蕉成人| 久久精品国产精品亜洲毛片| av无码久久久久久不卡网站| 中文字幕日本人妻久久久免费 | 97久久精品午夜一区二区| 无码任你躁久久久久久老妇App| 国产毛片久久久久久国产毛片| 99精品久久久久中文字幕| 色综合久久中文字幕无码| 久久天天躁狠狠躁夜夜不卡| 一级a性色生活片久久无| 日本精品一区二区久久久| 久久国产成人| 无码乱码观看精品久久| 久久人人爽人人爽人人片AV麻豆| 国产精品欧美久久久久无广告 | 久久99热国产这有精品| 91精品国产综合久久婷婷| 国产精品美女久久久久网| 久久精品视频网|