Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

When returning to my App after closing it the applicationDidBecomeActive(application: UIApplication) automatically fires in AppDelegate.swift. This fires a method that handles the paused status of the app: GameViewController().pause(true)

The method looks like this:

func pause(paused: Bool) {
    if paused == true {
        scene?.paused = true
        print("paused")

    } else if paused == false {
        scene?.paused = false
        print("unparsed")
    }
}

When first launching the app the Game is automatically paused which is exactly what should happen. When returning to the app it unpauses though. Still, the Console prints "paused".

I have also tried using scene?.view?.paused instead of scene?.paused. This does work, but leads to lag in the animations running on the scene.

Any help would be highly appreciated

EDIT

I managed to solve the problem by calling the pause() method in the update(currentTime: NSTimeInterval) function but I don't like this solution as it means the method is called once per frame. Other solutions would be highly appreciated

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
195 views
Welcome To Ask or Share your Answers For Others

1 Answer

This code makes no sense

GameViewController().pause(true)

because you are creating a new instance of GameViewController rather than accessing the current one.

Rather than pausing the whole scene you should just pause the nodes that you would liked paused. Usually you create some kind of worldNode in your game scene (Apple also does this in DemoBots)

class GameScene: SKScene {

     let worldNode = SKNode()

     // state machine, simple bool example in this case
     var isPaused = false

   ....
 }

than add it to the scene in DidMoveToView

override func didMoveToView(view: SKView) {
     addChild(worldNode)
}

Than all nodes that you need paused you add to the worldNode

worldNode.addChild(YOURNODE1)
worldNode.addChild(YOURNODE2)

Than your pause function should look like this

 func pause() {
     worldNode.paused = true
     physicsWorld.speed = 0
     isPaused = true
 }

and resume like this

  func resume() {
     worldNode.paused = false
     physicsWorld.speed = 1
     isPaused = false
 }

Lastly to make sure the game is always paused when in paused add this to your update method. This ensures that you game does not resume by accident e.g due to app delegate, iOS alerts etc.

  override func update(currentTime: CFTimeInterval) {

      if isPaused {
         worldNode.paused = true
         physicsWord.speed = 0
         return
      }

     // Your update code
     ...
  }

To call these from your AppDelegate you should use delegation or NSNotificationCenter as has been mentioned in one of the comments.

In gameScene create the NSNotifcationObserver in didMoveToView

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(pause), name: "Pause", object: nil) // in your app put the name string into a global constant property to avoid typos when posting 

and in appDelegate post it at the correct spot

NSNotificationCenter.defaultCenter().postNotificationName("Pause", object: nil)

The main benefit with the worldNode approach is that you can easily add pause menu sprites etc while the actual game is paused. You also have more control over your game, e.g having the background still be animated while game is paused.

Hope this helps.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...