第一章 cocos基礎介紹

1.1 歷史介紹

Ricardo2008年的時候發佈cocos2d-iPhone的引擎。cocos2d-x是由王哲在2010年引進的,它的前身是cocos-ios,但是不兼容其他的平臺。Cocos在國內遊戲份額是70%,國外20%cocos向下兼容一直做得不好,即使兩個版本發佈的很近,也有很多的細節是不可以在低版本上運行的。

由於遊戲的生命週期很短,開發週期也很短,對代碼的要求不高,有更多寫代碼的機會,所以適合新手進入。遊戲需要建立面向對象的概念,Cocos2d-x是基於C++寫的,裏面都是一堆的類庫。

爲何都是類庫,有的稱爲庫,有的稱爲框架,有的稱爲引擎?因爲C語言庫,只是使用庫中的函數等等;但是qt框架,可以繼承類庫,在類的基礎上增加一些特殊的功能;cocos2d-x遊戲引擎是按照遊戲設計的要求順序的調用這些資源,比如定時器定時發送圖片。cocos2dx封裝了OpenGL的圖形接口,本質是一個圖形引擎。遊戲要具有簡單,耐玩和虐心等特點。

1.2 開發環境搭建

Windows平臺下,直接將壓縮包解壓就好,解壓之後將_MACOSX刪除,需要安裝pathon(默認安裝就ok)纔可以創建工程。創建工程需要從終端運行一個的腳本,路徑是cocos2d-x-2.2.3\tools\project-creator\

然後create_project.py -project  -package  -language  。包名稱對於Android來說有用,Android下面project沒有用,創建之後生成一個項目,項目下面的classes目錄存儲的是和平臺無關的代碼。之後再vs裏面打開這個項目,編譯這個項目,第一次花費一段時間,編譯之後就可以運行了。

1.3 helloWorld代碼分析

生成的win32代碼是用WindowsAPI寫的,main函數封裝爲_tWinMainAppDelegate定義代理對象(應用程序app),CCEGLView 創建窗口,設置窗 口的屬性,之後執行應用程序的runrun不是用app調用的,CCApplication::sharedApplication()->run()。貌似沒有使用定義的代理對象,其實在定義代理對象的時候,調用基類CCApplication的構造函數,在基類中定義了一個靜態指針變量(因爲是單例),在構造函數中用這個成員變量保存this指針,然後調用成員函數sharedApplication返回那個變量,也就是this指針。在run中調用正在執行的那個對象的虛方法applicationDidFinishLaunching,其實遊戲真正是從這裏開始的。這裏用到了代理AppDelegate,代理類是private的繼承於AppAplication,這樣代理不會知道太多的被代理的信息,而CCApplication繼承於CCApplicationProtocolAppAplication中放入了很多跨平臺的代碼,AppDelegate實現CCApplicationProtocol中定義的虛接口。在cocos中經常會用到代理。

1.4 遊戲架構

director->scene->layer->spritemenulable.

導演類CCDirector ,推動遊戲的發展,切換場景,運行場景,一個導演同一時間只能運行一個場景。

場景CCScene抽象一個獨立遊戲邏輯,每一個關卡爲一個場景,就像話劇用的畫幕一樣,也是渲染樹的根節點。

CCLayer 將精靈分類,劃分層次,舞臺有多層畫布。在2.x中,層還有一個很重要的功能,接收觸摸消息,只有它可以接收觸摸,但是3.0的話就有很多可以接收摸。

精靈CCSprite抽象了一個可見的遊戲元素,一般是圖片。

cocos的類構造和初始化是用create函數,沒有在構造函數和析構函數中寫代碼。cocos中定義一個宏函數CREATE_FUNCclass),是爲了簡化代碼,其實裏面調用了initautorelease函數。將來寫類的時候,需要包含cocos2d.h頭文件,使用命名空間USING_NS_CC,添加init函數,在init中調用父類中的init,一般都是返回true。在類定義時候添加CREATE_FUNCcreate函數用到了工廠模式,只能用於不帶參數的create。在layer中定義scene函數,在這個函數中創建一個場景,然後創建層,之後加入到場景中。Cocos創建對象一般不使用new,而是使用create方法。Cocos的二段初始化,init是業務相關的初始化,構造函數中語言層次的初始化(基本不使用)。

1.5 錨點

