cocos2dx要點總結

原文地址:http://www.cnblogs.com/xxiaoye/p/3950185.html

 

1、Cocos2d-x是怎樣實現跨平臺?

  AppDelegate 作爲跨平臺程序入口,在這之上做了另一層的封裝,封裝了不同平臺的不同實現。比如我們通常認爲一個程序是由 main 函數開始運行,那我們就去找尋,我們看到了在 proj.linux 目錄下存在 main.cpp 文件。在main.cpp 中 CCApplication::sharedApplication()–>run(); 這一句看起,這一句標誌着, cocos2d-x 程序正式開始運行,現在定位到 sharedApplication() 方法的實現,在CCAplication類中我們可以看到從 sharedApplication() 方法,在調用 run() 方法,在這之前,我們需要調用到它的構造函數,否則不能運行,這就是爲什麼在 CCApplication::sharedApplication()–>run(); 之前,我們首先有語句 AppDelegate app; 而創建 AppDelegate 變量的原因是 AppDelegate 是 CCApplication 的子類,在創建子類對象的時候,調用其構造函數的同時,父類構造函數也會執行,然後就將 AppDelegate 的對象賦給了 CCApplication 的靜態變量,而在 AppDelegate 之中我們實現了 applicationDidFinishLaunching方法,所以在 CCApplication 中 run 方法的開始處調用的就是 AppDelegate 之中的實現。而我們在此方法中我們初始化了一些變量,創建了第一個 CCScene 場景等,之後的控制權,便全權交給了CCDirector::sharedDirector()–>mainLoop(); 方法了。

在cocos2d-x的文件夾下,有一個platform文件夾,裏面存放了跨平臺的封裝接口。當前目錄下有CCApplicationProtocol.h頭文件,子目錄有win32,Android,IOS三個文件夾,裏面分別存放跨平臺需要的函數,其中包括CCApplication。而AppDelegate 類則是繼承自CCApplicationCCApplication又繼承自

CCApplicationProtocol。在CCApplicationProtocol中定義了applicationDidFinishLaunching虛方法,由CCApplication 繼承, AppDelegate 實現的。以此實現了跨平臺。

java輸入→Jni→c++輸入→c++處理(API實現)→c++輸出→Jni→java輸出

而在Android 平臺啓動 cocos2d-x程序。可以找到Android 平臺與上面等價的入口點,proj.android/jni/hellocpp/main.cpp。在main.cpp文件裏面並沒有看到 main 函數,這是由於不同的平臺封裝所以有着不同的實現,在 Android 平臺,默認是使用 Java 開發,可以使用 Java 通過 Jni 調用 C++ 程序,而這裏也正式如此。我們暫且只需知道,由 Android 啓動一個應用,通過各種峯迴路轉,最終執行到了 Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit 函數,由此,變開始了我們 cocos2d-x Android 平臺的程序入口處。,其它平臺程序的入口必然包含着其它平臺的不同封裝實現 。

參考:http://blog.leafsoar.com/archives/2013/05-05.html

 

2.cocos2d-x 程序的結束流程?

  程序運行時期,由 mainLoop 方法維持運行着遊戲之內的各個邏輯,當在彈出最後一個場景,或者直接調用 CCDirector::end(); 方法後,觸發遊戲的清理工作,執行 purgeDirector 方法,從而結束了 CCEGLView(不同平臺不同封裝,PC使用OpenGl封裝,移動終端封裝的爲 OpenGl ES) 的運行,調用其 end() 方法,從而直接執行 exit(0); 退出程序進程,從而結束了整個程序的運行。(Android 平臺的 end() 方法內部通過Jni 方法 terminateProcessJNI(); 調用 Java 實現的功能,其功能一樣,直接結束了當前運行的進程)

 

