cocos2d-x學習筆記01——初識

     下學期要專心學習cocos2d-x開發cdio,還有unix socket,爲了不那麼累,先提前感悟感悟cocos2d-x。況且學習cocos2d-x,可以提高自己的面向對象封裝能力,學習良好的代碼風格,跨平臺處理,遊戲開發等。把這學期學的C++理論,比如虛函數,多繼承,單例模式,內存池,自定義命名空間等平常不太常用的都能在cocos2d-x裏隨處可見,完全告訴你它們怎麼整成一體,可見語言基礎的重要,這樣肯定可以加深C++理解和使用。不多說了,開始吧。


       1.首先C++不同於as3.0和java,它有頭文件,頭文件往往可以聲明多個類,在cocos2d-x裏,往往把多個類似的類聲明放同一個頭文件中,如CCDirector類聲明和CCDisplayLinkDirector,而CCDisplayLinkDirector繼承自CCDirector。這樣的代碼設計值得學習,因爲一個引擎類實在很多種,把類似的,或者說是有血緣關係的放在同一個文件中,方便查找。而且往往子類的聲明代碼已經很少了,因爲父類已經做了大部分的工作。同樣地,父類和子類的實現代碼也都放在了同一個cpp文件中,原因很簡單,假如把有血緣關係的這2個類放在不同地方去實現,那麼由於這2個類往往都要include很多相同的外部頭文件,造成預編譯展開時擴大了代碼的行數。如果放在同一個文件,則減少了一半的展開量,當然如果有#ifndef之類的則可避免展開,但仍然需要寫同樣的很多include的包含。另外,往往文件名.h和文件名.cpp和父類的名字一樣。


      2.從解決方案資源管理器結構學習引擎(2.0.4版),遊戲邏輯核心文件都在libcocosd工程內(實際對應於I:\cocos2d-2.0-x-2.0.4\cocos2d-2.0-x-2.0.4\cocos2dx文件夾內,裏面又有很多個子文件,用於分開不同用途的遊戲引擎邏輯帶按摩)。裏面有個include子文件夾,裏面有個cocos2d.h,要知道的是,C++裏的頭文件和源文件,並不是非得頭文件就得聲明類,源文件就是用於實現類,這是錯誤的。比如這個cocos2d.h,就是專門用於包含所有常用遊戲引擎邏輯的代碼的(把需要的都給include進來),這樣以後我們就可以直接包含cocos2d.h一個文件,而無需每次都包含那麼一堆邏輯的東西進我們的代碼了。cocos2d.cpp文件在include的上層目錄裏,並無太多實現,只有一個函數cocos2dVersion(),用於return "cocos2d-2.0-x-2.0.4";  的版本號。有的文件只是專門只用於定義宏,include下的ccConfig.h配置文件。都是爲了其他文件服務的。其實可以想象一下,遊戲編程裏常常獨立出一個頭文件來寫一些代碼,這些代碼是整個工程通用的,也就是說讓別的一個活多個文件都能共享它。


       3.學習Hello World!一種是通過引擎自帶的helloworld項目,另一種是自己用模板新建一個cocos2d-x項目。然後學習它。值得注意的是:cocos2d-x一般都用vs打開,每個工程(項目)裏面有個win32文件夾,裏面放了main.cpp和main.h.


看來,這裏這裏是windows系統上運行時的入口,平臺相關的代碼,而main.h裏可以看到它include<windows.h>。

這裏可以改變設置open gl 的視口大小。默認是480*320.

令人疑惑的是app這個自動變量並沒有app->run() ;   而是通過單例模式的CCApplication:sharedApplication()->run();於是我註釋掉AppDelegate app;試試看,居然崩潰了。難道CCApplication:sharedApplication()->run();這個調用可以取得app對象的地址????答案是是的。

經過不斷地f12進入定義,原來CCAplication的定義裏有個static CCApplication * sm_pSharedApplication;靜態成員變量。而CCApplication構造函數裏有個sm_pSharedApplication = this;語句。CCApplication:sharedApplication()函數正是返回sm_pSharedApplication。果然單例模式是很常用的。


       4.簡單運行看過HelloWorld項目後,看完後依然發現還是不知怎麼進一步學習的感覺,於是把TestCpp項目設置成啓動項目,然後運行它,發現裏面有菜單,體驗使用引擎支持的不同的功能,無疑是初學者最好的學習方式了,學習使用中熟悉引擎的實現。所以接下來就是學習TestCpp項目裏的源碼了。

從上到下分析:

main.h和main.cpp剛纔已經看過了,它是初始化app對象的地方,同時也是設置open gl 的視口的地方。

AppDelegate類是應用程序類,啓動類(呵呵,越來越面向對象的感覺了)

其中的AppDelegate::applicationDidFinishLaunching() 函數的部分實現即可看出總體邏輯了,如下:


pScene場景addChild(菜單層)。記住:pScene並沒有成爲AppDelegate類的成員變量,而是把它放到runWithScene函數裏,我估計這樣導演類就記下了這個場景在堆中的地址,而pDirector更無須成爲AppDelegate類的成員變量,因爲它是全局的單例對象。

TestController類是主菜單層(繼承自CLayer),包括了主菜單的控制,和啓動正式的測試效果場景。

TestScene類是基礎場景類(public繼承於CCScene),實現了一些基本功能,之後的場景類繼承與此,是爲了方便後面的演示例子使用。

tests.h文件裏是枚舉和數組的配合,枚舉做數組的下標,數組值是菜單選項顯示的字符串。

testResource.h則當做本TestCpp項目的配置文件,引入所有圖片的資源的相對路徑。
看下面的部分代碼,即可知道這個TestCpp的能演示不同功能的整體設計:

