Keeping data, switching scene cocos2d - iphone

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];

Related

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];
}

How to add transition effect in Current running scene in cocos2d iphone

How to add transition effect in Current running scene in cocos2d iphone. Means I am making a game and after each goal I want to give a fade effect or any type of effect on the current running scene.
If I write this, It replace current scene to its new scene. But I don't want to replace scene.
[[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:1.0f scene:[GamePage scene]]];
Is there some way to show effect on the current page like this. I know that it is wrong but I want something like this :
[self transitionEffect:[CCTransitionFade actionWithDuration:0.5]];
For Scene,Layer (Subclass of CCNode) action related to Opacity will not work. !
You can Either Use transition, or Must have to apply CCFadeTo to all of your sprite.
But If you are choosing to CCFadeTo to all sprites, this will require allocation of lots of actions suddenly ! FPS slow down !!
Another best approach:
Tell to your designer, to make 1 x 1 pixel Square black dot image.
Add this code at last in the init method.
CCSprite *temp=[CCSprite spriteWithFile:#"squaredotBlack.png"];
temp.position=ccp(s.w/2,s.h/2);
[self addChild:temp z:50000]; //set as most top layer
temp.scaleX=s.w;
temp.scaleY=s.h;
temp.opacity=0;
Then Apply, For "Fade out" process of whole screen, Increase the opacity.
temp.opacity=0;
[temp runAction:[CCFadeTo actionWithDuration:1 opacity:255]]; //0 to 255
Then Apply, For "Fade In" process of whole screen, decrease the opacity.
temp.opacity=255; // this will cover whole screen with black color
[temp runAction:[CCFadeTo actionWithDuration:1 opacity:0]]; //255 to 0
you can run an action on the entire CCLayer
[self runAction:[CCFadeOut actionWithDuration:0.5f]];
or you can use CCFadeTo to fade to a desired opacity.

How can I make a scrolling game using Cocos2D without a tile map?

I want to move the background when I tilt the iPhone so it will look like it is moving your character. So if I tilt it forward, my background will go backwards.
Use a CCParallaxNode.
Here is a good article / blog, about using CCParallaxNode in a 2d scrolling game. In this person's example, they are moving the background on every frame, but you could modify it to only move when tilting the iphone by using the UIAcceleration delegate.
Here is the link: here
In terms of how to handle accelerometer input: In the init method of your layer, add:
self.isAccelerometerEnabled = YES;
Then, implement the method:
-(void) accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
You can get the accelerometer values by doing
accX = acceleration.x; //etc...
Now in terms of the animation, there's a couple ways to do it. One way you could do it is just make a large image, add it to a layer, and then adjust its position based on accelerometer input. However, this is very memory inefficient and not ideal. Why are you so opposed to using tile maps? They are quite useful for what you have in mind. A good resource for an introduction to them is at: http://www.raywenderlich.com/1163/how-to-make-a-tile-based-game-with-cocos2d

Cocos2d adding a background image to a layer?

I just finished reading some of the cocos2d documentation, and as far as I understand to add a background image to a layer you have to do something like:
Sprite * bg = [Sprite spriteWithFile:#"Background.png"];
[layer addChild:bg z:0];
Allthough as far as my testing goes you can just directly add the sprite to the scene like this:
#implementation IntroScene
- (id) init {
self = [super init];
if (self != nil) {
Sprite * bg = [Sprite spriteWithFile:#"Background.png"];
[bg setPosition:ccp(240, 160)];
[self addChild:bg z:0];
[self addChild:[MenuLayer node] z:1];
}
return self;
}
What is the difference between this 2 options, and what is the better way to set a background for a layer?. Any help will be greatly appreciated.
You do not need to have a layer, but they are handy. Think of the layers as a way of grouping sprites (both visually and organizationally). You may want your background images grouped as a layer and all the enemies in a game as another layer. This allows you to deal with each set more cleanly. e.g. You can remove a specific layer instead of finding all of the enemies and removing them.
If it helps, play with layers in Photoshop or a graphics editing program. Layers in cocos2d work similarly.
For a simple scene, adding the background to a layer or to a scene won't make much difference. But it doesn't take long before the benefits of layering kicks in.
Also layers control drawing order (over and above any inter-layer z ordering).
In geoSpark, for example, I have a background layer, a spark layer, a UI layer, etc. (Simplified). But this allows me to make sure my UI stuff is always above any game stuff (the spark layer) and all that is above the background.
If your game does only additive rendering, draw order won't matter much. :)
-- David
scene is a blackboard, layer is a page... news is wrote on page, but, if you want you can write on the board. If you want erase all new.
In cocos2d we can add any node on any node. But it depends on level of hierarchy.
You can add Layers on Scenes. If you want same property or look for all layers that you add on a CCScene you can add those in CCScene (as in your second case). but if you want to have different feature on each layer add those to CCLayer.
CCLayer is meant for grouping a set of nodes/sprites for some purpose. For example you can add a layer which includes options after pausing a game, or HUD layer for displaying som kind always on screen along with some scrolling layer (liken in some scrolling platform games).
Finally you can even CCNode on a CCScene, a layer on another layer, and even a CCNode on a CCSprite.
But the order of drawing in graphics context in cocos2d differs.
Hope you got the difference.
Good luck!