我得到了我的用户的反馈,“我的游戏 - 应用程序有时会出现一个错误,即船舶完全无法控制。在对此进行调查之后,CoreMotion报告的态度看起来非常快(低于一秒)并且它会突然消失。您可以玩最多五分钟,然后突然发生船舶移动到其中一个屏幕边框并且不再远离该点。
我的问题:有没有人对CoreMotion的态度有相同的体验,你有什么方法或想法来控制这些突如其来的大规模漂移?
我用来获取SpriteKit update()
态度的代码是:
if let motion = motionManager.deviceMotion {
let x = CGFloat(motion.attitude.yaw - basePosition.x)
let y = CGFloat(motion.attitude.roll - basePosition.y)
ship.physicsBody?.applyImpulse(CGVectorMake(X_SENSITITVITY * x, Y_SENSITITVITY * y))
}
其中basePosition
,X_SENSITITVITY
,Y_SENSITITVITY
是游戏中的常量值。
motionManager
由班级顶部的private var motionManager = CMMotionManager()
定义。
据我了解文档,deviceMotion
使用重力和态度测量的组合来最小化长期漂移。
也许重要的是要注意:当游戏在没有汽车等振动的静音环境中运行时,它的工作原理非常好。 我想让人们在需要休息的时候玩我的游戏 - 比如乘坐长途火车或飞机 - 或者坐在汽车后座的小孩。
答案 0 :(得分:1)
我发现了同样的漂移问题。我将CMDeviceMotion的态度与CLLocation的magneticHeading进行了比较。因此,我在一张小桌子周围走了10次,然后在每一轮之后将设备放在同一个地方。
我发现,DeviceMotion的态度每轮都会漂移30度左右。因此,在10轮之后,态度大约是300度。 根据Apple的WWDC 2012演讲“Session 524:了解核心运动”,使用的传感器融合取决于指定的参考框架。 Phil Adam提到,如果指定了xArbitraryCorrected参考帧,传感器融合算法也会使用磁力计。我使用xArbitrary,xArbitraryCorrected和xMagneticNorth进行了相同的测试,但没有区别。指南针的不确定性大约为2-3度(标题滤波器为1.0度)。
也许这是一个错误,我不知道。但我预计至少xArbitrary和xArbitraryCorrected之间存在差异。
答案 1 :(得分:0)
根据我的理解,您可以依赖两件事:
CMDeviceMotion.rotationRate
CMDeviceMotion.gravity
看起来第一个通过读取某种当前力来使用当前位置的变化。这是一个当前值,并且不需要总结这些值 - 因此不会总结错误。
第二个(重力)测量当前对地球的力量。再次:当前值,没有总结,没有错误总和,没有漂移。
其他任何事情,特别是CMDeviceMotion.attitude
,都会采取措施并加以补充。导致每个度量中的小错误相加,导致结果漂移。
我试图使用转速并通过累加来计算自己的态度。好吧,Apple在这方面并不完美,但比我的任何解决方案都要好: - )
update()
期间调用此方法(对于每个帧)
private func update(ship: SKSpriteNode) {
// Orientation can be landscape left or right
let orientation = UIApplication.sharedApplication().statusBarOrientation == UIInterfaceOrientation.LandscapeLeft ? -1.0 : 1.0
// Get rotation rate
let x = orientation*motionManager.deviceMotion.rotationRate.x
let y = orientation*motionManager.deviceMotion.rotationRate.y
// If user tilts device very slow it does not affect the ship
let xf = CGFloat(abs(x) >= X_RESPONSIVNESS ? X_SENSITITVITY*x : 0.0)
let yf = CGFloat(abs(y) >= Y_RESPONSIVNESS ? Y_SENSITITVITY*y : 0.0)
// Apply as impulse
ship.physicsBody?.applyImpulse(CGVectorMake(xf, yf))
}
由于我的游戏更多关于"用户如何倾斜设备让我知道您希望船舶前往何处?我只是用rotationRate
来衡量这个并将其作为冲动来应用。作为附件,您可以旋转设备,这意味着朝向屏幕顶部的旋转实际上是旋转后向底部的旋转。所以我必须在旋转设备时反转脉冲。
您现在可以向任何方向玩游戏。在汽车或火车等振动的环境中,景观向左,横向,在头顶。它就像一个魅力。我甚至期待下周六的2.5小时航班......