Iphone game development switching between scenes - iphone

i have created a pause button on touch the scene is replaced by the pause menu....
and when we resume the scene comes back...however the function keep calling themselves....
how can i pause every thing in my current file when i switch to another scene...

"on touch", the running scene should call:
[[CCDirector sharedDirector] pushScene: [PauseMenu scene]];
The pause menu's "back to game" button should then call:
[[CCDirector sharedDirector] popScene];
Pushing the pause menu into place, should "pause" the scene that is currently being pushed back and when you pop it back it should continue running.
Documentation: http://www.cocos2d-iphone.org/api-ref/latest-stable/interface_c_c_director.html

Related

Keeping data, switching scene cocos2d

In a simple game, I preload approximately 100 sprites onto a CCBatchNode, and then modify their visibility and position during the game. When the game is over I want to switch to a different scene to show High Scores, and then go back and play again. Is there a way to avoid having to reload all the sprites onto a new BatchNode?
I was also wondering how it would be best to store things like coins, that can be collected each game. Would NSUserDefaults be the best way to go?
I think best solution is to use a push scene to push your scene that shows the high scores and then use popscene to pop the high scores scene from the stack. When you push and pop a scene, the underlying scene is unchanged.
[[CCDirector sharedDirector] pushScene:[HelloWorldLayer scene]];
[[Director sharedDirector] popScene];

Cocos2d access scene properties and methods

I'm trying to include a pause feature for my game. So far running pause on the [CCDirector sharedDirector] has been good enough when run through my pauseGame method (which incorporates a BOOL to tell if game is paused, etc.)
However, I noticed that if I go back to the homescreen on my device, my application delegate will automatically run pause and resume on the sharedDirector.
Ideally, I would like access my active scene/layer's so I can run my own pause method.
How can I: 1) check if the current scene is my game scene
2) access the game scene's pause property, and run the pauseGame method on it?
Any help appreciated. Thanks
The running scene is [CCDirector sharedDirector].runningScene
If you call [scene pauseSchedulerAndActions]; on the current scene this is will not be resumed when going back and forth on the home screen.
If you need to pause ALL nodes in the hierarchy, here is a method to extend CCNode
-(void)recursivePauseSchedulerAndActions {
[self pauseSchedulerAndActions];
CCNode *child;
CCARRAY_FOREACH(children_, child) {
[child recursivePauseSchedulerAndActions];
}
}
-(void)recursiveResumeSchedulerAndActions {
[self resumeSchedulerAndActions];
CCNode *child;
CCARRAY_FOREACH(children_, child) {
[child recursiveResumeSchedulerAndActions];
}
}
I use a different approach for pausing a game.
I usually have a game scene with game layers. To pause the game I add a new layer (covering the entire screen) and when I pause the game I display this layer. This way you can stop touching events for the game layer and restore them when resuming the game (and removing the pause layer from the scene)

Cocos2D not updating after view popped and pushed

I'm writing an iPhone game which has a number of levels. During play the user can use a menu to quit the game and return to the level select screen. To do this I'm using a UINavigationController with series of UIViewControllers. When the player chooses to quit, the game view is popped from the stack and the level select menu is displayed. The game runs fine the first time through but if the player quits the level and then tries to play the same or another level this causes a problem.
The game view controller (which displays the cocos2d scene) is a member variable of a game controller singleton. When the user clicks "play again" this game controller resets the game state. The cocos2d layers are cleared and the game is reset to it's starting condition. After this the game view is pushed onto the stack again. This time however cocos2d doesn't update. The screen is just the last frame from the previous game frozen.
It seems that for some reason when the cocos2d view is popped and then pushed it stops updating even though I use:
[[CCDirector sharedDirector] resume];
Does anyone have any experience of this problem and how it could be avoided?
When your game view controller is popped the [[CCDirector sharedDirector] stopAnimation] is called, so after pushing your game view controller onto the stack again you must call the [[CCDirector sharedDirector] startAnimation].
Hope this helps.
I would try it like that:
[self resumeSchedulerAndActions];
for(CCSprite *sprite in [self children]) {
[[CCActionManager sharedManager] resumeTarget:sprite];
}

cocos2d iphone wait for action to complete/finish

I'm trying to force an action to complete before another action can be called. I've looked all over for different examples of timing delays and CCSequencing and this is what i have so far, but it still isn't working. I need the full .5 to come out before another action (whether it be left, right or down) can be called. Everything is working as long as you don't hit the buttons before an action finishes, thats when the previous action is cut short.
-(void) moveup{
CCNode *mySprite = [self getChildByTag:kTagSprite];
//moves sprite up 30 pixels in 1/2 second
[mySprite runAction: [CCMoveTo actionWithDuration:.5 position:ccp(mySprite.position.x, mySprite.position.y+30)]];
}
//this is inside CCtouchesbegan. upsprite is a box that gets clicked to move the object up
if(CGRectContainsPoint([upsprite boundingBox], point)){
//should call CCSequence of events, method moveup, and then CCDelayTime, forcing a pause
[self runAction:[CCSequence actions:[CCCallFuncND actionWithTarget:self selector:#selector(moveup) data:nil], [CCDelayTime actionWithDuration:.5], nil]];
}
I've tried pausing using [[CCDirector sharedDirector] pause] but this freezes everything, including the sprite I'm moving. The CCDelayTime doesn't seem to be working in my current example.
I know this question is kind of a duplicate of a couple others about ccsequencing, so if it needs to be marked as a dupe, that's fine, but I'd really like some help as it's really holding me back.
You could make a BOOL "lock" variable, and only run the action on "mySprite" :
if(lock) {[mySprite runAction:...];}
set the BOOL lock to NO in the beginning and everytime you begin the action set it to "YES"...then add a CCCallFunc to the CCSequence to set the lock back to "NO"

hot to disable touch handling in CCLayer in cocos2d

I've got a CCLayer subclass i'm using to display some sprites and to show some animations. Also it has a CCMenu with some items. When user selects some of the menu item i want to run an animation and then to show another scene. But i want user not to be able to touch anything on the screen while animation is running.
Of course, i can just disable handling touches in my callbacks, but maybe there is more simple way - just to disable all touch handling for a while ?
Disable touch dispatcher before animation running and enable touch dispatcher after animation stopped. Here is the code snippet:
[[CCDirector sharedDirector] touchDispatcher].dispatchEvents = NO;
CCAnimation* animation = [CCAnimation animationWithFrame:#"numberexplode" frameCount:5 delay:0.2];
CCAnimate* animate = [CCAnimate actionWithAnimation:animation];
CCCallBlock* completion = [CCCallBlock actionWithBlock:^{
[[CCDirector sharedDirector] touchDispatcher].dispatchEvents = YES;
}];
CCSequence* sequence = [CCSequence actions:animate, completion, nil];
[self runAction:sequence];
You want to look at the CCTouchDispatcher singleton class. If you add a targeted touch handler that swallows touches (and does nothing) then you won't get any touches handled. As far as I can tell there's no way to totally disable touches.
Alternatively you can make a new CCLayer that's on top of everything else (I think z order really high will do this), and make it clear, and have it do nothing with touches.
hope that helps.