SpriteKit

时间:2015-06-16 01:14:50

标签: ios swift sprite-kit game-physics skphysicsbody

我在更新函数中将一个恒定速度应用于我的一个节点:

// Set a constant velocity to the right:
node.physicsBody?.velocity.dx = 300

当我在didSimulatePhysics函数中打印速度时,它打印出290左右。好吧,我正在失去一些速度到linearDamping,这是有道理的。但它不会保持不变。

每隔10-15秒,速度中会出现无法解释的抖动(来自didSimulatePhysics打印)。对于6或7帧,速度将从285-295波动。慢一点,然后更快。所以我会得到287,然后是294,然后是286,然后是294.从来没有两个慢或两个连续快。

这是我的主角,由我的相机跟踪,速度的微小变化使得相机在发生这种情况时会出现抖动。

我远离任何碰撞,但请注意我忽略了此节点上的碰撞并将恢复原状设置为0:

node.physicsBody?.collisionBitMask = 0
node.physicsBody?.restitution = 0

物理模拟是否滞后,然后在下一帧(FPS与60挂钩)试图弥补它?或者可能遇到四舍五入的问题?

有没有办法在每一帧上的一个方向上获得完全恒定的速度?

在没有碰撞的情况下直接在空中移动时,每帧中添加node.position.x的实际更改示例,每次更新时设置velocity.dx为300:

3.82861328125 // this is the norm - thousands of these before this blip)
3.82861328125
3.82861328125
5.740478515625 // blip begins
1.9150390625
3.82861328125
5.740478515625
1.9150390625
5.740478515625
1.9150390625
5.740478515625
1.9150390625
5.740478515625
3.82861328125 // blip ends
3.82861328125
3.82861328125

1 个答案:

答案 0 :(得分:0)

SpriteKit物理学的问题在于它使用的是可变时间步长,特别是在恒定运动的情况下,该步长不能很好地工作。这意味着SpriteKit使用从上一帧开始传递的deltaTime更新每帧中的物理。即使您保持恒定的60 FPS,此时间也绝不会完全相同。要解决此问题,最好使用恒定时间步长进行物理模拟。不幸的是,在SpriteKit中,无法控制物理模拟的时间步长,它始终与帧速率相关。如果使用允许手动更新物理学的引擎,则可以通过以下方式为物理学模拟实现恒定时间步长:

-(void)update:(double)dt
{
  double fixedDt = 1.0/60.0; // or you can put for example 1.0/300.0 to have more physics updates per frame

  self.difference += MIN(dt, 0.1); // prevent too big dt changes

  while (self.difference > fixedDt)
  {
      [self updatePhysics:fixedDt];
      self.difference -= fixedDt;
  }
}

不幸的是,在SpriteKit中您无法控制它,这就是为什么即使在60 FPS恒定运动下始终会看到一些小的抖动的原因。您有几种解决方案:

  • 忽略它,只接受它
  • 尝试使用其他物理引擎,例如Chipmunk或Box2D
  • 完全不使用任何物理引擎

您还可以在此处找到有关物理的可变/恒定时间步长的更多信息:https://gamedev.stackexchange.com/questions/1589/when-should-i-use-a-fixed-or-variable-time-step