使用CMDeviceMotion获取绝对旋转?

lis*_*aro 4 accelerometer ios gyroscope cmmotionmanager swift

我正在使用Sprite Kit构建一个简单的游戏,屏幕不会旋转,但我想知道用户拿着手机进行游戏机制的角度.

可以使用加速度计(x,y)轻松检索我想要获取的值,但我发现这是不可靠的,所以我试图存档更好的结果CMDeviceMotion.我可以获得相当于data.acceleration.y但我无法弄清楚如何得到相当于data.acceleration.x.

if let data = motionManager.accelerometerData? {
    let y = CGFloat(data.acceleration.y)
    let x = CGFloat(data.acceleration.x)
}

// Device Motion
if let attitude = motionManager.deviceMotion?.attitude? {
    let y = CGFloat(-attitude.pitch * 2 / M_PI) // This matches closely with data.acceleration.y
    let x = ??????????
}
Run Code Online (Sandbox Code Playgroud)

我如何计算data.acceleration.x使用的等价物CMDeviceMotion

Mic*_*lum 8

如果您希望旋转值考虑陀螺仪和加速度计输入,听起来您想要运动管理器的设备运动.根据文件:

CMDeviceMotion的一个实例封装了设备的姿态,旋转速率和加速度的测量值.

因此,不是直接监控陀螺仪数据,而是监控设备运动.下面的示例演示了如何逐帧获取设备运动.我刚刚决定CMAttitude直接打印对象,但是从这个对象,你可以直接访问设备的俯仰,滚动和偏航(以及更多),如果我没有弄错的话,那正是你正在寻找的.

import SpriteKit
import CoreMotion

class GameScene: SKScene {
    let motionManager = CMMotionManager()

    override func didMoveToView(view: SKView) {
        motionManager.deviceMotionUpdateInterval = 1.0 / 30.0
        motionManager.startDeviceMotionUpdates()
    }

    override func willMoveFromView(view: SKView!) {
        motionManager.stopDeviceMotionUpdates()
    }

    override func update(currentTime: CFTimeInterval) {
        if let attitude = motionManager.deviceMotion?.attitude? {
            println(attitude)
            let y = CGFloat(-attitude.pitch * 2 / M_PI)
            let x = CGFloat(-attitude.roll * 2 / M_PI)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您使用的是Swift 2,则需要进行一些小的更改,如下所示.

class GameScene: SKScene {
    let motionManager = CMMotionManager()

    override func didMoveToView(view: SKView) {
        motionManager.deviceMotionUpdateInterval = 1.0 / 30.0
        motionManager.startDeviceMotionUpdates()
    }

    override func willMoveFromView(view: SKView) {
        motionManager.stopDeviceMotionUpdates()
    }

    override func update(currentTime: CFTimeInterval) {
        if let attitude = motionManager.deviceMotion?.attitude {
            print(attitude)
            let y = CGFloat(-attitude.pitch * 2 / M_PI)
            let x = CGFloat(-attitude.roll * 2 / M_PI)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅此图像.

在此输入图像描述