Spritekit and Scenekit - How to Completely Pause a Game

SpriteKit and SceneKit – How to completely pause a game?

You can't add the SKLabelNode (or anything else) to your scene while the SKView is paused. You will need to return to the run loop so your text is added before pausing the game. Here's one way to do that:

// Add pause text or button to scene
addChild(pauseText)
let pauseAction = SKAction.run {
self.view?.isPaused = true
}
self.run(pauseAction)

How can I pause a game in SpriteKit and SceneKit - SWIFT

I resolved by myself the problem :

here my code function :

  override func touchesBegan(touches: NSSet!, withEvent event: UIEvent!) 
{
var touch:UITouch = touches.anyObject() as UITouch
pauseText.text = "Pause"
pauseText.fontSize = 50
pauseText.position = CGPointMake(self.frame.size.width/2, self.frame.size.height/2)

/* bouton play/pause */

var locationPause: CGPoint = touch.locationInNode(self)
if self.nodeAtPoint(locationPause) == self.pause
{
addChild(pauseText) // add the text
pause.removeFromParent () // to avoid error when you touch again
self.runAction (SKAction.runBlock(self.pauseGame))
}

}

To resume the game you just have to add this code before the last "}" :

    if self.nodeAtPoint(locationPause) == self.pauseText
{
pauseText.removeFromParent() // remove the pause text
self.view.paused = false // resume the game
addChild(pause) // add the pause button
}

And in SKScene subclass add this function to add a label during the pause :

func pauseGame()
{
self.view.paused = true // to pause the game
}

How to Pause my Game View Controler (game) when segue to another VIew Controler (which is menu)

You can set the paused property of your scene to true. Put this in your prepareForSegue.

gameScene.paused = true //gameScene is whatever your scene variable is

When you return to the game VC, just set paused to false.

If you look at the docs for SKScene you'll notice its a subclass of SKNode. Here's a link to the paused property on SKNode

Pause all ongoing asyncAfter() delays in SpriteKit game

If you're inside of a SKScene class just have the scene run a delay in the form of an SKAction. The action will pause and resume when you pause/unpause either the view or scene.

func spawnMeteorite(timeInterval:Double) {

run(SKAction.wait(forDuration: timeInterval), completion: {
self.spawnMeteorite(timeInterval: timeInterval * 0.9)
})

print("Spawn Meteorite")
}

Pausing my game isn't working in Swift SpriteKit

I do not think runAction will be performed while the game is paused. Try simply

func unpauseGame() {
self.view!.paused = false
}

Trying to display a resume button after pausing the game scene on SpriteKit

For my next game I'm sure I'll give Nik's suggestion a try. As for my issue above, it worked by using the code shown below. The additional code is to dismiss the pause button as well. Now that this works I can maybe add a fadeIn and fadeOut actions to both buttons.

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch: AnyObject in touches {

let pointOfTouch = touch.location(in: self)

let nodeUserTapped = atPoint(pointOfTouch)

if nodeUserTapped.name == "PauseButton" {
if (self.isPaused == false) {
pauseGame()
}
}

if nodeUserTapped.name == "ResumeButton" {
if (self.isPaused == true) {
resumeGame()
}

}
}
}


// MARK: - pauseGame
func pauseGame() {
self.isPaused = true
currentGameState = gameState.pauseGame
self.physicsWorld.speed = 0
self.speed = 0.0
if (backgroundMusicIsOn == true) {
backingAudio.stop()
}
if resumeButton.isHidden == true {
resumeButton.isHidden = false
}
if pauseButton.isHidden == false {
pauseButton.isHidden = true
}
}


// MARK: - resumeGame
func resumeGame() {
self.isPaused = false
currentGameState = gameState.inGame
self.physicsWorld.speed = 1
self.speed = 1.0
if (backgroundMusicIsOn == true) {
backingAudio.play()
}
if resumeButton.isHidden == false {
resumeButton.isHidden = true
}
if pauseButton.isHidden == true {
pauseButton.isHidden = false
}
}

Swift 3: Making a Pause Menu in SpriteKit by overlaying a SKView?

I struggled with the problem of pausing the game within the game scene for a while.

As several others have suggested in the comments, building a "pause scene" to transition into when the game is paused and then out of is an effective solution. This approach avoids problems you might run into with timers firing within the game scene while the game is paused or animation skips when waking up.

To implement a pause scene, I use a custom subclass of UIViewController to handle scene transitions.

Within my CustomViewController:

var sceneForGame: MyGameScene? //scene to handle gameplay
var paused: PauseScene? //scene to appear when paused

...

// presentPauseScene() and unpauseGame() handle the transition from game to pause and back

