How to ensure SKScene is paused when app resumed from background? - ios

I am developing an iOS game; I am using several SKScenes and a single View Controller and my menu navigates between the different SKScenes. I'm having a problem with pausing (my game is using SKActions):
Problem: Suppose my game is in a 'paused' state (all SKActions of objects in my game are paused). When I click the 'home' button and send my app to the background, everything remains paused as it should. However, when I click my app to resume it, the scene that should be paused automatically 'resumes' itself, and all the SKActions resume to completion, and then the game pauses after this. (Please let me know if I can provide any additional details).
'Evidence': I know this because in the 'update' loop called every frame I have an NSLog statement that prints when the SKNode nodeGamePlay is paused, and it prints several times (half a second) when I click my game on the simulator's background.
What I want: When the app is clicked and opens, I want my pause-game-menu to appear, and I want my game (children of nodeGamePlay) to be paused.
What I have: In my SKScenePlay, I have a method that loads a 'pause menu' (not a child of nodeGamePlay) and pauses nodeGamePlay, which displays when a user clicks the pause button. Currently, when the user sends my app to the background and then reopens it, this method is called and the pause menu is added and the nodeGamePlay SHOULD GET paused (I call it with the following in my only viewController). However, although the pause menu displays, the nodeGamePlay does not get paused. How can I fix this?
- (void)appDidBecomeActive:(NSNotification *)notification {
[[NSNotificationCenter defaultCenter] postNotificationName:#"loadPauseGameMenu" object:scene];
}
EDIT: Update, when I set self.paused=true (for the SKScene), everything pauses correctly. When I do a for-in loop for each child in self and set each child.paused=true, SKActions are not paused correctly.

Related

Running a function when the game becomes active iOS - SpriteKit

In my game in swift / SpriteKit, I have a problem when the user quits the app and opens it up again. If the game is on the pause menu and everything is paused, when the game is reloaded the game is unpaused but the labels on the pause menu do not disappear. How do I keep the game paused when I reopen it? I have tried
func applicationWillEnterForeground(application: UIApplication) {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
let scene = GameScene(size: CGSize(width: 2048, height: 1356))
scene.view?.paused = true
}
But this is not doing anything. I have also tried pause() but that messes things up. Any help is appreciated.
You want to use the applicationWillResignActive function to pause your scene, by doing something like scene.speed = 0 which will properly pause your scene (don't know why, but it doesn't quite work just using pause). Here you can also display your pause menus (which you appear to be doing).
Then you want to use the applicationDidBecomeActive function to continue your game. Here you do your checks to see if (guessing here) your "resume" button is pressed, and in the response method for that, set the scene.speed = 1. Here your response method, do anything that requires starting back up (animations, actions, hiding your pause menu(s), or music).
I will say, these are the two functions that I use, you are free to use whichever two functions you would like that have a on/off kind of thing. I've found these to be very reliable.

Pausing iOS app game when User clicks Home Button

While the user is playing the game if they tap the Home Button on iPhone/iPad the game pauses itself but doesn't stay paused if the user clicks back on the app to open it, instead game leads them to game over screen. How do I code it that once the user clicks Home Button the game pauses and if they click back on app, within 2 seconds the game unpauses and you continue. Is there a particular code that goes inside the following methods that pauses the entire game and then unpauses it after a someone clicks on it and a few seconds go by?
UIApplicationDelegatedelegate
-(void)applicationWillResignActive:(UIApplication *)application{}
-(void)applicationWillEnterForeground:(UIApplication *)application{}
I got the app to pause in the background and stay paused but how do I make it that when the user EnterForeground again, there's about a 2 second delay before the game un-pauses?
iOS can't magically pause or un-pause your game for you - it's something you have to handle on your own in the code.
Once you have the logic to un-pause the game you can get the 2 seconds delay you mentioned in your question by calling performSelector:withObject:afterDelay: (see the docs). For example:
[self performSelector:#selector(continueGame) withObject:nil afterDelay:2.0]
where self has a method called continueGame to .. continue the game. :)

Presenting a new viewController doesn't seem to unload the previous

The game I'm developing consists of a Main Menu, and Game viewController separately.
However when moving from the game screen to the menu screen, it seems as if the class files from the previous viewController are still in effect?
For example, players start the game by tapping anywhere on the screen whilst in the game viewController, which causes a new bar to be "launched", which in turn plays a small tone which varies depending on the direction. However when returning to the main menu after the game is over (achieved by pressing a button to present the menu viewController), tapping anywhere on the menu screen seems to start the game again from the game viewController?
By this, I mean the bar launch sound is played, despite there being no code available in the main menu viewController to play said sound, pressing play on the menu will take you to the game screen, where the game has been reset, until tapping again, where the sound plays implying a new bar is launched, despite all images being invisible.
I made sure that, when leaving any view, I wipe all subviews from the view, so that whenever the screen is loaded there's nothing being covered up. I also tried dismissing the previous view controller, however nothing seems to take effect. So, I can't tell for certain whether the views are being removed or what... It's simply mind breaking to me.
Unfortunately my descriptions most likely aren't doing myself any justice, so hopefully this video demonstration will help out. Note that at the beginning, I am tapping the screen to show that no sound is played, however of course that won't be visible.
Edit: You'll notice that when returning to the menu, tapping the screen seems to mess up the moving bar in the background, despite the gameBarMovement timer being invalidated upon moving from the game to the menu. The fact that they're using separate class files also should mean the bars shouldn't be effected? Knowing me, I've missed something fairly obvious.
This is how the UIViewController life-cycle works as far as I know. UIViewcontrollers aren't unloaded until the app starts running out of memory. What you probably need is some way, in your game VC, to stop the game loop from running and resume it once a new game is started.

iOS correctly resume after application becomes active

I'm building a game for iOS using Cocos2D. In my game I have a pause menu that can be pulled up when playing the game. A simple tap will return from the pause menu to the game. What I would like to implement is a clean way to resume the game on the pause menu if the method applicationDidBecomeActive is called. The problem is that only the appDelegate receives the call to applicationDidBecomeActive, and my pause menu is many layers deeper than that. Right now I'm essentially passing the applicationDidBecomeActive call through about 4 different layers to get it down to the pause menu. There must be a cleaner way?
Sure is. Just add an observer for the UIApplicationDidBecomeActiveNotification from anywhere that's convenient. Application state changes can be hooked that way as well as via the app's delegate.
(Docs here.)
Read about the NSNotificationCenter
here and at Apple or just receive the UIApplicationDidBecomeActiveNotification anywhere.
take a BOOL variable in appdelegate.h with property and synthesised it then when pause button pressed from any scene set this variable to yes.
in applicationDidBecomeActive method of appdelegate check if(self.pause == YES) then don't resume ccdirector else resume it
i used this in my game and it work fine when i press pause and then press home button and when come back the app is still pause. try this

How to wait until the CCMenuItemImage is press in objective C?

I want to pause the program until my button is press
I have pause my scene by Use [[CCDirector sharedDirector] pause]; sure that the screen is pause but my function is continue running until it end function
Do they have any function to wait for the press button action??
If you pause the CCDirector, it will drop the framerate to 4 fps - it does not stop the CCDirector from running game updates, nor will it halt the execution of the current method.
Note that the low framerate will affect touch detection and you may find it hard to activate any CCMenu button while CCDirector is paused.
These are just two reasons why CCDirector's pause method is a poor substitute for a real implementation of pausing your game. In principle, when you bring up the ingame (pause) menu, what should happen is that any game play object is simply not running any updates and pauses any currently running actions. Only the foreground menu remains running normally to receive user input.

Resources