I've read everything I could find on this topic and still cant figure out my issue. I have tried pausing my game in every area of appdelegate
func applicationWillResignActive(application: UIApplication!) {
NSNotificationCenter.defaultCenter().postNotificationName("pauseGameScene", object: self)
}
func applicationDidEnterBackground(application: UIApplication!) {
NSNotificationCenter.defaultCenter().postNotificationName("pauseGameScene", object: self)
}
func applicationWillEnterForeground(application: UIApplication!) {
NSNotificationCenter.defaultCenter().postNotificationName("pauseGameScene", object: self)
}
func applicationDidBecomeActive(application: UIApplication!) {
NSNotificationCenter.defaultCenter().postNotificationName("pauseGameScene", object: self)
}
In my controller:
override func viewDidLoad() {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "pauseGame:", name: "pauseGameScene", object: nil)
}
func pauseGame(){
self.skView.paused = true
self.skView.scene!.paused = true
}
i know pauseGame works because if i toggle it with a button in my scene, it will stop the game. Even if I pause my skview and scene directly after they are loaded in the controller.. the game will not be paused on launch. It's easy to pause the game when I'm in-game. but for some reason whenever i exit and resume the app, the game will un-pause itself.
i notice if i get hacky and use some kind of delay.. i can get it to work. but obviously this is very stupid.. i just need to know where the game is unpausing itself!
func delay(delay:Double, closure:()->()) {
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(delay * Double(NSEC_PER_SEC))
),
dispatch_get_main_queue(), closure)
}
func pauseGame(sender: UIButton!){
delay(2) {
println("blah")
self.skView.paused = true
self.skView.scene!.paused = true
}
}
Here's a way to keep the view paused after returning from background mode.
Xcode 7 (see below for Xcode 8 instructions)
In the storyboard,
1) Change the class of the view to MyView
In the View Controller,
2) Define an SKView subclass with a boolean named stayPaused
class MyView: SKView {
var stayPaused = false
override var paused: Bool {
get {
return super.paused
}
set {
if (!stayPaused) {
super.paused = newValue
}
stayPaused = false
}
}
func setStayPaused() {
if (super.paused) {
self.stayPaused = true
}
}
}
3) Define the view as MyView
4) Add a notifier to set the stayPaused flag
class GameViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
// Configure the view.
let skView = self.view as MyView
NSNotificationCenter.defaultCenter().addObserver(skView, selector:Selector("setStayPaused"), name: "stayPausedNotification", object: nil)
In the App Delegate,
5) Post a notification to set the stay paused flag when the app becomes active
func applicationDidBecomeActive(application: UIApplication) {
NSNotificationCenter.defaultCenter().postNotificationName("stayPausedNotification", object:nil)
}
Xcode 8
In the storyboard,
1) Change the class of the view from SKView
to MyView
In the View Controller,
2) Define an SKView
subclass with a boolean named stayPaused
class MyView: SKView {
var stayPaused = false
override var isPaused: Bool {
get {
return super.isPaused
}
set {
if (!stayPaused) {
super.isPaused = newValue
}
stayPaused = false
}
}
func setStayPaused() {
if (super.isPaused) {
self.stayPaused = true
}
}
}
3) Define the view as MyView
4) Add a notifier to set the stayPaused flag
class GameViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
if let view = self.view as! MyView? {
NotificationCenter.default.addObserver(view, selector:#selector(MyView.setStayPaused), name: NSNotification.Name(rawValue: "stayPausedNotification"), object: nil)
In the App Delegate,
5) Post a notification to set the stay paused flag when the app becomes active
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "stayPausedNotification"), object: nil)
}
Here is an Obj-C example completely based on answer given by 0x141E, without subclassing a view. In my case, because I have internal game states, like finished, paused and started, I had to make an additional check in overridden setPaused:
method. But this worked flawlessly for me and definitely it is the one possible way to go.
AppDelegate.m
- (void)applicationDidBecomeActive:(UIApplication *)application {
[[NSNotificationCenter defaultCenter] postNotificationName:@"stayPausedNotification" object:nil];
}
GameScene.m
@interface GameScene()
@property (nonatomic, assign) BOOL stayPaused;
@end
@implementation GameScene
//Use initWithCoder: if you load a scene from .sks file, because initWithSize is not called in that case.
-(instancetype)initWithSize:(CGSize)size{
if(self = [super initWithSize:size]){
_stayPaused = NO;
//register to listen for event
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(setStayPaused)
name:@"stayPausedNotification"
object:nil ];
}
return self;
}
-(void)setStayPaused{
self.stayPaused = YES;
}
-(void)setPaused:(BOOL)paused{
if (!self.stayPaused) {
[super setPaused:paused];
}
self.stayPaused = NO;
}
-(void)willMoveFromView:(SKView *)view{
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"stayPausedNotification" object:nil];
}
@end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With