Dmitriy Vinnichuk
Dmitriy Vinnichuk

Reputation: 23

Pausing scene when game was interrupted

Another question: I call the function which generates sprites per time. But when I interrupt the game, for example picking up the call or double-click home button and go to task-manager, my scene doesn't stop and continue calling this function (oh, in this function i recall it per random time, cause in didMoveToView it calls once). So how stop the scene when game was interrupted? Thank you!

func spawnRocks(){

 if gameOver == 0{

    score++
    scoreLabel.text = "\(score)"

    let rockPosition = arc4random() % UInt32(self.frame.height/1.5)
    var rockAmount = CGFloat(rockPosition) - self.frame.size.height/4

    var rockTexture = SKTexture(imageNamed: randomRock())
    rock = SKSpriteNode(texture: rockTexture)

    rock.setScale(randomRockScale())

    rock.position = CGPointMake(CGRectGetMidX(self.frame) + self.frame.size.width, CGRectGetMidY(self.frame) + rockAmount)

    var moveRock = SKAction.moveByX(-self.frame.size.width*2, y: 0, duration: NSTimeInterval(randomRockMove()))
    var removeRock = SKAction.removeFromParent()
    var moveRemoveRock = SKAction.sequence([moveRock, removeRock])
    rock.runAction(moveRemoveRock)
    rockObject.addChild(rock)

    NSTimer.scheduledTimerWithTimeInterval(NSTimeInterval(randomRockSpeed()), target: self, selector: Selector("spawnRocks"), userInfo: nil, repeats: false)
 }

}

Upvotes: 1

Views: 127

Answers (3)

Dmitriy Vinnichuk
Dmitriy Vinnichuk

Reputation: 23

Better use action on repeating and avoid NSTimer in SpriteKit

Upvotes: 0

Whirlwind
Whirlwind

Reputation: 13665

SpriteKit in iOS 8 should automatically pause/resume your game (when app is moving to background or when exiting from background mode). In iOS 7 you should handle this manually. Search StackOverflow, there are some answers about this topic. Search about methods like aplicationWillResignActive, applicationDidEnterBackground, applicationDidBecomeActive) Also check the paused property of a view.

But, I guess that problem is with NSTimer which don't respect scene's or view's paused state. Try using action sequence instead with delay and block of code to spawn rocks. That should help.

Upvotes: 0

Dharmesh Kheni
Dharmesh Kheni

Reputation: 71854

You can try this idea:

First of all when your app will enter into background applicationDidEnterBackground will call from AppDelegate so you can set one bool there with NSUserDefaults which you can access anywhere is your project and set it this way:

func applicationDidEnterBackground(application: UIApplication) {
    NSUserDefaults.standardUserDefaults().setBool(true, forKey: "BackGround")

}

Now in your GameViewController.swift make if false when you load your game again like this:

override func viewDidLoad() {
    super.viewDidLoad()

    NSUserDefaults.standardUserDefaults().setBool(false, forKey: "BackGround")
}

and now you can read that NSUserDefaults in your function and you can stop it if your bool is true this way:

func spawnRocks(){

    let backGround = NSUserDefaults().boolForKey("BackGround")
    if !backGround {

        if gameOver == 0{

            score++
            scoreLabel.text = "\(score)"

            let rockPosition = arc4random() % UInt32(self.frame.height/1.5)
            var rockAmount = CGFloat(rockPosition) - self.frame.size.height/4

            var rockTexture = SKTexture(imageNamed: randomRock())
            rock = SKSpriteNode(texture: rockTexture)

            rock.setScale(randomRockScale())

            rock.position = CGPointMake(CGRectGetMidX(self.frame) + self.frame.size.width, CGRectGetMidY(self.frame) + rockAmount)

            var moveRock = SKAction.moveByX(-self.frame.size.width*2, y: 0, duration: NSTimeInterval(randomRockMove()))
            var removeRock = SKAction.removeFromParent()
            var moveRemoveRock = SKAction.sequence([moveRock, removeRock])
            rock.runAction(moveRemoveRock)
            rockObject.addChild(rock)

            NSTimer.scheduledTimerWithTimeInterval(NSTimeInterval(randomRockSpeed()), target: self, selector: Selector("spawnRocks"), userInfo: nil, repeats: false)
        }
    }
}

After that when user open app again from background you can set that bool false again from AppDelegate this way:

func applicationWillEnterForeground(application: UIApplication) {
    NSUserDefaults.standardUserDefaults().setBool(false, forKey: "BackGround")
}

Hope It will help you.

Upvotes: 1

Related Questions