Swift 3 (SpriteKit): 停止永远循环的 SKAction 有延迟

Swift 3 (SpriteKit): Stopping a forever looping SKAction has a delay

我一直在努力做一个永远的 运行ning SKAction,我可以随时停止。我是这样做的:

override func didMove(to view: SKView) {

    run(SKAction.repeatForever (
        SKAction.sequence ([
            SKAction.run(drawFrame),
            SKAction.wait(forDuration: 0.01),
            ])), withKey: "frameDrawing"
    )
}

然后在 drawFrame 函数中,我像这样停止 SKAction:

func drawFrame() {
    //(code)
    if stop {
        removeAction(forKey: "frameDrawing")
    }
}

出于某种原因,SKAction 仅在停止变为真后 运行 3 或 4 次时才停止。我希望它在 stop 设置为 true 时立即停止,而不是在重复 3 或 4 次之后。

如果有人知道如何解决这个问题,请告诉我,因为我已经尝试了很多方法,但他们从未解决过这个问题。谢谢!

编辑:这是我的代码:

var drawingFrame = SKAction()
class GameScene: SKScene, SKPhysicsContactDelegate {

override func didMove(to view: SKView) {

    drawingFrame = SKAction.repeatForever (
        SKAction.sequence ([
            SKAction.run(drawFrame),
            SKAction.wait(forDuration: 0.03),
            ]))
    run(drawingFrame)
}

func drawFrame() {
   //(code)
    if stop {
        drawingFrame.speed = 0.0
    }
}

如果您想知道为什么我一开始就将 SKAction drawingFrame 设置为空 SKAction,那是因为我需要在两个函数之前定义 SKAction。否则,不会为这两个函数定义它。

为遇到同样问题的任何人编辑:我已经用我自己的想法和@appzYourLife 的解决方案解决了这个问题。每次都有效的最有效方法是仅 运行 如果 stop 等于 false 的代码。但是,请确保停止程序的 if 语句在该括号之外,以便 SKAction 最终停止。这是工作代码:

var drawingFrame = SKAction()
class GameScene: SKScene, SKPhysicsContactDelegate {

override func didMove(to view: SKView) {

    drawingFrame = SKAction.repeatForever (
        SKAction.sequence ([
            SKAction.run(drawFrame),
            SKAction.wait(forDuration: 0.03),
            ]))
    run(drawingFrame)
}

func drawFrame() {
    if stop = false {
       //(code)
    }
    if stop {
        removeAllActions()
    }
}

如果您愿意,可以对 stop = false 语句使用 if else 语句。

尝试创建对 SKAction 的引用,并在您希望它停止时对其调用速度更改(至 0.0)。这两者都比查找操作名称然后将其删除要快。但是在 0.01 时,您已经以快于帧速率 (0.01666) 的速度重复它,因此无论您停止得有多好,您总是会至少获得一次额外的动作迭代。

类似于:

let myAction = SKAction.repeatForever (
        SKAction.sequence ([
            SKAction.run(drawFrame),
            SKAction.wait(forDuration: 0.01),
            ]))

//when you want to run it
run(myAction)

// when you want to stop it:
myAction.speed = 0.0

您可以删除当前节点上的所有操作运行。这不仅会立即删除序列动作,还会立即删除嵌入的动作。

func drawFrame() {
    if stop {
        removeAllActions()
    }
}

我没有确切的解释为什么 drawFrame() 目前被多次调用(但我会尝试发现 :D)...无论如何,试试这个代码:

import SpriteKit

class GameScene: SKScene, SKPhysicsContactDelegate {



    var stop = false

    override func didMove(to view: SKView) {

        run(SKAction.repeatForever (
            SKAction.sequence ([
                SKAction.run({[unowned self] in
                    if self.stop {
                        self.action(forKey: "frameDrawing")?.speed = 0.0
                    }else{
                        self.drawFrame()
                    }

                }),
                SKAction.wait(forDuration:0.03),
                ])), withKey: "frameDrawing"
        )
    }

    func drawFrame() {
        //(code)
        print("drawFrame")

    }
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)
        stop = !stop
        print(stop ? "stopped": "running")
        if !stop {
              self.action(forKey: "frameDrawing")?.speed = 1.0
        }
    }
}

使用 touchesBegan 切换暂停模式。