ios - map 设备倾斜到物理世界重力?

标签 ios sprite-kit cmmotionmanager

我正在构建一个“弹珠”迷宫游戏以学习 spritekit 基础知识。

我想将游戏的重力映射到设备的倾斜度。我一直在努力弄清楚如何去做,但我只能成功地映射 y 轴:

class func obtainGravity(motionManager: CMMotionManager) {
    var vec = CGVectorMake(0, 0)
    if let attitude = motionManager.deviceMotion?.attitude? {
        let y = CGFloat(-attitude.pitch * 2 / M_PI) // This works, it returns 1/-1 when the device is vertical (1 when the home button is upside down)
        let x = CGFloat(attitude.roll * 2 / M_PI) // This doesn't work
        physicsWorld.gravity = CGVectorMake(x, y)
    }
}   

我可以映射使球“向上”或“向下”移动的 Y 轴(相对于纵向模式),但我不明白如何映射 X 轴(从设备侧面拉动)。

例如,当把设备平放在 table 上时 (x, y) 应该是 (0,0) 并且当把它放在 table 上屏幕向下时它也应该是 (0,0) 但是 attitude.roll 返回-179。此外,如果我保持我的设备垂直(纵向模式)并打开我的脚保持设备静止,重力应该保持(x:0,y:1)但是 x 继续变化,因为它基于 attitude.roll

如何做到这一点?

最佳答案

最直接的方法是获取加速度计更新,而不是设备运动更新,并直接从那里读取重力矢量——这正是加速度计捕获的内容:设备坐标系中的重力测量值。

遗憾的是,我是一个 Swift thickie,所以无法提供示例代码,但您希望提供一个类型为 CMAccelerometerHandler 的 block ,它将接收一个 CMAccelerationData,从中您可以获得 CMAcceleration 结构,即直接应用的重力矢量。

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

关于ios - map 设备倾斜到物理世界重力?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25069161/

相关文章:

ios - 基本 while 循环中索引超出范围

swift - 如何缩放半径以适应所有设备?

ios - 运动事件在iOS中处于挂起状态

ios - 你怎么知道 iPhone 是哪个方向的?

swift - Sprite Kit 随机位置

swift - CMMotionManager 倾斜以左右移动节点 Swift 4

ios - 如何将 View 从一个 viewController 移动到另一个

ios - 大小类问题

iOS 11 [NSTimeZone localTimeZone] 忽略 [NSTimeZone defaultTimeZone];

swift - 如何让 Sprite 在圆圈内遵循随机模式?