【问题标题】:Detect when rotation has completed and move to new Scene检测旋转何时完成并移动到新场景
【发布时间】:2017-04-24 04:57:23
【问题描述】:

我正在尝试在车轮停止旋转时移动到另一个场景。我的代码如下所示。我不知道如何检测速度何时达到 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....”

【问题讨论】:

    标签: ios swift sprite-kit


    【解决方案1】:

    您的轮子的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。

    【讨论】:

    • 谢谢罗伯特。后来我发现,即使当我将速度打印到控制台时,轮子看起来已经停止了,但它看起来仍然旋转得如此缓慢。它从未真正停止过
    • @Nick 只需检查.angularVelocity &lt;= 0.001 或其他任意低值。
    • @Robert 将场景设置为自己的委托没有意义。在SKSceneDelegate 协议中找到的所有方法,包括didSimulatePhysics(),都会在SKScene 及其子类上自动调用。设置一些其他类来实现这个协议会更有意义......
    • @Nick 除了您不需要该行之外,如果您仍然想要类似的东西,请将self.delegate = self 放入init() 或其他适当的方法中。你不能在类的主体中使用 self。
    • @Nick 从场景的定义中删除 SKSceneDelegate 一致性(你的场景应该看起来像这样 class GameplayScene: SKScene{ }。从你的代码中删除 self.delegate = self。当你这样做时,告诉我错误是什么。一切否则罗伯特说,应该工作。符合SKSceneDelegate 是不必要的。这就是我的观点。
    猜你喜欢
    • 2018-06-09
    • 1970-01-01
    • 1970-01-01
    • 2020-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-05
    • 1970-01-01
    相关资源
    最近更新 更多