2011-01-24 40 views
0

我想在iPhone切換回基於UIView的視圖之前,讓iPhone上的Cocos2D「自行清理」 ,但它是過度放出(或者是過度放電),並且我無法做出正面或反面的反應。當我嘗試在動畫中間停止時,Cocos2D與殭屍崩潰

這有點長,但我試圖照顧好它的組織。

我的節點層次結構是這樣的,和括號註明 「什麼在」 每一個節點:

  1. CCScene(菜單)
  2. CCLayer(漢字)
  3. CCLayer(全動畫)
  4. CCSprite, CCSpriteBatchNode(部分動畫,可以有多種類型)

因此,當「角色」運行不同的動畫時,我會從「角色」CCLayer中刪除「動畫」CCLayer,創建一個新的「動畫」CCLayer,並將其添加爲小孩。到目前爲止,這沒有造成任何問題。

最後,CCScene上有一個按鈕,可以「結束」應用程序的Cocos部分。當我點擊「結束」按鈕時,我想返回到UIKit-land。

但是,在我回到UIView-land之前,我想在角色上運行最後一個動畫,當THAT完成時,終止。要做到這一點,我需要像這樣在角色CCLayer上「註冊」一個處理程序。我所說的「最後」的動畫,然後回調到CCScene當最後的動畫(使用志願)來完成:

- (void) doEndWithHandler:(id<LWECharacterDelegate>)handler 
{ 
    // Handler is the CCScene, "self.parent" could work but I want it loosely coupled 
    self.endOfSessionHandler = handler; 

    // Tell character to start final animation -- this creates a new CCLayer, 
    // starts the animation, and assigns that CCLayer into self.animatedSequence 
    [self changeCharacterActionTo:END_ANIMATION key:nil]]; 

    // The "animation" CCLayer has a property called "moving" -- observe it 
    [self.animatedSequence addObserver:self forKeyPath:@"moving" options:NSKeyValueObservingOptionNew context:NULL]; 
} 

然後我觀察代碼,被稱爲回來時,「搬」到成爲NO( =動畫完成):

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{ 
    if ([keyPath isEqualToString:@"moving"]) 
    { 
    BOOL movingStatus = [[change objectForKey:NSKeyValueChangeNewKey] boolValue]; 
    if (movingStatus == NO) 
    { 
     // Stop observing 
     [object removeObserver:self forKeyPath:@"moving"]; 

     // Stop all animations on this level 
     [self.animatedSequence stopAnimation]; 
     [self removeChild:self.animatedSequence cleanup:YES]; 
     [self removeFromParentAndCleanup:YES]; 

     // Handler callback 
     if (self.endOfSessionHandler && [self.endOfSessionHandler respondsToSelector:@selector(characterDidFinishSession)]) 
     { 
     [self.endOfSessionHandler characterDidFinishSession]; 
     } 
    } 
    } // if key = moving 
} 

現在,你可能會說,

不知道你,你可以只添加使用CCCallFunc作爲結尾的動畫動作的回調,所以你知道你什麼時候完成了G?

是的,我知道 - 但重點是CCScene「知道」何時按下了結束按鈕 - 並非任何一個特定的動畫。當結束按鈕被按下時,CCAction已經開始運動,所以我想告訴所有精靈停止動畫和摧毀。

我的動畫CCLayer有一些特殊的代碼告訴我什麼時候雪碧停止移動。該代碼運行良好 - 我在每個動畫的末尾都使用了一個CCCallFunc回調來告訴我的「動畫」CCLayer類它已完成。

爲什麼它似乎是個問題,但是,在Cocos2D操作堆棧跟蹤解除展開之前,我得到KVO通知「移動」發生了變化。我很確定我的問題在哪裏,因爲一旦KVO通知出現,我會嘗試停止一切(請參閱上面的代碼)。然而,並非所有事情都會停止,因爲Cocos2D框架試圖「包裝」堆棧跟蹤時崩潰(過度釋放)。

是否無法在CCCallFunc回調中停止動畫,該回調是動畫同一個精靈的動作?

對於你真正科科斯-頭在那裏,這是崩潰的確切路線是:

if(currentTarget->currentActionSalvaged) { 
    // The currentAction told the node to remove it. To prevent the action from 
    // accidentally deallocating itself before finishing its step, we retained 
    // it. Now that step is done, it's safe to release it.  
    [currentTarget->currentAction release]; 

..這是對CCActionManager.m 327線。

回答

0

好的,我自己解決了這個問題。這裏的關鍵教訓是這樣的:

如果您正在「清理」一科科斯會話,你應該罰款做到這一點從科科斯回調(CCCallFunc),但不叫[[CCDirector sharedDirector] end],直到你的科科斯回調堆棧跟蹤有後展開。

就是這樣。

相關問題