正确使用加速度计的方法

时间:2017-06-07 19:47:50

标签: swift sprite-kit accelerometer

我使用加速计作为我游戏的转向机制。它通常工作正常但偶尔会很奇怪。随机地突然出现大量的输入延迟,我所做的每次旋转都没有注册一段时间。在某些情况下,在彼此之后输入的命令之间可能存在很多延迟,导致我的角色在一个方向上漂移太久。这是由于游戏延迟还是我的代码有问题?我的代码如下。

   actionMoveLeft = SKAction.moveBy(x: -3, y: 0, duration: 0.1)
    actionMoveRight = SKAction.moveBy(x: 3, y: 0, duration: 0.1)
    self.addChild(ship)
    if motionManager.isAccelerometerAvailable == true {
        motionManager.startAccelerometerUpdates(to: OperationQueue.current!, withHandler:{
            data, error in
            if (data!.acceleration.y) < -0.05 {
                self.ship.run(self.actionMoveLeft)
            }

            else if data!.acceleration.y > 0.05 {
                self.ship.run(self.actionMoveRight)
            }

        })

    }

1 个答案:

答案 0 :(得分:1)

不能保证加速度计会定期为0.1秒提供更新(假设 CMMotionManager 实例的 deviceMotionUpdateInterval 属性设置为0.1)。当每个动作以不连续的时间间隔执行时,SKActions工作正常。但由于加速计为您提供不规则的间隔更新,您最终可能会同时执行更多操作。

一个简单的解决方法是每次都删除以前的操作:

if (data!.acceleration.y) < -0.05 {
    self.ship.removeAction(forKey: "Move")
    self.ship.run(self.actionMoveLeft, withKey: "Move")
}

但我仍然不建议使用这种方法,因为机芯看起来仍然不平滑,但看起来你的船正在急剧移动。我建议使用 SKPhysicsBody 并直接操作其 velocity 属性。像这样:

// Inside the update method, assuming you have saved the acceleration vector
// and you have a deltaTime variable that holds the difference of time
// elapsed from the previous update
self.ship.physicsBody.velocity = CGVector(dx: self.ship.physicsBody.velocity.dx + CGFloat(acceleration.x * deltaTime), dy: self.ship.physicsBody.velocity.dy + CGFloat(acceleration.y * deltaTime))    

如果您不想使用物理机构,因为您只是使用自定义函数处理物理,那么我建议您在每一帧手动计算船舶的位置。