加速度计的正确使用方法

Correct Way to use 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)
            }

        })

    }

不能保证加速度计会以 0.1 秒的固定间隔为您提供更新(假设 deviceMotionUpdateInterval 属性 您的 CMMotionManager 实例设置为 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))    

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