知易遊戲開發教程cocos2d-x移植版002(上)

原文:http://www.cnblogs.com/cocos2d-x/archive/2012/02/29/2373598.html


基本概念

爲了全面掌握cocos2d-x的開發,我們首先需要了解該引擎的幾個基本概念。實際上,這些基本概念是所有遊戲開發所必須的,並非cocos2d-x專有。任何遊戲都是通過這些概念所針對的對象組建起來的,遊戲的複雜程度決定了這些對象實現的複雜程度。

場景(CCScene)

我們假設一個只有兩關的遊戲:第一關(2個小鬼,1個小BOSS);第二關(5個小鬼,1個大BOSS)。通常情況下,我們會這樣設計整個遊戲的流程(workflow):

開場動畫,可以有幾個目的:
簡單介紹一下游戲操作
講述故事背景
公司或者工作室動畫LOGO

進入主菜單後可以引導用戶:
開始新遊戲
讀取進度
設置遊戲 聲音,文字,遊戲內容設置……
高分排名 通常都是列表,按分數排列。
幫助 操作簡介
退出

接下來,玩家可以有多種選擇,無論開始新遊戲還是讀取進度,遊戲都會進入到預設關卡。遊戲過程中,第一關勝利就進入第二關,第二關勝利則進入結尾的勝利畫面(播放視頻或者在背景圖上顯示文字),確認後進入排名畫面看看本次得了多少分。如果失敗了,那就會進入失敗結束的畫面,確定後跳轉到主菜單,重新開始。
可以看出,玩家玩遊戲的過程就是在我們預設的畫面之間進行跳轉,根據玩家操作的結果(選擇菜單項、消滅敵人或者被敵人殺死)跳轉到不同的畫面。
這些構成遊戲流程的畫面就是我們所說的場景,圖中用黑色線框表示的部分。顯然,不同的場景提供不同的操作,大致可以分爲以下幾類場景:

展示類場景:播放視頻或簡單的在圖像上輸出文字,來實現遊戲的開場介紹、勝利/失敗提示、幫助說明等。
選項類場景:主菜單、遊戲參數設置等。
遊戲場景:這是遊戲的主要內容,除了這個場景之外,其他類別的場景基本都是通用框架實現的。

那麼不同的場景是如何實現不同功能的呢?每個場景都是通過不同的層的疊加和組合來實現不同的功能的。因此,通常一個場景是由一個或多個層組成的。

層(CCLayer)

層是我們寫遊戲的重點,我們99%以上的時間是在層上實現我們的遊戲內容。如下圖所示,一個簡單的主菜單畫面是由3個層疊加實現的:

細心的讀者可能已經注意到,爲了讓不同的層可以組合產生統一的效果,這些層基本上都是透明或者半透明的。(否則我們就只能看到最上面的一個層了)
層的疊加是有順序的,如圖所示,編號爲1的背景層在最下層,2號在中間,3號在最上面。cocos2d-x也是按照這個次序來疊加畫面的,處於最上層的不透明的部分會將下面的內容覆蓋。
這個次序同樣用於編程模型中的事件響應機制。即編號3的層最先接收到系統事件(手指單擊屏幕事件),然後是編號2,最後是編號1的層。在事件的傳遞過程中,如果有一個層處理了該事件,那麼排在後面的層將不再接收到該事件。
我們可以簡單地把層理解爲我們在Windows編程中的窗口(hWnd或者WinForm,還有Delphi中的TForm)。
爲了方便大家進行遊戲開發,cocos2d-x從技術實現角度提供一些公用層:處理菜單用的菜單層,處理顏色顯示的顏色層等。
每一層又可以包含各式各樣的內容要素:文本、鏈接、精靈、地圖等等。其中,精靈是遊戲的重點。

精靈(CCSprite)

精靈是整個遊戲開發處理的主要對象。敵方的飛機、坦克是系統控制的精靈,玩家控制的我方飛機也是精靈,甚至隨機飛過的一片雲、一隻鳥都是精靈。
從技術上講,精靈就是一個可以不斷變化的圖片。這些變化包括:位移、旋轉、縮放以及圖片幀的切換。
所謂遊戲,就是玩家操作一個或多個精靈與系統控制的精靈進行互動:近身肉搏、遠程射擊、對話等等。

導演(CCDirector)

我們已經大概瞭解了一個遊戲的整體架構,不同的場景由不同的層組成,每個層又包含精靈在上面運動。玩家玩遊戲的過程就是在操作層上的精靈或者菜單項,從而在不同的場景中切換。
好了,有些OO編程基礎的讀者已經猜到導演對象的作用了。是的,按照面向對象的設計原則和反向依賴原則:精靈不應該依賴層,層不應該依賴場景,場景不應該依賴整個流程。導演對象就是整個流程的代表,他負責遊戲過程中的場景切換。
導演通常只有一個,因此這個對象是單例(singleton)。cocos2d-x框架已經預定義了該實例,無需額外創建,我們直接使用就可以。
導演對象接收層對象/場景對象的請求,按照預先設計好的流程來切換場景。至此,我們可以勾勒出一個遊戲的整體框架和cocos2d-x關鍵對象與之的對應關係:

