1. 程式人生 > >Cocos2d-x使用過程中遇到的錯誤(VS下開發,移植到Android釋出)(更新ing)

Cocos2d-x使用過程中遇到的錯誤(VS下開發,移植到Android釋出)(更新ing)

環境:windows7, VS2010, cocos2d-1.0.1-x-0.12.0, cygwin, eclipse, android sdk4.0.3, ndk r7b

在vs上開發,然後移植到android上.


20120718

CCArray的foreach操作:

cocos2d-x 本地通知呼叫的問題 CCNotificationCenter
在註冊的postNotification訊息函式中,不能再呼叫addObserver,可能會引發儲存CCNotificationObserver物件的CCArray擴容,導致CCArray重新new了一塊記憶體地址,CCArray首指標改變,當執行完返回postNotification函式的時候和原來的CCArray首指標不一致,導致記憶體讀取出錯。

observer->performSelector
就是註冊的訊息回撥函式。該函式內不能對再新增或減少自定義訊息。


void CCNotificationCenter::postNotification(const char *name, CCObject *object)
{
    CCObject* obj = NULL;
    CCARRAY_FOREACH(m_observers, obj)
    {
        CCNotificationObserver* observer = (CCNotificationObserver*) obj;
        if (!observer)
            continue;
        
        if (!strcmp(name,observer->getName()))
            observer->performSelector(object);
    }
}


20120719

強制型別轉換:

自定義類MainScene繼承自CCLayer,使用手法同HelloWorld,MainScene::scene()直接new了一個scene物件,並將MainScene的物件掛到scene下。

但是後來呼叫的時候產生錯誤操作:MainScene* pScene = (MainScene*)(pDirector->getRunningScene());scene被強制轉換成CCLayer,對所謂的MainScene物件成員操作,導致記憶體塊異常,現象就是在莫名其妙的地方掛掉,每次都不同,記憶體塊檢測也報過異常。

危險的強制記憶體轉換,切記切記!


20120723

最好不要寫出全域性變數初始化順序有依賴關係的程式碼。

const CCSize WIN_SIZE = CCDirector::sharedDirector()->getWinSize();

一開始在VS上除錯沒事,移植到Android上,初始化的時候就掛了。

查了一下資料,原因是初始化順序的問題。(具體初始化的順序沒搞清楚,⊙﹏⊙b汗,歡迎補充,感激不盡)

PS:找到了幾篇初始化靜態常量順序的文章

1.控制全域性變數初始化順序 && #pragma詳解

2.全域性變數初始化順序

int   get_a()
{
        static   int   a   =   5;
        return   a;
}
int   get_b()
{
        static   int   b   =   get_a();
        return   b;
} 

3.JAVA中初始化順序複習

4.初始化有序常量的一點小技巧


20120726

playEffect

音效播放前要先preloadEffect,否則第一次播放音效沒有聲音。可以一次preloadEffect所有音效,android那邊呼叫的是HashMap儲存音效存放路徑。

vs端不寫preloadEffect也能正常播放,但是android端必須先preloadEffect才能正常播放,否則第一次播放沒有聲音。背景音樂沒發現這個問題。



20120803

CCTargetedTouchDelegate 的繼承 和 dynamic_cast

想寫個可以響應touch的sprite

類定義成了這個樣子:

class GemBoard : public CCSprite, CCTargetedTouchDelegate

然後註冊touch訊息的時候

CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this, 0, true);

在這掛了,查了一下午,掛在了

-addTargetedDelegate

    -CCTargetedTouchHandler::handlerWithDelegate

        -initWithDelegate

             -CCTouchHandler::initWithDelegate

                  -dynamic_cast<CCObject*>(pDelegate)->retain();

                         -void CCObject::retain(void)

跟到這裡,編譯器告訴我CCObject的this指標是0,我暈呀。感覺太詭異了。

原因:CCTargetedTouchDelegate在上面的寫法中是私有繼承,而根據dynamic_cast的作用:(運算子可以在執行期決定真正的型別。如果downcast是安全的(也就說,如果基類指標或者引用確實指向一個派生類物件)這個運算子會傳回適當轉型過的指標。如果downcast不安全,這個運算子會傳回空指標(也就是說,基類指標或者引用沒有指向一個派生類物件)。)上面的情況就合情合理了。

今天學到了2個知識點:

1. class B: public A, C  這種情況下A是public繼承,C是private繼承;class B: A 這個A也是private繼承

2.dynamic_cast 除了public 的其他都返回null

所以改成

class GemBoard : public CCSprite, public CCTargetedTouchDelegate

就正確了。發現自己的c++基礎真爛。



20121101

今天不是萬聖節嗎,怎麼變成了愚人節!!!

因為做的專案是VC++下開發,然後編成原生代碼在Android上執行,所以有些地方需要上真機列印log除錯。我日哦,我在程式碼里加了N多的log程式碼,就是一句也不打出來,在log上糾結了一天,一開始以為是cocos2d的程式碼出問題了,難道是自動遮蔽了log輸出?上網查資料,當然什麼也找不到。我就在加log程式碼,然後上真機,看不到log,然後繼續加log程式碼,往復迴圈。下班的時候,同事看我這麼糾結,就問我,vc上打斷點看程式執行到log程式碼處了嗎?結果是程式正常執行,斷點根本不走,靠!原來我一直在一段廢程式碼上加log!我的生命呀,就這樣浪費了。我想起了一首神曲,有興趣的同學可以聽一下:Wrong hole  - DJ Lubel



20121103

CCTexture2D::initWithData

bool CCTexture2D::initWithData(const void *data, CCTexture2DPixelFormat pixelFormat, unsigned int pixelsWide, unsigned int pixelsHigh,const CCSize& contentSize)

使用資料建立紋理,我試了無數遍,各種問題都考慮了,就是不知道為啥正常創建出來的紋理顯示不出來。最後發現是contentSize這個最後的引數,我給的是(0,0)當然建立不出來了,一開始還以為是CCTexture2D建立成功後返回給我的生成的紋理大小。事實證明是我想多了……這個引數就是一開始指定要建立紋理的大小的。



20131220

runAction & OnEnter

今天學會了一個打開卷軸的動畫

一開始自己想的辦法是使用CCProgressTimer的CCProgressTo來執行這個動畫,但是因為我做的不僅是單個sprite,還有掛在上面的Label,CCProgressTimer在繪製的時候不會處理它的子節點,後來想到一個辦法,使用CCRenderTexture,將卷軸上的東西都畫到上面,然後使用CCRenderTexture生成CCProgressTimer的sprite,效果達到要求。

但是CCRenderTexture向來是不推薦使用的,因為繪製效率低,而且遊戲掛起後返回會丟失CCRenderTexture的資源。

找大能諮詢,推薦使用CCClippingNode,設定它的Stencil,然後對這個Stencil做處理就能出展示的效果。

遇到個問題:我在addChild之後替換了Stencil,然後再用這個Stencil播放動畫,死活播不出來,其他的都能播放動畫。後來發現是在節點的OnEnter之後改變節點下的子,再針對這個子的所有事件都不會發生。因為子的OnEnter函式不會再執行了。


20130901

CCBatchNode  vs  ccBlendFunc

引擎版本:2.2.5

放在CCBatchNode下的骨骼動畫設定不了ccBlendFunc,可檢視CCArmature的draw函式,第一句就是判斷batchnode是否為空,

想想也是,要是每個動畫都有自己的ccBlendFunc,那就沒必要放在batchnode下了。