3、cocos2d-x內存管理?

  目前主要有兩種實現智能管理內存的技術,一種是引用計數,一種是垃圾回收。Cocos2d-x採用的是引用計數機制。爲此實現了自己的根類CCObject,每個對象都包含了一個用來控制生命週期的引用計數器,就是CCObject的成員變量m_uReference。

  對於m_uReference,構造函數創建時對該引用計數器賦值爲1(自引用,並沒有實際的使用),當需要引用對象時調用retain()方法增1,當引用結束的時候調用release()方法減一。而autorelease()方法(create工廠方法迫切需要)會將對象放入自動回收池(CCAutoReleasePool)實現靈活的垃圾回收。當每一幀結束的時候,自動回收池中的對象都會被執行一次release()

autorelease()方法裏面代碼將該對象添加到自動釋放池中:CCPoolManager::sharedPoolManager()->addObject(this);

 create方法將對象加入內存池後,對象的所有權已經屬於內存池了, 我們返回的指針其實是沒有所有權的.  主循環mainloop幹了件非常重要的事情, 那就是pop最上層的autorelease pool, 此時是在release全部僅僅由此內存池所有的對象. 就是依靠這樣的原理, 我們可以放心的將對象放在autorelease pool中, 知道在需要的時候, 這個對象就能正確的釋放, 同時只要有上層的父節點通過addChild對遊戲對象有了所有權以後, 又能正確的保證該對象不會被刪除.

 

如果在一幀之內生成了大量的autorelease對象,將會導致回收池性能下降。因此,在生成autorelease對象密集的區域(通常循環中)的前後,我們最好可以手動創建並釋放一個回收池。CCAut0m_pReleasePoolStack

 CCPoolManager::sharePoolManage()->push()  

 for(){}

   CCPoolManager::sharePoolManage()->pop()

CCAutoreleasePool

 

4、Cocos2d-x中如何處理內存泄露,處理內存泄露有哪些檢測工具,如何針對crash後的遊戲聲稱報告發送回服務器

 VS下內存泄露檢測工具Visual Leak Detector:教程http://blog.csdn.net/onerain88/article/details/8574938

xcode ios下內存泄露使用Instruments來查找程序中的內存泄露:http://blog.csdn.net/totogo2010/article/details/8233565


3、Cocos2d-x 3版本的特性?

3.0版 1、將有一個新的渲染系統。

    2、支持多線程,並且易於支持新的GPU平臺。

         3、更快,更高效也更易於維護的Label文本繪製。

     4、擁有一個新的,統一的事件派發器。

     5、減少對objectc的兼容考慮,更多考慮對C++開發者更友好。用C++最佳實踐,替換掉了objectc模式。移除匈牙利命名法。

     6、menu和action可以接受Lambda表達式作爲輸入

   cocos2d之父加盟觸控視頻講解3.0新特性:http://v.youku.com/v_show/id_XNjM0OTY1NzEy.html


5、C++ 11的特性?

    參考文章:C++11 語法記錄    Cocos2dx3.2學習準備(一):C++11新特性  Cocos2d-x 3.1.1 學習日誌6--30分鐘瞭解C++11新特性

 

6、闡述cocos2d-x 中CCScene CCLayer CCSprite CCNodee

  CCNode是CCScene,CCLayer,CCSprite的基類,是一個抽象類,沒有可視化的表現形式。是爲了方便構造渲染樹而定義的一個類。CCScence是場景類,裏面可以放CCLayer和CCSprite。一個app裏面可以放多個scence,但是同一時刻只有一個scence被激活。CCLayer是層類,裏面可以放CCSprite。CCSprite是最小的精靈單元。


7、說一下CCAction和CCActionMessager

CCAction是動作的基類,所有的動作都派生自這個類,它創建的一個對象代表一個動作,動作作用於CCNode。主要使用CCFiniteTimeAction有限次動作執行,就是按時間順序執行一系列動作,執行完後動作結束;CCFiniteTimeAction 繼承自CCAction。CCFiniteTimeAction又分爲CCActionInstanse(瞬時動作的基類)和CCActionInterval(延時動作的基類)。

