SpriteKit:在场景暂停时运行动作

11

我有一个按钮可以暂停我的代码。我想要的是,用这个按钮暂停游戏时显示一个说“已暂停”的消息。然而,由于场景已经暂停了,消息没有出现。

我现在拥有一个SKLabelNode,在开始时alpha为0.0,当用户暂停游戏时,它会使用fadeInWithDuration()变为1.0。然后当用户再次按下按钮时,它会使用fadeOutWithDuration()变回0.0。问题是,当场景暂停时,带有fadeInWithDuration()的SKAction不会运行。

我该怎么做才能实现这个功能?

5个回答

14

最好的方法,苹果公司在“DemoBots”中也使用了这种方法,即创建一个世界节点来暂停,而不是场景。

创建一个worldNode属性。

class GameScene: SKScene {

    let worldNode = SKNode()
}

将其添加到 didMoveToView 方法中的场景中。

addChild(worldNode)

然后将需要暂停的所有内容添加到worldNode中。这包括通常由场景运行的动作(例如计时器、敌人生成等)。

worldNode.addChild(someNode)
worldNode.run(someSKAction)

然后在您的暂停函数中,您说

worldNode.isPaused = true
physicsWorld.speed = 0

并且在简历中

worldNode.isPaused = false
physicsWorld.speed = 1

如果您的Update函数中有需要在暂停时忽略的内容,您还可以在其中添加额外的检查。

override func update(_ currentTime: CFTimeInterval) {

    guard !worldNode.isPaused else { return }

    // your code
}

这种方式使得在游戏暂停时添加已暂停标签或其他UI更加容易,因为您实际上并没有暂停场景。除非该操作已添加到worldNode或worldNode的子节点中,否则您也可以运行任何想要的操作。

希望这能有所帮助。


你救了我,伙计!非常感谢这个解决方案,因为它解决了我另一个暂停问题!看起来是因为我从根节点暂停...这会在取消暂停时导致物理上的滞后..现在有了SKNode解决方案,一切都完美运作! - msqar

3

而不是暂停场景,您可以像这样在场景中分层一些节点

 SKScene
 |--SKNode 1
 |  |-- ... <--place all scene contents here
 |--SKNode 2
 |  |--  ... <--place all overlay contents here

当您想要暂停游戏时,只需暂停SKNode 1。

这样可以让节点SKNode 2继续运行,因此您可以执行动画等操作,并拥有一个按钮来为您取消场景的暂停状态,而无需将一些非Sprite Kit对象添加到混合中。


2

一个快速的解决方法是在SKLabelNode出现在屏幕上后暂停游戏:

let action = SKAction.fadeOutWithDuration(duration)
runAction(action) {
    // Pause your game
}

另一个选择是混合使用UIKit和SpriteKit,并通知ViewController需要显示此标签。
class ViewController: UIViewController {
    var gameScene: GameScene!

    override func viewDidLoad() {
        super.viewDidLoad()
        gameScene = GameScene(...)
        gameScene.sceneDelegate = self
    }
}

extension ViewController: GameSceneDelegate {
    func gameWasPaused() {
        // Show your Label on top of your GameScene
    }
}

protocol GameSceneDelegate: class {
    func gameWasPaused()
}

class GameScene: SKScene {
    weak var sceneDelegate: GameSceneDelegate?

    func pauseGame() {
        // Pause
        // ...
        sceneDelegate?.gameWasPaused()
    }
}

1

你想在动作执行完成之后暂停游戏。

class GameScene: SKScene {

    let pauseLabel = SKLabelNode(text: "Paused")

    override func didMoveToView(view: SKView) {
        pauseLabel.alpha = 0
        pauseLabel.position = CGPoint(x: CGRectGetMaxY(self.frame), y: CGRectGetMidY(self.frame))
        self.addChild(pauseLabel)
    }


    func pause(on: Bool) {
        switch on {
        case true: pauseLabel.runAction(SKAction.fadeInWithDuration(1)) {
            self.paused = true
        }
        case false:
            self.paused = false
            pauseLabel.runAction(SKAction.fadeOutWithDuration(1))
        }
    }
}

0

我会添加标签

self.addChild(nameOfLabel)

and then pause the game with

self.scene?.paused = true

这些代码应该全部放在“如果暂停按钮被触摸”的部分。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接