就像是船的錨,掛相片的點一樣。cocos的原點座標在左下角。精靈的錨點默認在中心,setAnchorPoint可以修改錨點。錨點影響放置位置,影響縮放(以錨點爲基點,四周進行縮放),影響旋轉(以中心爲圓心旋轉)。有一方法可以忽略錨點ignoreAnchorPointForPosition,忽略之後錨點在(0,0)點,層默認是忽略錨點的。不糊了錨點是中心點。錨點的座標是使用比例。使用getPosition獲取的點就是錨點。

背景是有範圍的地方,精靈也是有範圍的,錨點使用的是相對座標,代表百分比。每種節點的錨點的默認位置是不一樣的。精靈的錨點在中間,層的錨點在左下角,旋轉的時候利用錨點來轉,設在方便旋轉的地方。CCLable錨點在中間,和文字的對齊有關,在左邊文字左對齊。

1.6 精靈的創建-衆生皆精靈

1.6.1 創建

(1)圖片文件:直接使用create,創建的時候可以加參數CCRectMake(),截取圖片的大小。

(2)紋理:在內存中的圖片,相同圖片佔用一個內存,可以節約內存,但是在3.x中,通過圖片創建精靈,也不會浪費內存。紋理創建需要CCTextureCache(單例),使用的是緩衝,這個時候會用到CCTexture2D,之後使用創建createWithTexture

(3)幀:提取圖片中的一部分,類是CCSpriteFrame。可以通過紋理或者圖片來創建幀。使用createWithSpriteFramecreateWithSpriteFrameName創建,CCSpriteFrameCache來加載圖片。當導入精靈的圖片路徑錯誤的時候,會出現一個空白區域。TexturePackerGUI工具會生成plite文件

1.6.2 動作

定義一個CCMoveby對象,然後讓精靈調用runAction方法就動起來了。類CCMoveto是絕對路徑,CCMoveby是相對路徑。還有CCJumpByCCFadeIn等等。

1.6.3 動畫

每隔一段時間顯示一副圖片,使用類CCAnimation,使用之前需要定義一個CCArray,之後用路徑/文件名構造一個CCSpriteFrame,然後添加到數組中。創建CCAnimation的時候不可以使用create,會造成內存訪問出錯,需要createWithSpriteFrame。之後通過CCAnimation構造一個CCAnimate,最後調用runAction就是一幅幅的畫面了。爲了看到效果增加一個CCRepeatForever,可以一直循環顯示。

1.6.4 骨骼動畫

精靈套着精靈,小精靈也在執行動作,類同人體的骨骼。

1.6.5批處理精靈

相同的精靈加載到一份到內存,就是一個精靈,節約內存,比如子彈的加載,因爲如果加載過多的話,渲染很慢。CCSpriteBatchNode來創建批處理精靈,宏CCRANDOM_0_1產生隨機數[0,1]之間。

1.6.6粒子效果

很多精靈按照某種軌跡運行。CCParticleFire火的粒子效果,CCParticalGalaxy銀河效果,粒子有好多參數需要設置,也可以定義自己的粒子,調效果的時候很難,可以使用開源庫來實現。可以使用粒子編輯器生成plite文件。CCParticleSyatemQuad來加載plite文件。

通常對於多個圖片,一般是將多個圖片放到一個圖片中,需要提供一個.plist格式的文件來切割,否則需要自己來切割,plistXML文件,對應一個字典。這樣的話,就需要將合圖的幀加載到內存中,用到CCSpriteFrameCache,然後再把緩衝中的幀找出來放到數組中,構造CCSpriteFrame的時候,使用spriteFrameByName

緩衝:可以理解爲道具,放到內存中。例如紋理緩衝(是單例,只加載一次)、幀緩衝(單例)。舞臺、導演、CCApplication也都是單例。所以添加的主要就是精靈。 

1.7 遊戲優化

FPS:frame pre second左下角顯示狀態,電影一秒24幀。當在場景中添加上萬個sprite的時候,遊戲運行很卡。Cocos基本的數據結構是渲染樹,就是每一幀都會遍歷這個樹,底層使用OpenGL繪製場景,一般是用framebuf保存像素點,cocosOpenGL的基礎上又封裝了一層接口。CCNode 是所有Cocos類的基類,addChild就是向樹中添加子節點。優化的原理是,同樣的圖片使用CCBatchNode渲染一次,然後將圖片貼到那個node上,生成一個精靈。多張不同的圖片,使用TexturePackage生成plist格式文件,然後使用CCSpriteFrameCache,然後將那副大圖片渲染,之後使用就一樣了。

1.8座標體系

