CocosBuilder回調事件失敗問題

首先拋出我們現在已有的問題:

問題1: 我們使用cocosbuilder來做特效,會有回調事件丟失的問題,主要出現在結束之前的幾個關鍵幀。

問題2: 當回調函數失效的情況發生時,回調的一個CCString對象就會造成內存泄漏,雖然泄漏很少,但是依然是一個問題。

分析問題:

cocos2dx的動畫系統不夠安全 ?

最初我們認爲是cocos2dx的動畫系統是一個不完全依賴於幀處理的動畫,是不可足夠信賴的,所以會在加速的情況下,由於幀數的合併,造成丟失關鍵幀。經過我用加速器的測試,發現這是不對的,cocos2dx的動畫系統是可信賴的,能夠保證每一個關鍵幀不被丟失。

結論是:錯誤的,它的動畫系統足夠安全

爲什麼cocosbuilder的回調會失敗 ?

問題出在cocosbuilder的解析代碼中,具體是cocosbuilder會執行三個主線動畫:整個時間軸的延時動畫,之後是調用結束事件執行整個時間軸的事件回調執行整個時間軸的聲音回調

乍一看這並沒有什麼問題,很符合我們的設定,分工明確,操作獨立,然而作者忽略了一個問題,那就是在實際的設備執行過程中,每一幀的時間不是很理想的 1/30 或者 1/60,根據設備的運行狀態,會有一些浮動。問題就出在這裏,第一個動畫控制着動畫是否結束,他僅僅執行了一個延時,然後回調,相對來說是開銷比較少的,第二個和第三個動畫則不然,他們回去調用相關的邏輯,如果正常1/30的狀態下,差距不會很大,但是如果我們開啓了N倍的加速,就會把這個差距無限放大,時間的開銷也就大了起來,最後的結果是第二個和第三個動畫執行到最後的時間已經超過了動畫的設定總時間,而在動畫設定總時間到達的時候,已經調用了結束事件,也就是未被執行的關鍵幀就永遠的被拋棄了,而分配的內存空間也就被遺棄在了內存中。

解決方案:讓這三個動畫變爲一個動畫執行,然後在執行完這3個動畫之後,在執行結束動畫。

代碼如下:修改CCBAnimationManager::runAnimationsForSequenceIdTweenDuration函數


代碼如下:

// mRootNode run actions once 
	CCArray* spwans = CCArray::create();

	// Make callback at end of sequence
    CCBSequence *seq = getSequence(nSeqId);
	CCAction *callDelayTime = CCDelayTime::create(seq->getDuration() + fTweenDuration);
	CCCallFunc *completeCall = CCCallFunc::create(this, callfunc_selector(CCBAnimationManager::sequenceCompleted));
	spwans->addObject(callDelayTime);
   
    // add the event call back to spwans
    if(seq->getCallbackChannel() != NULL) {
        CCAction* action = (CCAction *)actionForCallbackChannel(seq->getCallbackChannel());
        if(action != NULL) {
			spwans->addObject(action);
        }
    } 

	// add the sound call back to spwans
    if(seq->getSoundChannel() != NULL) {
        CCAction* action = (CCAction *)actionForSoundChannel(seq->getSoundChannel());
        if(action != NULL) {
			spwans->addObject(action);
        }
    }

	// after all actions , call action complete event
	CCSpawn *spwanAction = CCSpawn::create(spwans);
	mRootNode->runAction(CCSequence::createWithTwoActions(spwanAction,completeCall));

    mRunningSequence = getSequence(nSeqId);




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