【正文】
況下幀率為 60,使用普通渲染機制幀率可能在 30 以下。 Cocos2dx 游戲引擎中提供了批次渲染機制 CCSpriteBatchNode,這種機制能使出現(xiàn)在屏幕之上的眾多子彈只被渲染一次,大大提高了游戲的運行效果 。 中國礦業(yè)大學 2020 屆本科生畢業(yè)設(shè)計(論文) 第 17 頁 紋理的優(yōu)化 由于 Cocos2dx 使用 OpenGL ES 進行繪圖, OpenGL ES 對紋理的渲染有特殊規(guī)則,即 每張紋理的 長和寬 的像素個數(shù)必須 為 二次冪數(shù)。比如 本身是 400*300,載入內(nèi)存后它就會變成 512*512 的紋理。如果用 RGBA8888 格式來表示一個像素點,既 4byte來表示一個像素點。 經(jīng)過加載后需要 1MB( 512*512*4=1MB)的空間,遠遠大于原圖。另一方面, OpenGL ES 每切換 一個圖像會 調(diào)用一次 glDrawArray。對于我們這款飛 行射擊類游戲,需要使用到的紋理比較多,花費在渲染上的時間將會比較多,所以會拖慢游戲整體的速度 從而 影響游戲的效果。 TexturePacker 是一款紋理打包軟件,它可以把所有的紋理以最小的存儲空間打包到一張圖里并生成一個 plist 文件。此外 Cocos2dx 為開發(fā)者提供了使用 plist 文件的函數(shù),開發(fā)者使用經(jīng)過打包的紋理圖,可以大大減少紋理所占內(nèi)存以及紋理切換所帶來的開銷。 經(jīng)過分析,決定使用 TexturePacker 紋理打包軟件對紋理進行打包來提高效率。 分數(shù)存儲的優(yōu)化 由于游戲所需存儲的數(shù)據(jù)并不多,所以我們 不用諸如 sql server、 MySQL 之類的數(shù)據(jù)庫,因為它們會為我們游戲的開發(fā)帶來不必要的 消耗 。在這里,我們使用 Cocos2dx 提供的 CCUserDefault 類, CCUserDefault 采用 XML 存儲技術(shù),通過 shareUserDefault()函數(shù)來獲取實例。使用這個類會大大減少我們在數(shù)據(jù)存儲上所 花 費的時間。 在這個游戲中使用的是 Cocos2dx 游戲引擎,所以設(shè)計思想需要與其保持一致。Cocos2dx 最主要有 4 個概念,分別是 Direct(導演)、 Scene(場景)、 Layer(層)、 Sprite(精靈)。其中一個游戲中只能有一個導演,導演用以場景調(diào)度。場景可以通俗的理 解為手機屏幕,它是有一個或多個層組成的。而游戲的主角或者地圖上 漂浮的云彩等都可以定義為精靈,精靈在定義完成后由開發(fā)者加到層上。具體調(diào)度如圖 所示 。 圖 Cocos2dx 設(shè)計思想 所以,在設(shè)計類時需要設(shè)計繼承場景的類,繼承圖層的類等等。 中國礦業(yè)大學 2020 屆本科生畢業(yè)設(shè)計(論文) 第 18 頁 由于有些類是使用游戲引擎所必須定義的,所以本游戲的 類 會比較多。在這里,我們只列舉飛機大戰(zhàn)最主要的幾個類,分別是:敵機類、敵機層類、游戲?qū)宇?、游戲場景類、?zhàn)機層類、道具層類、歡迎層類、歡迎場景類、設(shè)置類、游戲簡介類、開發(fā)者類、子彈層類、闖關(guān)歡迎場景類、闖關(guān)歡迎層類、游戲結(jié)束場景類、游戲結(jié)束層類、闖關(guān)游戲結(jié)束場景類、闖關(guān)游戲結(jié)束層類、控制層類、菜單層類。在這些類中最復雜最主要的是游戲?qū)宇?,因為它?lián)系了戰(zhàn)機層、子彈層、雙排子彈層、控制層、道具層、敵機層等。 敵機類:繼承 CCNode 類,主要負責敵機創(chuàng)建的內(nèi)存管理、把相應的生命值賦予給敵機精靈、返回精靈、敵機被子彈擊 中時生命值減一、獲取敵機紋理的矩形框。 敵機層類:繼承 CCLayer 類,主要負責三種敵機類型生命值的設(shè)定、闖關(guān)模式中 BOSS標記符的設(shè)定、游戲難度的設(shè)定、加載三種敵機、移除三種敵機、三種敵機的爆炸效果、敵機數(shù)組的操作。 游戲?qū)宇?: 繼承 CCLayer 類,主要負責加載無盡模式中的背景、音樂、飛機層類、子彈層類、雙排子彈層類、敵機層類、控制層類、鍵盤監(jiān)聽。此外,游戲?qū)宇愂钦麄€游戲的核心。在此類中對 CCLayer 中 update 函數(shù)進行重寫,系統(tǒng)會在游戲執(zhí)行的每一幀 中 執(zhí)行這個函數(shù)。它主要負責戰(zhàn)機普通子彈與三種敵機的 碰撞檢測、戰(zhàn)機在獲得雙排子彈道具后雙排子彈與三種敵機的碰撞檢測、戰(zhàn)機與三種敵機的碰撞檢測、全屏炸彈使用后毀滅當前幀中所有敵機、更新全屏炸彈的數(shù)量、內(nèi)存的管理、更新積分等等。 游戲場景類:繼承 CCScene 類,游戲引擎思想中的必備部分,主要用于游戲場景的初始化,容納游戲?qū)印? 戰(zhàn)機層類:繼承 CCLayer 類,玩家選擇無盡模式或闖關(guān)模式 后加入 到 游戲場景中。主要負責玩家戰(zhàn)機的創(chuàng)建、玩家對飛機位置的控制、判斷戰(zhàn)機是否生存、飛機的爆炸幀動畫、移除飛機。 道具層類:繼承 CCLayer 類,主要負責雙排道具和全屏炸彈道具的初 始化、定義道具出現(xiàn)的概率及位置、雙排子彈的移除、道具使用后的效果、戰(zhàn)機沒有獲得道具對道具進行回收。 歡迎層類:繼承 CCLayer 類,主要負責在玩家選擇無盡模式或闖關(guān)模式后進入游戲時,加載換場動畫、判斷積分存檔是否存在、獲取積分存檔。 歡迎場景類:繼承 CCScene 類,游戲引擎思想中的必備部分,主要用于加載歡迎層類。 設(shè)置類:繼承 CCLayer 類,主要負責對游戲背景音樂、音效的設(shè)置。 游戲簡介類:繼承 CCLayer 類,主要負責顯示游戲幫助及游戲背景。 開發(fā)者類:繼承 CCLayer 類,主要負責顯示開發(fā)者開發(fā)游戲 時的相關(guān)信息。 子彈層類:繼承 CCLayer 類,主要負責加載戰(zhàn)機子彈紋理、啟動戰(zhàn)機子彈的射擊、停止戰(zhàn)機子彈射擊、諸如速度和起始位置的戰(zhàn)機屬性的設(shè)置、子彈的移除操作。 闖關(guān)歡迎場景類:繼承 CCScene 類,主要負責容納闖關(guān)歡迎層。 闖關(guān)歡迎層類:繼承 CCLayer 類,主要負責闖關(guān)模式的換場動畫。 游戲結(jié)束場景類:繼承 CCScene 類,主要負責容納游戲結(jié)束層。 游戲結(jié)束層類:繼承 CCLayer 類,主要負責無盡模式游戲結(jié)束時,對積分的統(tǒng)計、判斷是否加入歷史最高分。 闖關(guān)游戲結(jié)束場景類:繼承 CCScene 類,主要負 責容納闖關(guān)游戲結(jié)束層。 中國礦業(yè)大學 2020 屆本科生畢業(yè)設(shè)計(論文) 第 19 頁 闖關(guān)游戲結(jié)束層類:繼承 CCLayer 類,主要負責闖關(guān)模式游戲結(jié)束時的換場動畫。 控制層類 : 繼承 CCLayer 類,用于加載到游戲場景之中。 主要 負責游戲暫停、更新分數(shù)的操作。 菜單層類:繼承 CCLayer 類,主要負責把 plist 文件加入精靈幀緩沖、菜單界面及版權(quán)、加載菜單項及對應事件、預加載音樂及音效。 圖 飛機大戰(zhàn)類圖 如圖 所示,由于類比較多空間有限 , 所以就不一一列舉類中的參數(shù)及函數(shù)。下面對游戲中重 要 的主要類的屬性和方法加以說明。 ( 1) 游戲?qū)宇?GameLayer,如表 、表 所示。 表 GameLayer 類屬性 屬性 類型 說明 MAX_BIGBOOM_COUNT int 全屏炸彈的最大數(shù)量 background1 CCSprite* 背景圖片一 background2 CCSprite* 背景圖片二 planeLayer PlaneLayer* 飛機層 bulletLayer BulletLayer* 子彈層 A bo u tC o n t r o lL a y e rB u lle t L a y e rE n e m yE n e m y L a y e rG a m e O v e r L a y e rG a m e O v e r Sc e n eG a m e Sc e n eI n t r o d u c eM e n u L a y e rM u t iB u lle t s L a y e rP la n e L a y e rSe tU F O L a y e rW e lc o m e L a y e rW e lc o m e Sc e n eC G G a m e Sc e n eC G G a m e L a y e rG a m e L a y e rA p p D e le g a t eC G W e lc o m e Sc e n eC G W e lc o m e L a y e rC G B u lle t L a y e rC G G a m e O v e r Sc e n eC G G a m e O v e r L a y e r 中國礦業(yè)大學 2020 屆本科生畢業(yè)設(shè)計(論文) 第 20 頁 mutiBulletsLayer MutiBulletsLayer* 雙排子彈層 controlLayer ControlLayer* 控制層 ufoLayer UFOLayer* 道具層 enemyLayer EnemyLayer* 敵機層 menuBigBoom CCMenu* 全屏炸彈菜單 bigBoomCountItem CCLabelBMFont* 全屏炸彈菜單項 score int 分數(shù) bigBoomCount int 全屏炸彈數(shù)量 level int 游戲難度 表 GameLayer 類的方法 方法 返回類型 說明 GameLayer() 構(gòu)造函數(shù) ~ GameLayer() 析構(gòu)函數(shù) CREATE_FUNC(GameLayer) 調(diào)用宏創(chuàng)建游戲?qū)? init() bool 初始化 backgroundMove(float dt) void 背景移動 ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent) bool 判斷手指是否觸摸到手機屏幕 ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent) void 若手指觸摸到手機屏幕且在飛機有效范圍移動飛機 ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent) void 手指拿開屏幕 registerWithTouchDispatcher() void 設(shè)置觸摸屏可用 update(float dt) void 每一幀所要完成的操作 menuBigBoomCallback(CCObject* pSender) void 全屏炸彈的操作 updateBigBoomItem(int bigBoomCount) void 更新全屏炸彈的數(shù)量 keyBackClicked() void 當玩家點擊返回鍵時結(jié)束游戲 getCurLevel() Level 獲取游戲難度 中國礦業(yè)大學 2020 屆本科生畢業(yè)設(shè)計(論文) 第 21 頁 ( 2) 敵機層類 EnemyLayer。如表 、表 所示。 表 EnemyLayer 類的屬性 屬性 類型 說明 ENEMY1_SCORE int 敵機一生命值 ENEMY2_SCORE int 敵機二生命值 ENEMY3_SCORE int 敵機三生命值 AIRBOSS1 int 闖關(guān)模式中 BOSS1 標記 AIRBOSS2 int 闖關(guān)模式中 BOSS2 標記 m_pAllEnemy1 CCArray* 管理敵機一的數(shù)組 m_pAllEnemy2 CCArray* 管理敵機二的數(shù)組 m_pAllEnemy3 CCArray* 管理敵機三的數(shù)組 m_pAllBoss1 CCArray* 管理 BOSS1 的數(shù)組 m_pAllBoss2 CCArray* 管理 BOSS2 的數(shù)組 sharedBoss EnemyLayer* 分配 BOSS enemy1SpriteFrame CCSpriteFrame* 存儲敵機一的紋理 enemy2SpriteFrame CCSpriteFrame* 存儲敵機二的紋理 enemy3SpriteFrame_1 CCSpriteFrame* 存儲敵機三的紋理一 enemy3SpriteFrame_2 CCSpriteFrame* 存儲敵機三的紋理二 enemyBoss1SpriteFrame CCSpriteFrame* 存儲 BOSS1 的紋理 enemyBoss2SpriteFrame CCSpriteFrame* 存儲 BOSS2 的紋理 表 EnemyLayer 類的方法 方法 返回類型 說明 EnemyLayer(void) 構(gòu)造函數(shù) ~EnemyLayer(void) 析構(gòu)函數(shù) create() EnemyLayer* 創(chuàng)建敵機層并返回地址給游戲場景 GameScene 使用 init() bool 初始化操作 addBoss1() void 加入 BOSS1 addBoss2() void 加入 BOSS2 addEnemy1(float dt) void 增加敵機 1 enemy1MoveFinished(CCNode* pSender) void 把敵機一從屏幕上移除 enemy1Blowup(Enemy* enemy1) void 敵機一的爆炸效果 removeEnemy1(CCNode* pTarget, void* data) void 把敵機一從敵機一管理數(shù)組中移除 removeAllEnemy1() void 移除當前幀所有敵機一