"Tap To Resume" 暂停文本 SpriteKit

"Tap To Resume" Pause text SpriteKit

我知道 SpriteKit 已经在应用程序进入非活动状态时处理暂停游戏,但我想做的是在应用程序重新进入活动状态时添加一个 SKLabelNode "tap to resume"。现在它正确地调用了我的函数并暂停了游戏,但是文本没有显示。

AppDelegate.swift

func applicationWillResignActive(application: UIApplication) {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
    println("applicationWillResignActive")
    NSNotificationCenter.defaultCenter().postNotificationName("PauseGameScene", object: self)
    NSNotificationCenter.defaultCenter().postNotificationName("ShowPauseText", object: self)
    ...
}

GameScene.swift

class GameScene: SKScene, SKPhysicsContactDelegate {
    ...
    let tapToResume = SKLabelNode(fontNamed: "Noteworthy")
    ...
    override func didMoveToView(view: SKView) {
        ...
        NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("pauseGameScene"), name: "PauseGameScene", object: nil)
        NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("showPauseText"), name: "ShowPauseText", object: nil)

        tapToResume.text = "tap to resume"
        tapToResume.position = CGPoint(x:CGRectGetMidX(self.frame), y:CGRectGetMidY(self.frame))
        tapToResume.fontSize = 55
        tapToResume.hidden = true
        self.addChild(tapToResume)
        ...
    }

    func pauseGameScene() {
        println("pause game")
        self.view?.paused = true
    }

    func showPauseText() {
        if self.view?.paused == true {
            tapToResume.hidden = false
            println("show text")
        }
    }

    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
        ...
        if self.paused {
            self.view?.paused = false
            if tapToResume.hidden == false {
                tapToResume.hidden = true
            }
        }
    }
    ...
}

编辑:

下面是我的终端输出的屏幕截图,其中包含我对上述代码的最新编辑:

我想我遇到了问题。您应该先致电 pauseGameScene()。那么view?.paused就是true那么你可以调用showPauseText().

希望对您有所帮助:)

我相信您的问题是设置 self.view?.paused = true,正如@Steve 在评论中和@Linus G. 在他的回答中指出的那样。因此,当您尝试取消隐藏标签时,没有任何反应,因为视图已暂停。

我尝试使用 self.paused 来暂停 SKScene。这解决了显示标签的问题,但实际上并没有暂停场景。这可能是由于:自 iOS8 起,SpriteKit 会在进入后台时自动暂停您的游戏,并在进入前台时自动取消暂停游戏。因此,尝试使用 applicationWillResignActive 设置 self.paused = true 没有效果,因为它在进入前台时未暂停。

要解决这个问题你可以观察UIApplicationWillResignActiveNotification。然后,当应用程序要退出活动状态时,您设置 self.speed = 0,这与暂停 SKScene 具有相同的效果。这将显示标签并根据需要暂停场景。

例如:

class GameScene: SKScene {
    let tapToResume = SKLabelNode(fontNamed: "Noteworthy")

    override func didMoveToView(view: SKView) {
        NSNotificationCenter.defaultCenter().addObserver(self, 
                             selector: Selector("pauseScene"), 
                             name: UIApplicationWillResignActiveNotification, 
                             object: nil)

        tapToResume.text = "tap to resume"
        tapToResume.position = CGPoint(x: frame.midX, y: frame.midY)
        tapToResume.fontSize = 55
        tapToResume.hidden = true
        self.addChild(tapToResume)
}

func pauseScene() {
    self.speed = 0.0
    tapToResume.hidden = false
}

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    // Check the label was pressed here.
    if labelWasPressed {
        self.speed = 1.0
        tapToResume.hidden = true
    }
}

所以我 "hacked" 我的解决方案在这里。感谢 ABakerSmith 和设置 self.speed = 0.0 的建议,操作被暂停,我的标签将出现,但 physicsWorld 仍然有效。所以我的解决方案是设置 self.speed = 0.0self.physicsWorld.speed = 0.0。当应用程序从非活动状态 returns 时,我只是重置 self.speed = 1.0self.physicsWorld.speed = 1.0。我确信对于这个困境还有其他解决方案,但由于 SpriteKit 已经处理了中断,我真正需要做的就是暂停动作和物理。

GameScene.swift

class GameScene: SKScene, SKPhysicsContactDelegate {
    let tapToResume = SKLabelNode(fontNamed: "Noteworthy")
    ...

    override func didMoveToView(view: SKView) {
        ...
        NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("pauseGameScene"), name: "PauseGameScene", object: nil)
        NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("showPauseText"), name: "ShowPauseText", object: nil)
    }

    func pauseGameScene() {
        self.physicsWorld.speed = 0.0
        self.speed = 0.0
    }

    func showPauseText() {
        if self.physicsWorld.speed == 0.0 {
        tapToResume.hidden = false
        }
    }

    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
        ...
        if self.physicsWorld.speed == 0.0 {
            self.physicsWorld.speed = 1.0
            self.speed = 1.0
            if tapToResume.hidden == false {
                tapToResume.hidden = true
            }
        }
    }

    ...
}

AppDelegate.swift

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    func applicationWillResignActive(application: UIApplication) {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
    NSNotificationCenter.defaultCenter().postNotificationName("PauseGameScene", object: self)
    NSNotificationCenter.defaultCenter().postNotificationName("ShowPauseText", object: self)
    }
    ...
}