返回的pScene,其類型是正是TestScene類,基礎場景類。每個功能需要一個繼承自TestScene的場景類。

      5.從DrawPrimitivesTest 那個文件夾下的測試實例學習到:

基本圖元的繪製,是通過封裝open gl 的api。基本圖元繪製文件在libcocos2d項目的root目錄下CCDrawingPrimitives.h和CCDrawingPrimitives.cpp 裏。引擎的作者他們通過啓動libcocos2d項目先生成libcocos2d.lib和libcocos2d.dll到發佈版I:\cocos2d-2.0-x-2.0.4\cocos2d-2.0-x-2.0.4\Release.win32或者調試版I:\cocos2d-2.0-x-2.0.4\cocos2d-2.0-x-2.0.4\Debug.win32。。而剩下的各種無用的obj就放到I:\cocos2d-2.0-x-2.0.4\cocos2d-2.0-x-2.0.4\cocos2dx\proj.win32\Debug.win32或者I:\cocos2d-2.0-x-2.0.4\cocos2d-2.0-x-2.0.4\cocos2dx\proj.win32\Release.win32 。

至於其他os平臺, 只有對應os的開發工具的工程文件,而無obj文件,因爲並沒有把其他平臺編譯後的obj都放到目錄裏。作者只編譯了這個libcocos2d工程在windows上的。

DrawPrimitivesTest.cpp 裏可以用ccDrawLine() 等外部函數,是因爲DrawPrimitivesTest.cpp包含了DrawPrimitivesTest.h,DrawPrimitivesTest.h又去包含了"../testBasic.h",而testBasic.h又去包含了cocos2d.h

,好了,cocos2d.h,是一個大雜燴頭文件。幾乎把libcocos2d裏的所有文件從root到所有子文件夾裏的文件都給包含了。而CCDrawingPrimitives.h正是在root裏,即libcocos2d裏。

void CC_DLL ccDrawLine( const CCPoint& origin, const CCPoint& destination );

CC_DLL是個宏,#define CC_DLL     __declspec(dllimport)

也就是說告訴編譯器,這個函數的實現應當通過dll動態導入。。哪裏導入呢,自然是上面說的libcocos2d.dll咯,一來這樣就做到了模塊化,二來是隱藏圖元繪製的具體實現,只提供接口。但是作者還是給出了DrawPrimitivesTest.cpp 文件,其好處是讓我們可以看到它的具體實現,有朝一日讓用戶修改它,然後重新生成功能更多更好的dll,這就是開源嘛。


        6.節點CCNode 有成員函數OnEnter,OnExit,後續的子類都會繼承這一特性。它們分別是進入到舞臺時,和切換出舞臺時自動被調用的函數。


        7.場景CCScene

       在場景類的構造函數裏先調用基類場景的初始化,然後自己再初始化。假如不需要有自己的操作,那麼甚至可以無需聲明構造函數(直接交給父類了)。

       在場景的OnEnter裏先調用父類場景的OnEnter,再做一些本類定製的操作,比如往裏面加一個菜單。

場景是可以讓切換的,CCDirector隨叫隨到(通過CCDirector::sharedDirector()函數),你不叫,他不來,所以可以定義類似這樣的操作virtual void runThisTest(); 該函數裏面定義是:

    CCLayer* pLayer = new DrawPrimitivesTest();
    addChild(pLayer);
    pLayer->release();

    CCDirector::sharedDirector()->replaceScene(this);

       8.佈景層CCLayer

       往往我們繪畫操作,還有精靈佈置操作,可以在CCLayer類裏(或者我們自定義的繼承自CClayer的類)裏操作,把它們分別寫在一個繪畫函數裏,如繪畫操作virtual void draw();  精靈佈置操作 void centerSprites(unsigned int numberOfSprites);     之類的。當然佈景層也可以添加菜單CCMenu,菜單再添加各個菜單項CMenuItem。

        setTouchEnabled(true);可以控制響應是否觸屏事件。 默認是m_bIsTouchEnabled = false。這些和觸屏相關的代碼都實現在CCLayer類中,還有它的其中一個父類CCTouchDelegate裏。。。CCLayer對CCTouchDelegate改寫了不少觸屏相關的函數。

          9.學習一個新建工程,首先要理解新建工程的classes目錄裏只有那麼幾個頭文件和源文件,卻能運行用上引擎的所有功能,因爲這些文件包括了其他工程(用於生成dll,lib的工程)的頭文件,經過vs編譯器展開後,自然就相當於寫進了這些頭文件了。但是實現去哪找呢,所以新建工程的libs目錄會有如此多的dll(新建工程時從其他地方拷貝過來的),所以在libs裏找實現。這樣一個工程就串起來了,表面上那麼微小,就4個文件,但是卻能實現引擎所有功能。也就是說,如果自己寫一個工具類,比如SpriteHelper,最好放到所用工程裏去,如果放到外面的工程,那麼會找不到實現。要麼就寫一個函數好了,放棄寫工具類。

        10.差不多該動手實踐了,先實現一個 “人物走動+場景移動”的動畫。

參考地球人阻止不了程序猿學習了系列http://www.baidu.com/s?word=%E5%9C%B0%E7%90%83%E4%BA%BA%E5%B7%B1%E9%98%BB%E6%AD%A2%E4%B8%8D%E4%BA%86%E7%A8%8B%E5%BA%8F%E7%8C%BF%E4%BB%AC%E5%AD%A6%E4%B9%A0cocos2d-x%E4%BA%86&tn=sitehao123&ie=utf-8

老G的經典博客http://4137613.blog.51cto.com/4127613/759610

        



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