I am developing an iOS game using sprite kit with an iAd banner, and this iAd is causing the game to unpause itself, and by unpausing I mean SKActions are continuing, here are some details:
1) I have several objects in my game that have a sequence (in series not parallel) of SKActions.
2) clicking the 'pause game' button on my game's screen and 'resuming' work fine - everything is pauses as desired. NSLog statement in "Note" below not displayed.
3) I've coded the following notification which has an observer that calls a selector to pause the game (which gets called properly). NSLog statement in "Note" below not displayed.
-(BOOL)bannerViewActionShouldBegin:(ADBannerView *)banner willLeaveApplication:(BOOL)willLeave
[[NSNotificationCenter defaultCenter] postNotificationName:#"iAdsoPauseGame" object:self];
return YES;
}
4) iAd appears lalala... everything is paused as it should be. NSLog statement in "Note" below not displayed.
5) when I click the "x" in the iAd, the following occur in this order:
a) the SKAction that my object in game was running while I 'paused' the game by going to iAd goes to completion, and the NSLog statement (in Note below) IS listed.
b) around 0.5sec later, my ViewController's "viewDidAppear" is called
c) less than 1ms after 5b, my iAd's "bannerViewActionDidFinish" is called (I have a notification here that tells my game to pause ... problem is there is this 0.5sec downtime between me closing the iAd and this method being called...)
Note: In my game's main .m file, in the "update" method (called every frame), I have an NSLog statement (below), and this does display as soon as I click the 'x' in the iAd, but then stops (when 5b/5c are called).
if (NodeGamePlay.paused==FALSE) {
NSLog(#"NodeGamePlay.paused==FALSE");
}
So my question: How can I prevent the SKaction from continuing (step that occurs in 5a) when I exit the iAd? Thank you for your time and help - this has been bugging me for quite some time!
just try this one
- (BOOL)bannerViewActionShouldBegin:(ADBannerView *)banner willLeaveApplication:(BOOL)willLeave
{
skView.scene.paused = YES;
return true;
}
Related
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. :)
I'm trying to extend what apple watch can do by rendering UIImage 'frames' and then setting them on my WKInterfaceImage every 500 milliseconds (2 frames per second).
My plan is to try render 8bit style games that don't need high detail or frame rates and then get arrow buttons on the watch app to direct how the game state changes.
So I have a Game class that has a 'tick' method which returns a UIImage. Each call to 'tick' will proceed the game by a single point. Think Tetris where each 'tick' of the game moves the falling blocks by one block space downwards. The game proceeds by 'ticks' until there is interaction from the user. Upon call to rotate the block, I am telling the Game class to rotate left or right when the next 'tick' happens. Here are the relevant parts of my WKInterfaceController class below.
- (void)willActivate
{
// This method is called when watch view controller is about to be visible to user
NSLog(#"%# will activate", self);
// wait 2 seconds until game 'starts'
[self performSelector:#selector(timerFired) withObject:nil afterDelay:2.];
}
- (void)timerFired
{
dispatch_async(dispatch_get_main_queue(), ^{
[self.theImage setImage:[self.game tick]];
[self performSelector:#selector(timerFired) withObject:nil afterDelay:.5];
});
}
- (IBAction)leftButtonPressed
{
self.game.futureMove = FutureMoveAntiClockWise;
}
- (IBAction)rightButtonPressed
{
self.game.futureMove = FutureMoveClockWise;
}
Now, amazingly all that code works great - for a few seconds. Then it all gets slower and slower and more and more behind (in terms of frames). After 10 seconds or so pressing the rotate left or right buttons only shows up on the rendered UIImage a few seconds later.
The watch app starts off rendering maybe 30 frames a second (if I wanted it to), and then crawls slower and slower and ultimately stops. Is there a better way to reliably setImage on a WKInterfaceImage repeatedly without it slowing down?
I'm so close!!
Thanks for you comments. After updating to Xcode 6.3 it works fine and doesn't lag but I will heed #MikeSwanson and expect Apple to reject my app :(.
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.
I am having a simple game in which if user goes to background, the game upon starting has to hide the player sprite node.
My code is as follows:
- (void)didMoveToView:(SKView *)view
{
[super didMoveToView:view];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(appDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
}
- (void)appDidEnterBackground:(NSNotification *)notification
{
[self hidePlayerNode];
}
- (void)hidePlayerNode
{
[self.playerNode runAction:[SKAction fadeOutWithDuration:0.0]];
}
The problem is that when the game is launched from background, I can see the player node for a split second and then it disappears. I need to make the player node invisible, the moment it goes to background and user shouldn't see it when the app is relaunched.
I tried with UIApplicationWillResignActiveNotification but the result is the same. Also, I tried running the code inside the selector method by main thread, but same result again.
You are probably seeing the state of your app that was saved as you went into the background.
Apple docs: "When your applicationDidEnterBackground: method returns, the system takes a picture of your app’s user interface and uses the resulting image for transition animations. If any views in your interface contain sensitive information, you should hide or modify those views before the applicationDidEnterBackground: method returns."
My app checks the GPS while my app is not the active app and I use AVAudioplayer too in background.
It works fine and stays in the background doing its thing, but ios7 displays this red top banner with my app name flashing on it when it is not the active app.
How can I disable this banner, it is annoying to use other apps that are squished down 1 line?
I know this can be done as I have other GPS based background apps that don't display this flashing banner.
EDIT - So we found the answer quickly but the solution evades me:
If I stop OpenEars pocketsphinxController from listening with a button that calls this method while the program is active, the banner disappears when the app loses focus:
-(void) mystopListening{
NSLog(#"Tried to stop listening");
[pocketsphinxController stopListening];
}
BUT if I call the same method from my app delegate with (I had to import my view controller.h file in my app delegate.h and add -(void) nystopListening; in my view controller.h to make the below execute properly):
- (void)applicationWillResignActive:(UIApplication *)application{
myViewController * vc = [[myViewController alloc]init];
[vc mystopListening];
}
The banner persists! It is a little like ios7 has decided I am a recording culprit before I even have a chance to turn it off. OR, am I even turning it off?
How do I do this effectively and in what event?
EDIT - So it turns out I am not really turning pocketsphinxController off when 'mystopListening' is called from the app delegate. I know this because it DOES log the 'Tried to stop listening' when called from app delegate but the pocketsphinxController does not respond with its 'pocketsphinxDidStopListening' method. PocketsphinxController does call its 'pocketsphinxDidStopListening' method when I call 'mystopListening' from a button while the app is active.
Why won't the pocketsphinxController respond when called from from the app delegate, I must be doing it wrong?
Thanks,Carmen
Turns out I was not really calling the original pockectsphinxcontroller instance from my app delegate.
As a workaround to the problem I did this:
My app always has a timer running, so in my app delegate where I get notice of when app goes to inactive and comes back active, I just set global flags so my timer can know app active status. Then my timer just uses pockecsphinxcontroller methods to stop and start listening and voila, the banner is no more while app not active.