本文介绍了Cocos2d和并发:如何正确停止场景之间的动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个GameScene(这里叫做ShooterScene),我退出到MainMenu。我使用精灵表,我加载在纹理缓存。有各种各样的动画(背景元素,敌人,球员等)。我有几个月的问题,其中有一个断言失败在setTexture方法的敌人。我通过在更换场景之前暂停共享CCDirector来解决这个问题。这具有停止动画的效果。然而我只是部分解决这个问题。游戏不会在Enemy setTexture上崩溃,但现在会在AnimatedBackgroundElement setTexture方法上崩溃。

I got a GameScene (here called ShooterScene) and I do exit to a MainMenu. I do use sprite sheets which I load in a texture cache. There are various animations going on (on background elements, enemies, player etc...). I had for months an issue where there was an assertion failure on the "setTexture" method for the Enemies. I solved this by pausing the shared CCDirector before replacing the scene. This has the effect of stopping the animations. However I solved this only partially. The game doesn't crash anymore on the Enemy setTexture but now crashes on the AnimatedBackgroundElement setTexture method.

背景元素被添加到Sprite批处理节点,该节点是Background类的子代,后者作为子代添加到GameScene。我不知道,由于某些层次结构的原因,在暂停调用的传播有一些延迟,或者如果在暂停线程和之间有一些并发问题 CCAnimate-> setTexture线程的背景元素。

The background elements are added to a sprite batch node that is child of the Background class that is added as child to the GameScene. I do wonder if, for some hierarchy reasons, there is some delay in the propagation of the pause call or if there are some concurrency problems between the "pause" thread and the CCAnimate->setTexture thread of the background element.

任何建议/想法?

[[CCDirector sharedDirector] stopAnimation],它说:

PS: I checked the "[[CCDirector sharedDirector] stopAnimation]" and it says:

CCLOG(@"cocos2d: Director#stopAnimation. Override me");

我是为了覆盖这个方法来解决上述问题吗?我想这将是一个好地方,真正停止所有的孩子的所有动画的递归调用,但再次,我不能确定延迟,由于潜在的并发与随后的replaceScene方法。我可以通过使用一系列回调(CCSequence with action1 =调用停止动画和action2 =替换场景)来解决这个问题,但是我不是100%确定action2的调用只会在调用结束后发生的事实停止动画(action1)。我可以pheraphs写一个递归(所有的孩子),并放在replaceScene ..或回调replaceScene的延迟(这将不是一个优雅的解决方案,因为它是半任意的)..

Am I meant to "override" this method to solve issues described above? I guess that this would be a good place to really stop all the animation of all the children with a recursive call but again, I am not sure on the latency due to the potential concurrency with the subsequent "replaceScene" method. I could solve this by using a sequence of callbacks (CCSequence with action1 = call stop animation and action2= replace scene) but again I am not 100% sure on the fact that the call of action2 will happen only after the end of the call to stop animation (action1). I could pheraphs write a recursive for (all children) and place that before the replaceScene.. or callback the replaceScene with a delay (which would not be an elegant solution as it would be semi-arbitrary)..

-(void) restartLevel
{
    [self resetSharedData];
    [[CCDirector sharedDirector] pause];
    LevelName currentLevel = [GameController sharedGameController].currentlyPlayedLevelName;
     [[CCDirector sharedDirector] replaceScene:[ShooterScene sceneWithLevelName:currentLevel]];
}


-(void) exitToMainMenu
{
    [self resetSharedData];
    [[CCDirector sharedDirector] pause];
    [[CCDirector sharedDirector] replaceScene:[MainMenu scene]];
}



PPS:我看到有各种相关的尝试一个场景。我猜其他人可能有类似的问题,因此可能有一个最先进的解决方案/设计模式为此。

PPS: I see that there are various related posts on trying to stop a scene. I guess other people might have similar issues so there is probably a state-of-the art solution/design pattern for this.

编辑:我已经尝试实现这个,但它仍然失败。

I have tried implementing this but it still fails.

-(void) restartLevel
{
    [self resetSharedData];
    [[CCDirector sharedDirector] pause];
    LevelName currentLevel = [GameController sharedGameController].currentlyPlayedLevelName;

    [self stopAllActions];   //Does this actually stopAllActions and Animations for ALL child nodes?
    [self unscheduleAllSelectors];
    //Do I need something else here?
     [[CCDirector sharedDirector] replaceScene:[ShooterScene sceneWithLevelName:currentLevel]];
}


推荐答案

[self stopAllActions];不是真的停止所有添加到图层的子节点的动作。您需要在特定节点上手动调用stopAllActions。

[self stopAllActions]; not really stop all actions added to layer's child node. You need to manually call stopAllActions on particular node.

-(void)onExit
{
   [self.gameHeroSprite  stopAllActions]; //call this for all animated sprite
   [self stopAllActions];
   [super onExit];
}

这篇关于Cocos2d和并发:如何正确停止场景之间的动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 22:04