Cocos2d-x開發中遇到的問題彙總

學習Cocos2d-x有半年時間了,版本從2.1.3到3.0,對於這個引擎的感覺就是跨平臺做的好,用起來簡單,但是在開發的過程中難免還是遇到一些問題,這裏做下彙總:

1、在Android系統上游戲崩潰,錯誤是由於內存訪問越界

      一般出現這種情況主要是由於Cocos2d-x中的對象大部分都是會自動進行內存管理,在Win32平臺上可能不會出現什麼問題,但是到了Android上面就會出現,要避免這個問題的出現就需要按照一些原則來使用Coco2d-x引擎中的對象

     1、當某個Cocos2d-x的對象是屬於類成員對象,那麼在創建它的之後需要調用retain函數,以免出現所屬類對象還存在,而該作爲成員的對象卻已經被自動回收了

     2、當在某個函數中創建某個全局的Cocos2d-x引擎的對象時,也需要調用其retain函數,以免在函數退出後,對象被釋放,之後對全局對象的訪問出現崩潰。

     3、Cocos2d-x框架中的Array類是非常容易被釋放掉的,如果使用的Array對象要被作爲參數傳遞,或被多次在不同函數中被使用,那麼在創建這類Array對象也要調用它的retian            函數,以免程序崩潰。

2、關於Cocos2d-x多線程的替代方案的思考

    在Cocos2d-x的主線程中調用的很多屬於其框架下含有函數retian,autorealease等的調用的對象時是沒有問題的,但是這些對象是不是線程安全的,因此就算輸可以使用pthread這樣跨平臺的線程庫也很不方便,不過有另外一種方法可以實現類線程的效果,那就是使用schedule函數對需要並行的邏輯進行定時調用,schedule的定時調用時線程安全的,因此可以利用該機制去實現想要的並行的邏輯。


3、3.0版本中編譯項目出現 無法解析的外部符號 __imp__mci_Player之類的錯誤

     我把2.x下的項目放到3.0下編譯會出現這個錯誤,原因肯定是有的庫沒有引用進來,解決的辦法是在鏈接器->輸入->附加依賴項中加入winmm.lib

     這裏有一個關於版本移植的啓示,在每次版本更新後如果出現缺少庫或者鏈接階段的錯誤時,不妨參考下目標版本引擎下的Sample

4、Cocos2d-x 3.0alpha中使用UserDefault 的setIntegerForKey() 導致程序崩潰

     一般不會出現這類問題,由於UserDefault使用了tinyxml 進行xml文件的操作,出現這個問題的原因有可能是xml文件的路徑中包含中文字符,這會導致tinyxml出錯,因此開發Cocos2d-x項目

     切記不要使用帶中文的路徑和文件名,以免出錯。

5、在Sequence 和Spwan這2個Action中加入RepeatForever後沒有執行,這個問題的主要原因還是出在Sequence和Spawn的實現代碼中,但是有時候有需要這麼做,是有解決辦法的,下面的鏈接是鵬飛大牛給出的問題解釋和解決方案:

http://blog.csdn.net/jackystudio/article/details/17019023

6、生成的Android apk真機下運行啓動即出錯 libc Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1)

這個問題困擾了我很久,當時是我把3.0alpha版本下的一個項目移植到3.0版本下,新生成的apk報了這個錯誤,我以爲是因爲版本不同而導致的崩潰,各種修改C++代碼,但錯誤一直在,後來我就把3.0版本自帶的一個android項目的模板拷貝過來替換掉舊版本的android項目,奇蹟出現了,生成的apk就沒有這個錯誤了,我很奇怪,把3.0alpha的android項目內的文件和3.0版本的android項目內的文件做了一一對比,發現都是一樣的,後來懷疑是不是依賴庫還是舊的,於是把java層的和c++層的庫都重新生成了下,結果舊項目還是報錯,無法理解,找不出問題所在,不過問題總算解決了。

7、將一個Node從原父節點轉而掛接到新的父節點的正確方法

直觀的代碼是這樣的:

child->removeFromParent();

newParent->addChild(child);

但是執行到第二句就會報錯,child已經被釋放了,原因在於當執行第一句的時候,child從父節點的子節點列表中刪除,會調用子節點的release函數將子節點的引用計數減1,

這時候就很可能出現引用計數爲0的情況,而如果出現這種情況release函數內部會將該節點內存釋放,也就是會執行delete this; 這時候child就變成指向非法空間了。

正確的代碼是:

child->retain();

child->removeFromParent();

newParent->addChild(child);

先調用retain函數將child的引用加1,這樣就不會出現child被意外釋放的情況了


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