我有一个 GameScene(这里称为 ShooterScene),然后我退出到 MainMenu。我确实使用加载到纹理缓存中的精灵表。有各种动画正在进行(背景元素、敌人、玩家等......)。几个月来,我遇到了一个问题,即 Enemies 的“setTexture”方法断言失败。我通过在替换场景之前暂停共享 CCDirector 解决了这个问题。这具有停止动画的效果。但是我只部分解决了这个问题。游戏不再在 Enemy setTexture 上崩溃,但现在在 AnimatedBackgroundElement setTexture 方法上崩溃。
背景元素被添加到精灵批处理节点,该节点是作为子元素添加到 GameScene 的 Background 类的子节点。我确实想知道,由于某些层次结构的原因,暂停调用的传播是否存在一些延迟,或者“暂停”线程和背景元素的 CCAnimate->setTexture 线程之间是否存在一些并发问题。
有什么建议/想法吗?
PS:我检查了“[[CCDirector sharedDirector] stopAnimation]”,它说:
CCLOG(@"cocos2d: Director#stopAnimation. Override me");
我是否打算“覆盖”此方法来解决上述问题?我想这将是一个通过递归调用真正停止所有孩子的所有动画的好地方,但同样,由于随后的“replaceScene”方法可能并发,我不确定延迟。我可以通过使用一系列回调(CCSequence with action1 = call stop animation and action2= replace scene)来解决这个问题,但我不能 100% 确定 action2 的调用只会在调用结束后发生停止动画(action1)。我可以为(所有孩子)写一个递归并将其放在replaceScene之前。或者延迟回调replaceScene(这不是一个优雅的解决方案,因为它是半任意的)..
-(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:我看到有很多关于试图阻止一个场景的相关帖子。我猜其他人可能有类似的问题,所以可能有一个最先进的解决方案/设计模式。
编辑:我已经尝试实现这一点,但它仍然失败。
-(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]];
}