加速度计的正确使用方法
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))
如果您不想使用物理体,因为您只是使用自定义函数处理物理,那么我建议您在每一帧手动计算飞船的位置。
我使用加速度计作为游戏的转向机制。它通常工作正常,但偶尔会表现得很奇怪。随机地突然出现大量的输入延迟,我做的每一次旋转都有一段时间没有注册。在某些情况下,紧接着输入的命令之间可能会有很多延迟,导致我的角色在一个方向上漂移的时间太长。这是由于游戏延迟还是我的代码有问题?我的代码如下。
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))
如果您不想使用物理体,因为您只是使用自定义函数处理物理,那么我建议您在每一帧手动计算飞船的位置。