Ios 地图设备倾斜到物理世界重力?

Ios 地图设备倾斜到物理世界重力?,ios,sprite-kit,cmmotionmanager,Ios,Sprite Kit,Cmmotionmanager,为了学习spritekit的基础知识,我正在制作一个“大理石”迷宫游戏 我想将游戏的重力映射到设备的倾斜角度。我一直在努力想办法,但我只能成功地映射y轴: class func obtainGravity(motionManager: CMMotionManager) { var vec = CGVectorMake(0, 0) if let attitude = motionManager.deviceMotion?.attitude? { let y = CG

为了学习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轴(设备侧面的拉力)

例如,当将设备平放在工作台上时(x,y)应为(0,0),当将其放在工作台屏幕上时,也应为(0,0),但姿态。滚动返回-179。另外,如果我保持设备垂直(在纵向模式下)并打开脚使设备保持静止,重力应保持(x:0,y:1),但是x会继续变化,因为它基于姿态。滚动


如何做到这一点?

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

遗憾的是,我是一个敏捷的矮人,因此无法提供示例代码,但您希望提供一个类型为
cmAccelerometherHandler
的块,它将接收
CMAccelerationData
,您可以从中获得
CMAcceleration
结构,即直接应用的重力向量

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

对我来说,roll很管用。它返回[-pi/2,pi/2]中的值。你打电话给StartDeviceMotionUpdate了吗?是的,我打电话给你了,但是如果我把我的设备放在桌子上,屏幕朝下,姿态。滚动返回-pi,这不可能是正确的。你得到了同样的结果吗?实际上它返回-179,而在桌子上它应该返回0,我的姿态。滚动几乎为零-179? 你在转换学位吗?也许这是一个快速的问题。我用的是Objective-C。嗨,汤米,我为你的建议添加了代码。我试过加速计,但由于某种原因,游戏中的运动感觉不稳定。我测试了设备的运动和态度,突然一切都变得稳定了,所以我试着用它来做。您知道如果使用deviceMotion,是否可以获得与data.acceleration.x和data.acceleration.y匹配的值?您是否为
AccelerometrUpdateInterval
属性设置了自定义值?这将影响您获得更新的频率。一开始它可能会很低,因为加速计在设备中的原因是为了发现缓慢且不经常发生的广泛设备旋转事件。不,我没有。也许这就是问题所在,你知道我可以用什么初始值来测试它吗?
1.0/60.0
是一个很好的尝试值-这是设备的每帧时间。data.acceleration.x和data.acceleration.y已经在[-1,1]中了。您需要删除“*2/M_PI”。