【问题标题】:Moving sprite "smoothly"“平稳”移动精灵
【发布时间】:2014-08-13 00:03:04
【问题描述】:

我正在尝试使用physicsBody.velocity 属性在屏幕上按照设定的方向移动精灵。然而,这个动作非常“跳跃”(让游戏看起来像是滞后)。我认为这与每次调用update-方法之间的不同时间间隔有关。我怎样才能实现更“流畅”的运动?

现在这是我的更新循环中用于使精灵向前移动的代码:

if (_movingForward) {
  CGFloat forwardVel = _ball.physicsBody.velocity.dx;
  forwardVel += 20.0;
  if (forwardVel > bMaxForwardVelocity) {
    forwardVel = bMaxForwardVelocity;
  }
  _ball.physicsBody.velocity = CGVectorMake(forwardVel, _ball.physicsBody.velocity.dy);
}

如您所见,我正在尝试加快速度,所以它不会立即达到它的终端速度。这是为了让动作看起来更自然。然而,即使精灵以设定的速度行进,滞后也会极大地破坏这种效果。

编辑 1:

我正在尝试制作一个平台风格的游戏(如超级马里奥等),当用户点击屏幕时,_ball 会沿着地面水平移动。将球向右移动的代码包含在编辑上方。地面由多个地块组成,每个地块为32x32,彼此相邻,中间没有间隙。

根据要求,这里是设置_balls 物理体的代码:

self.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:self.size.width/2.0];
self.physicsBody.dynamic = YES;
self.physicsBody.restitution = 0.5f;
self.physicsBody.usesPreciseCollisionDetection = YES;
self.physicsBody.allowsRotation = NO;
self.physicsBody.mass = 0.5f;
self.physicsBody.friction = 0.0f;
self.physicsBody.linearDamping = 0.0f;
self.physicsBody.categoryBitMask = CollisionCategoryBall;

下面是每个tile的physicsBody的代码:

tile.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:tile.size];
tile.physicsBody.dynamic = NO;
tile.physicsBody.categoryBitMask = CollisionCategoryGround;

physicsWorld 是这样设置的:

self.physicsWorld.gravity = CGVectorMake(0, -4);
self.physicsWorld.contactDelegate = self;

谢谢!

编辑 2:

这是一款横向卷轴游戏,因此“摄像头”会跟随球。下面是移动背景层的代码:

- (void)centerViewOn:(CGPoint)centerOn {
  CGFloat x = Clamp(centerOn.x, (self.size.width / 2.0), (_bgLayer.layerSize.width) - (self.size.width / 2.0));

  _worldNode.position = CGPointMake((int)-x, _worldNode.position.y);
}

Clamp 的原因是“相机”不会滚动到背景范围之外。这是当球接近关卡的起点或终点时。 我将位置投射到int,因为没有它,瓷砖之间有时会出现小间隙。有人告诉我这是因为一些不准确或其他原因。但是,即使没有将位置转换为 int,它仍然有点“滞后”。但因为瓷砖之间的缝隙,看起来更糟。

【问题讨论】:

  • 摩擦?线性阻尼?
  • @prototypical 我不是在寻找模拟加速的方法,我只是将它包含在我的帖子中以解释代码。我正在寻找的是一种根据每个更新循环之间经过的时间动态设置速度的方法,因此它不会那么滞后。我会看看你发送的链接,可能包含一些有用的提示:)
  • 好吧,当你说它滞后时,但你没有指定是否存在帧率问题?如果不是,那么它与物理有关,对吗?你说有一个滞后效应,即使精灵“应该”以设定的速度移动。在我看来,您需要阅读该链接;)
  • @prototypical 有道理。如果将线性阻尼或摩擦属性设置为非零值,它们将影响节点的速度,因为在调用更新方法后会模拟物理场。因此,节点可能会在游戏循环的每次迭代中获得可变速度,从而导致您描述的滞后。

标签: sprite-kit sprite skphysicsbody


【解决方案1】:

问题在于您的滚动代码。

改变这一行:

_worldNode.position = CGPointMake((int)-x, _worldNode.position.y);

到

_worldNode.position = CGPointMake(-x, _worldNode.position.y);

然后动作如丝般顺滑。

但是你确实得到了那些接缝。您应该在放置这些瓷砖时解决这个问题。您可能会使用浮点值定位您的 _worldNode 磁贴。

【讨论】:

  • 我尝试在我上传的简化项目中执行此操作,您是对的 - 更改此设置可以使动作如丝般顺滑。可悲的是,当在我的原始项目中更改它时,滞后实际上变得更糟——这次是滞后的背景,而不是以前的实际球。但我想这是某种进步哈哈。感谢一百万您的帮助! :)
猜你喜欢
  • 2016-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-20
  • 1970-01-01
  • 2023-03-15
相关资源
最近更新 更多