func presentPauseScene() {
//transition the outgoing scene
let transitionFadeLength = 0.30
let transitionFadeColor = UIColor.white
let pauseTransition = SKTransition.fade(with: transitionFadeColor, duration: transitionFadeLength)
pauseTransition.pausesOutgoingScene = true

let currentSKView = view as! SKView
currentSKView.presentScene(paused!, transition: pauseTransition)
}

func unpauseGame() {
let transitionFadeLength = 0.30
let transitionFadeColor = UIColor.white
let unpauseTransition = SKTransition.fade(with: transitionFadeColor, duration: transitionFadeLength)
unpauseTransition.pausesIncomingScene = false

let currentSKView = view as! SKView
currentSKView.presentScene(sceneForGame!, transition: unpauseTransition)
}

Within MyGameScene class (subclass of SKScene):

var parentViewController: CustomViewController?  // ref to the managing view controller 

...

// invoke this func when you want to pause
func setScenePause() {
parentViewController?.presentPauseScene()
self.isPaused = true
}

...

// you may need a snippet like this in your game scene's didMove(toView: ) to wake up when you come back to the game
else if self.isPaused {
self.isPaused = false
}

This is my PauseScene implementation. This version will unpause when the user taps anywhere in the pause scene, except for an endGameButton, which terminates the current game:

struct PauseNames {
static let endGameButton = "ENDGAME"
static let pausedButton = "PAUSE"
}

class PauseScene: SKScene {

var center : CGPoint?
var pauseButton: SKSpriteNode?
var endGameButton: SKSpriteNode?
var parentViewController: CustomViewController?

override func didMove(to view: SKView) {
setUpScene()
}

func setUpScene() {
self.backgroundColor = SKColor.white
self.center = CGPoint(x: self.size.width / 2, y: self.size.height / 2)
self.isUserInteractionEnabled = false

setUpSceneNodes()
showPauseEndButtons()

} // end setup scene

func setUpSceneNodes() {
let buttonScale: CGFloat = 0.5
let smallButtonScale: CGFloat = 0.25

let pauseOffset = //some CGPoint
let endGameOffset = //some CGPoint
pauseButton = SKSpriteNode(imageNamed: PauseNames.pausedButton)
pauseButton?.name = PauseNames.pausedButton
pauseButton?.anchorPoint = CGPoint(x: 0.5, y: 0.5)
pauseButton?.position = self.center! + pauseOffset
pauseButton?.alpha = 0
pauseButton?.setScale(buttonScale)

endGameButton = SKSpriteNode(imageNamed: PauseNames.endGameButton)
endGameButton?.name = PauseNames.pausedButton
endGameButton?.anchorPoint = CGPoint(x: 0.5, y: 0.5)
endGameButton?.position = self.center! + endGameOffset
endGameButton?.alpha = 0
endGameButton?.setScale(smallButtonScale)
}

func showPauseEndButtons() {
let buttonFadeInTime = 0.25
let pauseDelay = 1.0

self.addChild(pauseButton!)
self.addChild(endGameButton!)

pauseButton?.run(SKAction.fadeIn(withDuration: buttonFadeInTime))
endGameButton?.run(SKAction.fadeIn(withDuration: buttonFadeInTime))
self.run(SKAction.sequence([
SKAction.wait(forDuration: pauseDelay),
SKAction.run{ self.isUserInteractionEnabled = true }]))
}

func endGamePressed() {
// add confrim logic
parentViewController?.endGame()
}

func unpausePress() {
parentViewController?.unpauseGame()
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches {
let touchLocation = touch.location(in: self)

if endGameButton!.contains(touchLocation) {
endGamePressed()
return
}
else {
unpausePress()
}

} // end for each touch
} // end touchesBegan

override func update(_ currentTime: TimeInterval) {
/* Called before each frame is rendered */
}

} //end class PauseScene

(The pauseButton is really more of a banner to inform the user of the pause state in this version)

Unable to pause Game Scene when home button pressed

You can set an observer for UIApplication.willResignActiveNotification like this, without using your custom notification:

let notificationCenter = NotificationCenter.default
notificationCenter.addObserver(self, selector: #selector(appMovedToBackground), name: UIApplication.willResignActiveNotification, object: nil)

@objc func appMovedToBackground {
// You will need to pause the game here, save state etc.
// e.g. set SKView.isPaused = true
}

This page from Apple contains more information. It states that SKView.isPaused should be set automatically when an app is sent to the background.

One point to consider. If the nodes’ movement is based on a timer relative to an absolute point in time, this would have the effect of updating the positions as if they had been moving while in the background.

Finally, are you calling isPaused on the SKScene?



Related Topics



Leave a reply



Submit