检测旋转完成后移动到新场景

时间:2017-04-24 04:57:23

标签: ios swift sprite-kit

我正在尝试在车轮停止旋转时移动到另一个场景。我的代码如下所示。我无法弄清楚如何检测速度何时达到0.0?

import SpriteKit
import GameplayKit

class GameplayScene: SKScene {

    var player: Player?;

    override func didMove(to view: SKView) {
        player = self.childNode(withName: "spinner") as! Player?;
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches {
            let location = touch.location(in: self)
            if atPoint(location).name == "play_button" {
               spin()
            }
        }
    }

    func spin () {
        let random = GKRandomDistribution(lowestValue: 20, highestValue: 90)
        let r = random.nextInt()
        player?.physicsBody = SKPhysicsBody(circleOfRadius: CGFloat(self.frame.width))
        player?.physicsBody?.affectedByGravity = false
        player?.physicsBody?.isDynamic = true
        player?.physicsBody?.allowsRotation = true
        player?.physicsBody?.angularVelocity = CGFloat(r)
        player?.physicsBody?.angularDamping = 1.0
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {

     }
}

所以从这里开始,我想在车轮停止旋转时执行以下操作:

let play_scene = Questions(fileNamed: "QuestionsScene")
play_scene?.scaleMode = .aspectFill
self.view?.presentScene(play_scene!, transition: SKTransition.doorsOpenVertical(withDuration: 1))

我现在编辑了这个类,它看起来如下:

import SpriteKit
import GameplayKit

class GameplayScene: SKScene, SKSceneDelegate {


var player: Player?

override func didMove(to view: SKView) {
    self.delegate = self
    player = self.childNode(withName: "spinner") as! Player?;

}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    for touch in touches {
        let location = touch.location(in: self)
        if atPoint(location).name == "play_button" {
            spin()
        }
    }
}
    func spin () {
        let random = GKRandomDistribution(lowestValue: 20, highestValue: 90)
    let r = random.nextInt()
    player?.physicsBody = SKPhysicsBody(circleOfRadius: CGFloat(self.frame.width))
    player?.physicsBody?.affectedByGravity = false
    player?.physicsBody?.isDynamic = true
    player?.physicsBody?.allowsRotation = true
    player?.physicsBody?.pinned = true
    player?.physicsBody?.angularVelocity = CGFloat(r)
    player?.physicsBody?.angularDamping = 1.0

}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {

}
    override func didSimulatePhysics() {
        if ((player?.physicsBody?.angularVelocity)! <= CGFloat(0.01)) 
        {
            print("Got it")
        }
    }
}

问题是我仍然在didSimulatePhysics函数中的if语句上收到错误。我收到的错误是“主题1:EXC_BAD_INSTRUCTION ....”

1 个答案:

答案 0 :(得分:4)

你的轮子SKPhysicsBody有一个内置属性angularVelocity,告诉你它的旋转速度有多快。当您将其设置为r以启动车轮旋转时,您已经在使用它。

要观看angularVelocity,您可以使用didSimulatePhysics()。物理计算完成后,每帧调用一次。这看起来像这样:

func didSimulatePhysics() {
    if wheelIsSpinning && angularVelocity != nil && angularVelocity! <= CGFloat(0.001) {
        wheelIsSpinning = false
        // wheel has stopped
        // add your code here
    }
}

由于物理建模的变幻莫测,angularVelocity可能永远不会完全为零。因此,我们注意它低于某个任意阈值,在这种情况下为0.001。

当滚轮没有移动时,你不希望它执行每一帧,所以我添加了一个属性wheelIsSpinning来跟踪。您需要将其作为实例属性添加到GameplayScene,并在spin()中将其设置为true。