“点击恢复”暂停文本 SpriteKit

Posted

技术标签:

【中文标题】“点击恢复”暂停文本 SpriteKit【英文标题】:"Tap To Resume" Pause text SpriteKit 【发布时间】:2015-04-20 19:33:45 【问题描述】:

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

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
            
        
    
    ...

编辑:

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

【问题讨论】:

您不应该设置SKLabelNodetext 属性吗?还是您只是没有在上面的代码中包含该位? 抱歉,代码在那里,只是忘记添加了 您是否在暂停视图之前调用 showPauseText?您似乎是先暂停,然后再尝试取消隐藏文本。 我只是尝试切换它们,先调用显示文本,文本仍然没有显示出来。 可能是您的fontNamed 参数(当您声明标签时)传递给它的字体名称不正确,或者标签可能隐藏在另一个精灵后面,因为它的 z-index 较低? 【参考方案1】:

所以我在这里“破解”了我的解决方案。感谢ABakerSmith 和设置self.speed = 0.0 的建议,操作被暂停,我的标签会出现,但physicsWorld 仍然处于活动状态。所以我的解决方案是设置self.speed = 0.0self.physicsWorld.speed = 0.0。当应用程序从非活动状态返回时,我只需重置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)
    
    ...

【讨论】:

【参考方案2】:

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

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

要解决这个问题,您可以观察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
    

【讨论】:

感谢您的建议。虽然这确实允许“点击恢复”标签在应用程序进入非活动状态时取消隐藏,并允许我在返回并单击它时隐藏标签,但我的“飞扬的小鸟”(实际上是柯比,童年的最爱)仍然受到physicsWorld的影响并掉到地上。 tl;dr 将速度设置为 0.0 会停止世界,但不会停止我的柯比精灵。【参考方案3】:

我想我有问题。您应该先致电pauseGameScene()。那么view?.paused 就是true那么您可以拨打showPauseText()

希望有帮助:)

【讨论】:

嗨 Linus,我将我的 showPauseText() 函数移动到了 AppDelegate 函数 applicationWillEnterForeground(),这样当应用程序从非活动状态返回时,它会显示文本。但仍然没有运气。我已在原始帖子中更新了代码以反映更改,并且还添加了终端输出。 忽略以上。嗨,Linus,我对我的代码做了一些改动,并按照你的建议放回了我的打印语句。该标签仍未显示,但您可以看到它正在被调用。

以上是关于“点击恢复”暂停文本 SpriteKit的主要内容,如果未能解决你的问题,请参考以下文章

在 SpriteKit 中暂停游戏后文本消失

如何在单击按钮时暂停读取文本文件并在 mfc vc++ 中的单击按钮时恢复它?

更改单击脚本上的文本

bat脚本常用命令汇总

检测用户何时停止/暂停在 TextField 中写入 - SwiftUI

如何触发延迟到用户暂停输入的 onkeyup 事件?