0

It is my first post on this forum and I apologize in advance if I am doing something not in the right way ! :)

I am making an iphone game with Swift & SpriteKit and I am currently facing a problem. When my app is going to background it calls a function pause (cf. below) but it automatically unpause when the game resumes.

I have seen this very interesting post : Spritekit - Keep the game paused when didBecomeActive (and How to keep SpriteKit scene paused when app becomes active?) but I am stuck.

I don't know how to implement the new SKView class as my View is configured as shown in the below code...

This is how my application works :

class GameViewController: UIViewController {

var scene: GameScene!

override func viewDidLoad() {
    super.viewDidLoad()

    // Configure the View
    let SkView = view as! SKView
    SkView.multipleTouchEnabled = true

    // Create and configure the scene
    scene = GameScene(size: SkView.bounds.size)
    scene.scaleMode = .AspectFill

    // Present the scene
    SkView.presentScene(scene)

    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("PauseWhenBackGround:"), name:"PauseWhenBackGround", object: nil)
}

func PauseWhenBackGround(notification : NSNotification) {
    if scene.Pausing == false{
        scene.Pause()
    }
}

I've tried the following :

I added a new class which is :

class GameSceneView : SKView {      
    func CBApplicationDidBecomeActive() {
    }
}

Then, I tried to set my view as let SkView = view as! GameSceneView but I got an error saying that I cannot cast the view to MyProjectName.GameSceneView()... I also tried the following : let SkView! = GameSceneView() as GameSceneView! but I end up with a gray background scene...

Does anyone knows how I can implement the new SKView class to prevent the CBApplicationDidBecomeActive() bug from happening so that the game does not unpause when becoming active ?

Thank you very much in advance ! :)

Community
  • 1
  • 1

1 Answers1

0

I think a better way is instead of pausing the whole scene you could create a worldNode in your GameScene and add all the sprites that need to be paused to that worldNode. Its better because if you pause the scene you cannot add pause menu nodes or use touches began etc. It basically gives you more flexibility pausing a node rather than the whole scene.

First create the world node (make global property if needed)

 let worldNode = SKNode()
 addChild(worldNode)

Than add all the sprites you need paused to the worldNode

 worldNode.addChild(sprite1)
 worldNode.addChild(sprite2)

Create an enum for your different game states

enum GameState {
    case Playing
    case Paused
    case GameOver
    static var current = GameState.Playing
}

Than make a pause func in your game scene

 func pause() {
     GameState.current = .Paused
     //self.physicsWorld.speed = 0 // in update
     //worldNode.paused = true     // in update

     // show pause menu etc
 }

And call it like you did above using NSNotification or even better using delegation.

I prefer this method way more than pausing the scene from the gameViewController and also pausing the whole scene.

Create a resume method

 func resume() {
        GameState.current = .Playing
        self.physicsWorld.speed = 1
        worldNode.paused = false  

        // remove pause menu etc
 }

and finally add this to your update method

override func update(currentTime: CFTimeInterval) {

  if GameState.current == .Paused { 
      self.physicsWorld.speed = 0
      worldNode.paused = true
}

Spritekit sometimes tends to resume the game when the app becomes active again or when an alert such as for in app purchases is dismissed. To avoid this I always put the code to actually pause the game in the update method.

Hope this helps.

crashoverride777
  • 10,581
  • 2
  • 32
  • 56
  • Thank you for your answer ! I used a bool and set it to true when the pause function is called and when the application becomeactive again I put this in my scene update function `if Pausing==true && self.paused==false{self.paused=true}` so the game is put back to pause. Pausing the world node is a problem for me as it does not stop the physics as well so my character just falls when worldnode stops !:) – CharlyStudio Jan 07 '16 at 09:33
  • Glad it helped. I just update the answer, if you want to use the worldNode and pause physics you need to set the physicsWorld.speed = 0. This way your guy won't fall through. I forgot this before. Happy coding – crashoverride777 Jan 07 '16 at 11:36
  • hi, also having the same problem ! I tried a worldNode solution - but now i can't get touches to work !! :( – Adam Jan 18 '16 at 20:51
  • i got touches working ... but.. guess what.. things still unPause when i go back to game from exiting the app.. i can't understand it ?! – Adam Jan 18 '16 at 22:33
  • so.. i call a notification to run pauseGame() – Adam Jan 18 '16 at 22:50
  • the func is run and i print to console - worldNode.paused and it says true - but my sprites are all still moving!! what is going on ?! – Adam Jan 18 '16 at 22:50
  • Did you add all your sprites to worldNode as in worldNode.addChild. Also I forgot you probably need to set some bool value to true when game is paused. Than in your update method say "if paused { //pause game}. Spritekit sometimes resumes the game by itself, this also tends to happen once an inAppPurchase is completed. Just have the paused check in your update method – crashoverride777 Jan 19 '16 at 11:40
  • i think i got it working thanks to this ! i had to put in a short delay into the update method or it would freeze everything too quickly.. a 0.1second delay sorts it out! thanks ! – Adam Jan 19 '16 at 19:39
  • spoke too soon, something (unknown) is causing a nasty crash when i pause - ONLY on an iPhone 4S... works fine on 5S and even an iPod touch.. all running iOS 9.2.. WEIRD ! – Adam Jan 19 '16 at 19:55
  • Himhh, i am this way for 2 games and never had a problem – crashoverride777 Jan 19 '16 at 20:49