Cocos2d and concurrency: how to properly stop animations between scenes(Cocos2d 和并发:如何正确停止场景之间的动画)
问题描述
我有一个 GameScene(这里称为 ShooterScene),然后我退出到 MainMenu.我确实使用加载到纹理缓存中的精灵表.有各种动画正在进行(背景元素、敌人、玩家等......).几个月来,我遇到了一个问题,即 Enemies 的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.
背景元素被添加到一个精灵批处理节点中,该节点是作为子节点添加到 GameScene 的 Background 类的子节点.我确实想知道,由于某些层次结构的原因,暂停调用的传播是否存在一些延迟,或者暂停"线程和暂停"线程之间是否存在一些并发问题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.
有什么建议/想法吗?
PS:我检查了[[CCDirector sharedDirector] stopAnimation]",它说:
PS: I checked the "[[CCDirector sharedDirector] stopAnimation]" and it says:
CCLOG(@"cocos2d: Director#stopAnimation. Override me");
我是否打算覆盖"此方法来解决上述问题?我想这将是一个通过递归调用真正停止所有孩子的所有动画的好地方,但同样,由于后续replaceScene"方法的潜在并发性,我不确定延迟.我可以通过使用一系列回调(CCSequence with action1 = call stop animation and action2= replace scene)来解决这个问题,但我不能 100% 确定 action2 的调用只会在调用结束后发生停止动画(action1).我可以为(所有孩子)写一个递归并将其放在 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 和并发:如何正确停止场景之间的动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:Cocos2d 和并发:如何正确停止场景之间的动画
- MalformedJsonException:在第1行第1列路径中使用JsonReader.setLenient(True)接受格式错误的JSON 2022-01-01
- Android - 拆分 Drawable 2022-01-01
- 想使用ViewPager,无法识别android.support.*? 2022-01-01
- 使用自定义动画时在 iOS9 上忽略 edgesForExtendedLayout 2022-01-01
- android 4中的android RadioButton问题 2022-01-01
- 如何检查发送到 Android 应用程序的 Firebase 消息的传递状态? 2022-01-01
- 在测试浓缩咖啡时,Android设备不会在屏幕上启动活动 2022-01-01
- Android viewpager检测滑动超出范围 2022-01-01
- Android - 我如何找出用户有多少未读电子邮件? 2022-01-01
- 用 Swift 实现 UITextFieldDelegate 2022-01-01