CoreDeviceMotion无法更新物理世界的引力

时间:2015-01-29 07:51:27

标签: ios swift sprite-kit core-motion skphysicsworld

我正在尝试获取设备运动数据并改变重力方向,这样当我倾斜iPhone时,球会向倾斜方向移动。在这个tutorial中,该方法是在节点上获取加速度数据和applyForce。但是,我想通过改变重力方向来实现这个目标(无论我如何倾斜手机,重力始终沿着真实的物理重力方向)。

这是我的代码:

import SpriteKit
import CoreMotion
class GameScene: SKScene {
let ballName = "redBall"
var gravityDirection = CGVectorMake(0,-9.8)


let motionManager = CMMotionManager()
let motion = CMDeviceMotion()

func addBall(){
    //Create the ball
    var ball = SKShapeNode()
    var path = CGPathCreateMutable()
    CGPathAddArc(path, nil, 0, 0, 45, 0, CGFloat(M_PI * 2), true)
    CGPathCloseSubpath(path)
    ball.name = ballName
    ball.path = path
    ball.lineWidth = 2.0
    ball.fillColor = SKColor(red: 0.95, green: 0.2, blue: 0.2, alpha: 0.9)
    ball.position = CGPoint(x:size.width/2, y: size.height)

    //Set the ball's physcial properties
    ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.frame.width/2)
    ball.physicsBody!.dynamic = true
    ball.physicsBody!.mass = 0.1
    ball.physicsBody!.friction = 0.2
    ball.physicsBody!.restitution = 0.9
    ball.physicsBody!.affectedByGravity = true

    self.addChild(ball)
}

func gravityUpdated(){
    let vector = CGVectorMake(CGFloat(motion.gravity.x), CGFloat(motion.gravity.y))
    self.physicsWorld.gravity = vector
}

override func didMoveToView(view: SKView) {
    physicsBody = SKPhysicsBody(edgeLoopFromRect: view.frame)
    self.physicsWorld.gravity = gravityDirection
    motionManager.startDeviceMotionUpdates()
    addBall()
}


override func update(currentTime: CFTimeInterval) {
    gravityUpdated()
}
}

在上面的代码中,我使用CMDeviceMotion获取重力数据,并将重力值提供给physicsWorld.gravity。当我运行它时,应用程序总是崩溃。

Xcode表示gravityUpdate()函数存在错误,但我无法找到它。希望有人能帮我解决这个问题。或者为我提供一种模拟重力的更好方法。谢谢!

1 个答案:

答案 0 :(得分:0)

我自己已经弄清楚了。在将值赋予physicsworld.gravity之前,有必要检查运动数据是否可用。

这是新代码:

func gravityUpdated(){
    if let data = motionManager.deviceMotion {
        let gravity = data.gravity
        self.physicsWorld.gravity = CGVectorMake(CGFloat(gravity.x), CGFloat(gravity.y))
    }
}

请注意,如果没有可用的设备运动数据,则该属性的值为nil。 CMMotionManager Class Reference