CCActionInstanse:沒什麼特別,跟CCActionInterval主要區別是沒有執行過程,動作瞬間就執行完成了;CCActionInterval:執行需要一定的時間(或者說一個過程)。我們用的最多的就是延時動作,下面對它進行單獨介紹。

 

     CCActionMessage是管理所有Action的單例,一般情況下並不直接使用這個單例,而是使用CCNode的接口,(CCNiode*)->runaction()

而在runaction函數裏,通過CCActionMessage動作管理類將新的CCAction和對應的目標節點添加到其管理的動作表中。

 m_pActionManager->addAction(action, this, !m_bIsRunning); 再調用 action->startWithTarget(pTarget);

CCActionMessage的初始化在CCDirector的初始化裏執行。在裏面通過CCSchedule定時調度器爲CCActionMessage註冊了一個定期更新任務。所以

每一幀刷新更新時都會觸發CCActionMessage的update方法,系統都會遍歷動作表中每一個動作,並調用該動作的setup方法。

 

 但是假如你想操作的目標不是CCNode的子類或者你想暫停/恢復行動就要使用到CCActionMessager

 

7、你常用的cocos2d-x工具有哪些?

  TiledMap (地圖編輯器)ParticleEditor(粒子編輯器)cocosBuilder(可視化編輯)Texture Packer(圖片組合工具) plistEditor工具等

 

8、簡單介紹一下CocoStudio

CocoStudio是一套基於Cocos2D-X引擎的工具集,包括UI編輯器、動畫編輯器、場景編輯器和數據編輯器。UI編輯器和動畫編輯器主要面向美術,而場景編輯器和數據編輯器面則面向遊戲策劃,這四個工具合在一起構成了一套完整的遊戲開發體系,幫助開發者進一步降低開發難度、提高開發效率、減少開發成本。
UI編輯器:支持目前Cocos2D-X的所有控件,同時支持多分辨率適配、碎圖合併以及自定義UI。
動畫編輯器:支持骨骼關鍵幀動畫、序列幀動畫,同時支持碎圖合併、Flash動畫直接導入等。
數據編輯器:把策劃用的Excel數值表分解,然後轉化成Cocos2D-X可以識別的格式。
場景編輯器:可以整合我們之前CocoStudio其他編輯器的資源,編輯當前的遊戲場景,實時演示,所見即所得。同時也支持第三方的工具模式。

 

9、簡述CCSpriteframeCache   CCSpriteBatchNode,並說出CCNode,CCSprite是如何實現繪製的?

CCSpriteframeCache:精靈框幀緩存,緩存了精靈框幀,主要是爲了處理多張碎圖合併出來的紋理圖片。由於一張大圖包含了多張小圖所以不適合使用CCTextureCache。

CCSpriteBatchNode 中的所有CCSprite只會被渲染1次,因此可以提高遊戲的FPS,但是加入到 CCSpriteBatchNode 中的CCSprite必須使用同一張紋理圖。

 

10、cocos2d-x的屏幕適配解決方案?

  決定着我們屏幕適配的因素主要有:屏幕大小 和 寬高比

CCEGLView::sharedOpenGLView()->setDesignResolutionSize(720, 480, kResolutionShowAll);

CCEGLView::sharedOpenGLView()->setDesignResolutionSize(720, 480, kResolutionExactFit); 

kResolutionUnKnown:

  這是 cocos2d-x 編寫的默認模式,沒有做任何處理,在這種情況下,遊戲畫面的大小與比例都是不可控的

kResolutionExactFit:

  犧牲了畫質而保持了全屏顯示,對畫面進行了拉伸,意味着相對極端情況下,本來精靈是方形的,顯示出來變成長方形,本來圓形的變成了橢圓,固此模式不推薦使用。

kResolutionShowAll:

爲了保持設計畫面比例對四周進行留黑邊處理,使得不同比例下畫面不能全屏。魚和熊掌不能兼得

kResolutionNoBorder

