在iOS 9上,使用物理引擎暂停Sprite Kit游戏的功能无法正常工作。

3

我有一个关于在带物理引擎的Sprite Kit游戏中暂停的问题。游戏包含一个球,它在SpriteScene中移动,并具有以下参数:

self.ball.physicsBody.friction = 0;
self.ball.physicsBody.linearDamping = 0;
self.ball.physicsBody.restitution = 1.0f;
self.ball.physicsBody.affectedByGravity = NO;
self.ball.physicsBody.usesPreciseCollisionDetection = YES;

问题在于,当我暂停游戏时,我调用了这些方法:
self.scene.physicsWorld.speed = 0;
self.ball_velocity = self.ball.physicsBody.velocity;
self.ball.physicsBody.velocity = CGVectorMake(0, 0);
self.ball.speed = 0;
self.ball.physicsBody.dynamic = NO;
[self.scene.view setPaused:YES];

当恢复时,请调用以下内容:
self.scene.physicsWorld.speed = 1;
self.ball.physicsBody.velocity = self.ball_velocity;
self.ball.physicsBody.dynamic = YES;
self.ball.speed = 1;
[self.scene.view setPaused:NO];

这会停止球的动画,但是当恢复时,球的位置会改变,看起来好像在暂停期间一直在移动。

顺便说一下,在iOS 8上它可以正常工作,但在iOS 9上总是失败。

有什么建议吗?!!


这种情况总是发生吗?尝试两种情况:1. 暂停游戏,立即取消暂停。2. 暂停游戏,等待几秒钟,然后取消暂停。尝试观察在暂停和取消暂停视图时的fps。可能会出现一些延迟,这发生在视图取消暂停后立即发生。当场景暂停/取消暂停时不会发生这种情况。因此,您可以暂停场景而不是视图。 - Whirlwind
似乎球在暂停期间仍在继续其运动,而当取消暂停时,它立即转移到新位置。我尝试暂停场景本身但是仍发生相同的错误!!! - Amani Elsaed
很奇怪,如果我暂停场景,我无法产生你所说的内容。实际上,只有在我快速暂停/恢复视图时,我才能产生你所说的内容。你使用的是哪个Xcode版本、设备和模拟器? - Whirlwind
我已在iOS 8上进行了测试,它可以正常工作-正确暂停和恢复-但在iOS 9上,无论我是否快速暂停,这个问题总是发生。@Knight0fDragon:我在按钮按下时调用暂停和恢复,球上没有应用任何操作,只有速度。顺便说一句,在iOS 8上,仅使用[self.scene setPaused:YES]就可以正常工作。 - Amani Elsaed
这很奇怪,因为场景暂停不会暂停更新循环,改变物理状态也没有意义,很可能发生了一些在幕后的事情重置了某些物理状态。另一方面,暂停视图可能会导致其跳动,因为更新方法中的时间间隔将显示出非常高的差异,并且速度计算可能会考虑到这一点。 - Knight0fDragon
显示剩余6条评论
1个回答

2

经过讨论,我们得出结论,在iOS8和iOS9之间,苹果公司进行了一项更改,使暂停场景现在暂停了更新循环。由于更新循环被暂停,时间的变化没有被正确计算。现在发生的是,时间的变化将是暂停时的时间 - 恢复时的时间,模拟出了滞后状态。速度将考虑到这个数学差异,并根据这个时间差移动物体。为了解决这个问题,只需创建一个父节点,用于存放场景中的所有对象,并暂停该父节点。这将允许调用更新,从而使时间的变化与帧速率保持一致。


重要提示,仅设置ball.paused在iOS 9上无效,在iOS 8上正常工作。为了解决这个问题,我将球的速度设置为0,然后在恢复后将其设置回正常速度。 - Amani Elsaed
是的,看起来这不是答案,我们一定缺少了你正在做的某些东西。我写了一个示例应用程序,暂停场景,物理速度根本不基于更新计时器,无论是慢速还是快速暂停,我的精灵都按预期移动。这个示例在iOS 8和iOS 9上也可以工作。你能发一下你的update函数里面的内容吗?我有一种感觉你可能做错了什么。 - Knight0fDragon
@AmaniElsaed,如果你想要测试它。创建一个新的SpriteKit应用程序,并在示例中,将制作精灵的触摸代码移动到移动到视图区域,而不是使用SKAction旋转,请将其删除,添加物理体,并将速度设置为-30,0。然后只需让触摸操作做self.paused = !self.paused。您的精灵应该以预期的速度移动。 - Knight0fDragon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接