設置顏色CCLayerColorCCLayerGradient(顏色漸變)。座標體系代表的是一個標準。OpenGL的座標體系的原點是左下角,屏幕座標體系原點是左上角。GetLocation獲取的是世界座標,GetLocationInView獲取的是本地座標,使用ConverToUIconvertToGL可以實現兩者的轉換。

世界座標是絕對座標;本地座標是以父類爲基點定義的座標,加載的時候是本地座標,窗口重合的時候兩種座標是一樣的。convertToNodeSpace轉換爲本地座標,轉換世界座標的時候需要使用父類convertToWorldSpace。使用本地座標其實就是遞歸的過程,讓遊戲更好理解,寫代碼不用更多的考慮邏輯。

座標系統,每一個節點都有自己的座標體系,窗口的原點是左下角,layer默認和窗口是一樣大的。座標的轉換,世界座標體系和節點座標體系。spriteboundingBox返回我們可以看到的外切矩形,然後觀察是否點擊在這個矩形中。轉換的時候node->convertToNodeSpace將世界座標轉換爲節點座標,轉換之前需要獲取這個節點的父節點,然後纔可以根據這個父節點進行節點的座標轉換。

1.9 CCNode類詳解

CCNode是遊戲中最重要的對象,在 cocos2dx ,任何可見的或不可見的遊戲對象都是一個節點,節點有以下特點:是一個容器,可以包含任意多個其它節點;可以執行一個行爲(CCAction);可以執行一定時的任務回調;擁有座標變換(transform)信息,如 postion,scale,rotation 等;由於一個節點可以添加任意個子節點,所有的節點 組成一個樹狀結構,完成了渲染功能,一個節點只能擁有一個父節點。

CCNode的父節點是CCObjectcocos所有類的基類。CCObject和內存管理、回調函數有關。

CCNode有一系列的成員函數:setZOrder設置層次關係,setScale設置縮放,setSkewX設置扭曲,扭曲90度就看不見了,setContentSize設置內容的大小,內容不會因爲扭曲,縮放而改變,boundingBox一旦形狀發生內容就變化,setVisible設置是否可見,setRotation旋轉,旋轉90度就看不見了,180°什麼也不發生,旋轉和扭曲差不多;setOrderOfArrival一般系統來管理,setGLServerStatus設置GL的參數,addChild的時候可以設置一個tag,以後方便查找,setGrid設置格子效果,setShadeProgramOpenGL的範圍;getCamera獲取視角;isRuning查看是否運行起來;onEnter場景的初始化;onExit場景結束;transform變換;座標的轉換函數。

1.10 人機交互

觸摸(CCTouch)開始時調用setTouchEnable打開觸摸開關,然後設置setTouchMode(單點或者多點)。在類中需要添加虛函數ccTouchBegan,參數決定消息是否時候往下傳遞;ccTouchEnded觸摸結束的時候調用;ccTouchMoved移動的時候調用,有幀循環累積效應,只要按下就一直調用,調用的頻率是幀的間隔,使用CCLog打印信息,也可以實現拖動;ccTouchCanclled一般是電話打入的時候導致觸摸終止。這幾個函數的第二個參數是用在蘋果上的。getLocation是獲取座標點,getDelta獲取差值,就是觸摸移動相鄰點的差值。拖着飛機跑,在ccTouchMoved中處理,當點擊的點位於飛機的boundingBox時候就重新設置座標(當前座標+getDelta),讓飛機跑不出去,設置飛機的錨點在窗口的一定範圍內。boundingBox是輪廓(縮放)的大小,contentSize表示真實大小,碰撞檢測的時候使用boundingBox

觸摸有優先級(默認是0,數字越小優先級越高),優先級相同的層觸摸回調都會被回調,哪個先回調不清楚,一般是在上層的調用;如果有優先級高的層截獲消息(並且優先級高的層ccTouchBegan返回true),優先級低的不會獲得到消息。單點觸控的多點觸控,因爲調用的是相同的move函數,getID來獲取是哪一個點觸控。多點觸控:實現兩隻手的縮放功能,使用的函數也不一樣,用CCSet集合來保存這些點。然後使用迭代器來訪問,用的場景比較少。一個都不能死就是多點觸控。

觸摸使用了消息分發原理,觸摸將消息壓到一個棧中,然後將消息分給相應的進程,然後相應的進程來處理。同樣也使用了代理。addTargetedDelegate的第三個參數用於是否吞噬消息,接收觸摸的先後順序是和渲染的順序是不一樣的。 

鍵盤處理:主要指Android的返回鍵和菜單鍵,keyBackClickedkeyMenuClicked

搖一搖:setAccelerometerEnable重力感應,調用didAccelerate

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