此模式可以解決兩個問題,其一:遊戲畫面全屏;其二:保持設置遊戲時的寬高比例,相比 kResolutionShowAll 有所區別的是,爲了填補留下的黑邊,將畫面稍微放大,以至於能夠正好補齊黑邊,而這樣做的後果可想而知,補齊黑邊的同時,另一個方向上將會有一部分畫面露出屏幕之外。

 

10、cocos2d-x遊戲儲存 CCUserDefault和SQLite

CCUserDefault 是Cocos2d-x引擎提供的持久化方案,存儲所有遊戲通用的用戶配置信息。例如音樂和音效配置。本質是一個XML文件。使用只需一行代碼:

CCUserDefault::sharedUserDefault()->setIntegerForKey("coin",coin-1);

缺點:每次設置和讀取都會遍歷整棵XML樹,效率不高,且值類型具有侷限性,只支持int和float等基本類型。

 http://blog.163.com/zhoulong19880518@126/blog/static/607097022012985417804/

SQList是一個嵌入式數據庫,具有開源,輕量等特點,用於高速且安全地在本地存儲數據。核心接口函數只有一個:

int sqlite3_exec(sqlite3*, const char* sql, int (*callback)(void*,int,char**,char**), void*, char**errmsg);

還有函數: bool sqlite3_open(const char*, sqlite3*);

     sqlite3_close(sqlite3*);

 

 

12、autorelease和release的區別:

release 會立馬對對象進行引用計數減一操作,如果當前對象的引用計數小於0,則會進行釋放。

autorelease 則會將該對象放入到自動釋放池中,當一幀結束的時候會執行release操作進行引用計數減一操作,如果當前對象的引用計數小於0,則會進行釋放。

詳細由第三個問題cocos2d-x內存管理可以詳細解答。

 

 

13、cache機制原理是什麼?

  把新加進內存的資源做一個hashmap存儲,每一個資源加一個key。每次加載資源的時候,先查找資源是否存在,存在直接返回,否則加載進內存。

 

14、減少內存開銷的方法有哪些,圖片壓縮方法有哪些 及時釋放,減少泄露,重用資源,延遲加載,分部加載等

  1)不使用JPG,因爲JPG紋理在加載的時候,會實時地轉化爲PNG格式的紋理。

  2)預先加載所有的紋理。

  3)在後臺加載紋理CCTextureCache類還支持異步加載資源的功能,利用addImageAsync方法。你可以很方面地給addImageAsync方法添加一個回調方法,這樣,當紋理異步加載結束的時候,可以得到通知。

4)如果遊戲有很多場景,在切換場景的時候可以把前一個場景的內存全部釋放,防止總內存過高. 一般在切換場景的時候釋放資源,如果從A場景切換到B場景,調用的函數順序爲B::init()---->A::exit()---->B::onEnter() 。可如果使用了切換效果,比如CTransitionJumpZoom::transitionWithDuration這樣的函數,則函數的調用順序變爲B::init()---->B::onEnter()---->A::exit() 。
而且第二種方式會有一瞬間將兩個場景的資源疊加在一起,如果不採取過度,很可能會因爲內存吃緊而崩潰。

5)儘量去拼接圖片,使圖片邊長儘可能的保持2的N次方並且裝的很滿。但要注意,有邏輯關係的圖片儘量打包在一張大圖裏,另外一點就是打包的時候要考慮到層的分佈。因爲爲了渲染效率可能會用到CCSpriteBatchNode;同一個BatchNode裏的圖片都是位於一個層級的,因此必須根據各個圖片的層級關係,打包到不同的plist裏。有時內存和效率不可以兼得,只能儘量平衡了。

6)避免一個接一個地加載PNG和JPG紋理(他們之間至少等待一幀),因爲等待一幀,引用計數會把臨時的UIImage對象釋放掉,減少內存壓力。

7)使用pvr格式的紋理時,只使用pvr.ccz格式,不要使用其它格式!因爲它加載速度超快,而且加載的時候使用更少的內存!