需要特別說明的是:任何時間,只有一個CCScene對象實例處於激活狀態。該對象可以作爲當前遊戲內容的對象的容器,對於菜單對象來說,通常屬於當前場景的主層。以上就是一個遊戲的主要架構。
實際上,針對每一個遊戲場景而言,不同場景(關卡)、每一個層(靜態、動態)、每一個對象(敵人、我方、中立方)其實都很複雜。萬里長征,這才第一步呢。

cocos2d-x的實現類

下面,我們首先逐一介紹cocos2d-x對應上述基本概念的對象,以及他們之間的程序關聯。

CCDirector(導演類)

CCDirector對象的作用類似於Windows編程中的主窗口對象(不同之處在於該對象並不可見),它負責創建、管理應用程序/遊戲的主窗口,在特定的條件下顯示某個場景。

針對CCDirector的調用代碼(下面這段代碼是主程序啓動時的標準步驟,在AppDelegate的applicationDidFinishLaunching成員函數內實現):

複製代碼
 1 bool AppDelegate::applicationDidFinishLaunching()
2 {
3 // initialize director
4 CCDirector *pDirector = CCDirector::sharedDirector();
5 pDirector->setOpenGLView(&CCEGLView::sharedOpenGLView());
6
7 // enable High Resource Mode(2x, such as iphone4) and maintains low resource on other devices.
8 // pDirector->enableRetinaDisplay(true);
9
10 // turn on display FPS
11 pDirector->setDisplayFPS(true);
12
13 // set FPS. the default value is 1.0/60 if you don't call this
14 pDirector->setAnimationInterval(1.0 / 60);
15
16 // create a scene. it's an autorelease object
17 CCScene *pScene = HelloWorld::scene();
18
19 // run
20 pDirector->runWithScene(pScene);
21 return true;
22 }
複製代碼

顯然,我們看到可以通過CCDirector對象完成以下兩大類任務:

設置主程序窗口的顯示屬性。

依次設定了以下內容:
1.初始化CCDirector對象。
2.設置是否開啓Retina顯示模式
3.設置是否顯示FPS。
4.設置遊戲畫面每秒顯示的幀數,默認是60幀。

管理、顯示場景。

CCDirector對象一次只能顯示一個場景。爲了便於管理場景對象,CCDirector對象有3個屬性與場景有關(參見CCDirector.h):

複製代碼
1     /* 當前顯示的場景 */
2 CCScene *m_pRunningScene;
3
4 /* 下一個將要顯示的場景 */
5 CCScene *m_pNextScene;
6
7 /* 待執行的場景隊列 */
8 CCMutableArray<CCScene*> *m_pobScenesStack;
複製代碼

同時,CCDirector對象管理場景的方法主要有以下幾個:

複製代碼
 1     /* 用來顯示主程序啓動後的第一個場景,如果已存在運行的場景,則不可使用 */
2 void runWithScene(CCScene *pScene);
3
4 /* 掛起當前正在運行的場景,壓入待執行場景隊列,並開始執行新的場景 */
5 void pushScene(CCScene *pScene);
6
7 /* 從待執行場景隊列中彈出一個場景,並以此取代當前運行中的場景。
8 如果待執行場景隊列已爲空,那麼程序將終止運行。 */
9 void popScene(void);
10
11 /* 直接用一個場景取代當前場景,這是最常用的一個方法。 */
12 void replaceScene(CCScene *pScene);
13
14 /* 結束運行,釋放當前場景。 */
15 void end(void);
16
17 /* 暫停場景運行。畫面還存在,但時間任務停止。 */
18 void pause(void);
19
20 /* 恢復場景運行。 */
21 void resume(void);
複製代碼

CCScene(場景類)

場景對象當前比較簡單,當前版本的cocos2d-x(1.0.1)基本上沒有附加任何特殊功能,基本上可以看作是層(CCLayer)對象的一個容器。有些例子沒有使用CCScene來作爲場景切換,而是直接使用層的變換,筆者建議大家不要這樣。CCScene的作用十分重要,如果要爲場景切換增加動畫效果,CCScene是必不可少的。

CCLayer(層類)

CCLayer的主要功能在於:
1)接收觸摸(touch)操作輸入。
2)接收動力感知(Accelerometer)輸入。

除此之外,CCLayer對象本身沒有提供更多的功能。關於CCLayer對象與TouchDispatcher的相互作用關係,我們放在以後的章節重點介紹。

cocos2d-x爲了方便大家使用,直接提供了以下4個層:

CCLayerColor(顏色層)

這是一個透明的,可以按照RGB設置填充顏色的層。可以通過setContentSize設置層的大小,改變顏色塊的尺寸。圖中紅色部分就是一個CCLayerColor的實例。

層也支持動作,可以變色、淡入淡出和混合。

CCLayerGradient(漸變層)

CCLayerGradient是CCLayerColor的子類,他可以在背景上繪製漸變色。

CCMenu(菜單層)

這是一個以CCMenu對象爲集合類,CCMenuItem類實例組成各式各樣按鈕的菜單管理選擇畫面層。(注意:該層中的實例必須是CCMenuItem類或其子類的實例)
CCMenu類提供的方法主要是用來按照橫向、豎向或者多行列排序展示CCMenuItem類實例的。
爲了實現不同的按鈕效果,系統提供了多種類型的CCMenuItem,但每個按鈕都有三中基本狀態:正常、選中、禁用。
下面,我們逐一介紹一下CCMenuItem類系:
CCMenuItem
CCMenuItem是基礎類,不要直接使用該類。作爲所有菜單項的父類,CCMenuItem主要完成以下兩個任務:
1.設置按鈕的狀態。
2.負責處理回調函數(當按鈕被單擊後,需要調用的函數叫做回調函數)。具體說就是內置一個NSInvocation *invocation來統一實現回調函數的激活。(這段以後深入研究下再修正吧,在cocos2d-x裏肯定不是)

CCMenuItemLabel
CCMenuItemLabel能將任何支持CCLabelProtocol協議的CCNode轉變成一個菜單項,並增加選中時的放大效果。

CCMenuItemAtlasFont/CCMenuItemFont
CCMenuItemAtlasFont和CCMenuItemFont都繼承自CCMenuItemLabel,他們能根據你提供的字符串生成標籤,並以此創建菜單項。他們的區別是CCMenuItemAtlasFont使用圖片集,CCMenuItemFont使用預設字體。

CCMenuItemSprite
CCMenuItemSprite內置3個支持CCRGBAProtocol協議的CCNode對象,表示正常、選中、禁用三個狀態的圖像。

CCMenuItemImage
CCMenuItemImage從CCMenuItemSprite派生而來,你只需提供圖片的名字,創建CCSprite對象的過程由框架自動完成。

CCMenuItemToggle
內部有一個CCMenuItem數組,負責展示不同的狀態,進而達到狀態切換的效果。

CCLayerMultiplex(複合層)

這是可以包含多個層的複合層,將來再專門介紹。

CCSprite(精靈類)

精靈是遊戲中的主要靜態、動態目標(敵方怪物、我方操作對象)。具體講就是一個獨立的圖像塊,通常情況下他是運動的(Action):位移、旋轉、縮放、運動——連續漸變圖像形成的運動效果。我們可以直接通過設定精靈的屬性讓他運動,也可以通過動作(Action)來達到同樣的目的。

在cocos2d-x中精靈由CCSprite類實現。精靈允許包含子對象,當父對象變化的時候,子對象會跟着變化。
由於遊戲中95%以上的內容都是精靈類實現模擬的,因此如何提高精靈類的執行效率就是一個十分關鍵的問題。

1)緩存圖像內容,減少相同內容文件的讀取次數。
通過CCTextureCache類,cocos2d-x庫按照文件名爲主鍵索引全部運行時讀取的圖片文件。當文件名一樣時,直接返回內存中的圖片而不再讀取文件。
所有與圖片文件有關的實現在底層統一調用CCTextureCache類的單例對象,保證最少的系統IO操作,提高程序運行效率。
2)批量提交繪畫,減少OpenGL函數的調用次數。
通過CCSpriteBatchNode類,cocos2d-x庫將所有CCSpriteBatchNode類對象所屬的子CCSprite對象一次提交給OpenGL輸出。
還有一個叫CCSpriteFrameCache的類,用於管理動畫效果的全部幀圖像。該類的實現也調用了CCTextureCache類對象。

小結

至此,讀者對於cocos2d-x的幾個關鍵概念以及對應的實現類有了整體的把握。CCScene、CCLayer、CCSprite類都是從CCNode類派生的,從類對象角度上來說他們是一樣的,可以互相從屬。從遊戲設計的角度,他們完成的功能則互不相同,各有重點:

使用CCScene是爲了:
1)作爲某個場景的總體容器對象,將所有的內容對象(菜單、狀態、遊戲角色、NPC)包含在內,層疊關係通過CCNode的addChild的zOrder決定。
2)實現場景切換的特殊效果。因爲所有的場景切換特效都是從CCScene的子類CCTransitionScene派生的。

使用CCLayer是爲了處理輸入問題:
1)觸摸事件處理
2)動力感知處理

使用CCSprite是爲了顯示各式各樣的精靈,展示遊戲內容。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章