學習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被意外釋放的情況了