7)最快速地減少紋理內存佔用的辦法就是把它們作爲16位顏色深度的紋理來加載。cocos2d默認的紋理像素格式是32位顏色深度。如果把顏色深度減半,那麼內存消耗也就可以減少一半。並且這還會帶來渲染效率的提升。

 15、說說Lua

 

17、Cocos2d-x中使用的各種設計模式

  觀察者模式:NotificationCenter

   裝飾者模式:Action和它的繼承類之間的關係

   單例模式:Director有一個sharedDirector,NotificationCenter也有sharedNotificationCenter

      工廠方法:Create方法

 

 


19、Unity和Cocos2d-x的區別

Unity3D的亮點是可視化編程,資源輕鬆導入,一鍵部署各個平臺,擁有衆多第三方插件,輕鬆處理音頻/視頻的兼容。Cocos2d-x是擁 有發達的開發者社區,能夠方便的找到各種問題的解決方案。spine、TexturePacker、Cocostudio等工具讓引擎方便的處理各種資 源,UI問題。而且開源方式也使開發者很方便的研發出適合自己項目的編輯器。

使用方式:Unity3D任何功能都可以拆分成單個組件來實現;Cocos2d-x開源的優勢在於可以根據自身的需求進行自定義修改。

可視化編輯:

Unity3D對可視化編輯的支持更好,腳本編譯時間很快,可以快速出原型出Demo Cocos2d-x更多是代碼層面的編寫,爲了補充可視化編輯方面的問題推出了Cocos studio 。

形象生動的比較:http://unity3d.9tech.cn/news/2013/1223/39327.html

 

20、遊戲中的狀態機的設計,動畫曲線的設計,相機的移動,遊戲中如何使用MVC之類


21、如何對手機遊戲進行優化

   一般分爲內存優化幀數優化,內存優化和運存優化。

 幀數優化可以考慮對一個message loop中的邏輯運算進行優化,比如可以考慮A*的剪枝。或者進行time slice

體積和運行內存優化有以下幾點

使用TexturePacker等工具把多張資源合成一張圖片。

採用png壓縮工具,在打包圖片之前對每張圖片進行壓縮,比如將32bit顏色深度改爲16bit顏色深度以降低圖片質量。

 針對不同的平臺使用特定的壓縮格式的圖片

 如果項目中幀序列佔的比較多,那麼可以採用降幀的方式來優化。

縮放圖片,將原來圖片縮小爲原來的70% ~ %80,再對圖像進行放大 採用編輯器,

將大圖轉化爲拼接,那麼就可以利用地圖編輯器、動作編輯器等從而減少體積,降低內存的使用。

 

22、如何在對遊戲的“手感”進行改進?

  遊戲手感一般指的是打擊感,那麼我就在打擊到一個遊戲對象時,遊戲對象要產生擊退的效果,產生該對象被打擊的感覺。 時間控制要恰當,要讓某個對象(比如拳頭)打擊到另一個遊戲對象的時候,才產生擊退效果,這就需要進行使用消息機制和回調來解決。 

 

23、如何在數據庫中存儲一個人的所有裝備

建立一個人物ID和裝備ID的關係表。

   將人物的所有裝備的id序列化爲一個JSON字符串存儲爲人物的一個字段。 這兩個最大的區別是在修改裝備時,第一個只會影響一條記錄,當時第二個會影響所有裝備,一旦出現bug還讓玩家損失所有裝備。兩者各有利弊,根據使用場景自己權衡。。

 24、如何減小cocos2d-x壓縮包的大小?

25、如何減少遊戲內存的使用?

 同行整理題目鏈接:http://www.58player.com/blog-2534-94098.html

園子游戲人生:  http://www.cnblogs.com/lancidie/default.html?page=4

大拿:  http://blog.leafsoar.com/archives/category/cocos2d-x/

發佈了21 篇原創文章 · 獲贊 6 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章