how can we know that we have released memory - cocos2d-iphone

I have created a game of two levels.Now when we are in level one i create sprite sheet for animation and a lot of sprites.On reaching a certain score i move to level 2 now here here is another sprite sheet and a lot of variables.
When i am moving from level 1 to level 2 using.
[[CCDirector sharedDirector] pushScene:[Level2 node]];
when i lose on level 2 i move back to level 1 using
[[CCDirector sharedDirector] pushScene:[Level1 node]];
What happens to the sprite sheet and other sprites i created before on level 1 ? If i retry level 1 will the sprite sheet and sprites i created before be removed automatically ?or they will exists in this new scene?
kindly clear me these issue i am having a lot of trouble because of no understanding of this..
thank you in advance.. :(

In cocos2d almost everything is marked as autorelease. So when you create a new scene it is not released because it becomes the main scene. Once it is no longer the main scene, if you do not specifically retain it then it will be released.
In the case you state above I believe that both scenes are retained as you are using the director like a stack, pushing the scenes on each other. If you never need to go back to level 1 you can use CCDirector's replaceScene: method instead to release level 1.
Having a custom pause scene or bonus round might be a good example of when to use the pushScene: call.

Related

Memory Issue in cocos2dx

Thanx in advance..I have a problem , how we release memory in cocos2dx ??
In my game, my first scene takes a lot of memory because there are so many animations run at a single time on this scene,there are so many animations , so i am satisfied with this but when we go to next scene, it does not release previous memory used,this is my problem so how we release memory used by previous scene when we change the scene?
To go between scenes you can either call pushScene or replaceScene.
Push Scene
If you're pushing between scenes then I recommend that you have a loading scene in between. It should be lightweight so that you have a chance to release everything from your old scene. This is where the onEnter(DidFinish) and onExit(DidStart) methods come in handy.
The chain of calls would be:
oldScene->onExitDidStart()
loadScene->onEnter()
oldScene->onExit() <-- this is where you release everything
loadScene->onEnterDidFinish() <-- this is where you load up the new scene
newScene->onEnter()
and so on... If you've managed your memory correctly then you shouldn't have 2 heavy scenes at once.
Replace Scene
This is a much easier scenario. You simply need to make sure that for the new scene you load as little as possible until the old scene has completely disappeared. I.e. when onEnterDidFinish() is called, or even 1 frame after it.
Cocos2d-x supports auto release memory. For example, when you create a sprite by calling Sprite::create() it will add this sprite to the auto-release pool. If you don't add this sprite to become the child (or n-th leveled child) of the current scene, it will be released.
Do not create an object using new,use create() instead when you call the next scene, everything from the last scene are released.

Why am I not able to Add new Layer to Scene from another Layer by parent?

I don't get why this code is incorrect...
DeadPanelLayer* deadPanelLayer = [DeadPanelLayer node];
[(CCScene*)self.parent addChild:deadPanelLayer z:2];
DeadPanel is a layer that I want to add on the Scene running from another layer
any idea why my layer is not loaded?
Edit: the game is not crashing, but the new layer does't show up. I tried to even move the objects on the scene and layer just to make sure it is not displaying due zindex hierarchic
but still...
I tried to add a method on Scene to add the layer in case it is called from parent:
[(GameScene*)self.parent showDeadPanel];
and even get current scene from Director
[[CCDirector sharedDirector] runningScene]
and it doesn't work either

How To Retrieve Actions From Sprite In cocos2d

I have a CCSprite that I'm using in a scene and have created multiple CCAnimation actions to apply to it all using a single CCSpriteFrameCache sharedSpriteFrameCache. While everything is working and I'm able to switch between animations, I feel like I'm doing poorly and would like to simplify my code by retrieving the running action(s) on the CCSprite to stop them individually before running the next action on it.
To help create some context, lets assume the following situation:
We have a CCSprite called mySprite
We have 3 separate CCAnimation actions defined for walking to the right, walking to the left, and sitting looking forward called: actionAnimWalkRight, actionAnimWalkLeft, and actionAnimSitForward respectively.
We want to have the sprite walk to the right when someone touches the screen right of mySprite, walk left when someone touches the screen left of mySprite and sit when someone touches mySprite.
The approach I'm using to accomplish this is as follows:
Place CCSprite as a child in the scene.
Tell the sprite to run an action using: [self runAction:actionWalkRight];
When I want to change the action after someone touches, I have a method called stopAllAnimationActions which I call before I apply a new action that stops any animation action no matter what's running. Basically lists ALL the CCAnimation/CCActions I have defined and stops each one individually since I don't want to use stopAllActions. as follows: [self stopAction:actionWalkRight]; [self stopAction:actionWalkLeft]; [self stopAction:actionSitForward];
Then I apply the new animation after the above method fires using: [self runAction:actionWalkLeft];
While this works, it just seems like a poor design to stop items that I know aren't running just because I don't know exactly what is running. So just looking for advice and the best recommended practice to do something like this within very complex situations so tracking every possible situation is difficult. Any feedback would be appreciated.
When creating the actions set the tag of that action with a constant:
actionWalkRight.tag= kCurrentAction;
[self runAction:actionWalkRight];
Then, retrieve the running action by that tag and stop it.
[self stopActionByTag:kCurrentAction];
I recommend you simplify your process and take advantage of the native Cocos features, including stopAllActions. Don't re-use actions, always create them from scratch as it has been well discussed among Cocos developers that re-using actions can be buggy.
Cocos is well optimized and features like stopAllActions are not performance hogs. It would probably be faster than your approach, actually.

Using replace scene to navigate

I have a question with regards to using replace scene in cocos2d.
Assume my game menu has the following structure:
Main Menu
Play
2.1 Strategy levels
2.2 Accuracy levels
Settings
Tutorial
Is the recommended method of navigation between the menus, "replace scene" or "push/pop"?
I've read in some places that its good to avoid push/pop in cocos2d. But my concern in using replace scene is that i have the impression that im just stacking up scenes instead of having a proper navigational flow.
Push and pop scene is going to stack your scenes. Each time you push a new scene, the old scene remains in memory and you need the exact same amount of popScene to get back to the initial scene.
So yes, using replaceScene is the standard and recommended method of switching scenes. While replaceScene removes the original scene from memory, there is a short time of overlap where both scenes remain in memory. So if you have two very memory intensive scenes, it is recommended to go through a temporary loading scene instead to allow the previous scene enough time to release its memory.
Note also that you cannot call replaceScene within the init method of a scene. That will cause CCDirector to crash.

How to keep fps rate constant in cocos2d

I have 3 question.
How to keep fps rate constant(almost) in cocos2d.When lots of CCSprite created and removed within a small interval like (5-8) per second is it possible to keep frame rate lmost constant??
Is [self removeChild:sprite cleanup:YES] is enough or i should also use
CCTexture2D *texture = [sprite texture];
[[CCTextureCache sharedTextureCache] removeTexture: texture];
The following Part of code is responsible for my frame drop.How to accomplish same task in better way-
id fadeout = [CCFadeOut actionWithDuration:1.4f];
id call = [CCCallFunc
actionWithTarget:self
selector:#selector(RemoveSmashedSprite:)];
CCSequence* sequence= [CCSequence actions:fadeout, call, nil];
[smash runAction:sequence];
and
-(void)RemoveSmashedSprite:(id)sender
{
CCSprite *sp = (CCSprite *)sender;
[self removeChild:sp cleanup:YES];
}
This is called 5-8 times per second.So the frame rate goes down.Can any one help me.
I am guessing that the "smashed sprite" in question is probably one of a number of sprites visible on the screen, more than likely sharing the same texture (part of a sprite sheet perhaps, or all the same image, etc?).
If this is the case, I would recommend allocating the number of sprites your games requires to have on screen and rather than "destroy" (remove them, re-create them) you should "re-use them".
Store a reference to all the CCSprite's in an NSMutableArray, populate this array with the number of sprites you think is appropriate (how many sprites are removed per second? how many sprites are added per second? how many sprites are on the screen to start? - use the answers to these questions to determine the most appropriate size of your array).
Then, rather than removing the sprite as a child, simply [sprite setVisible: NO] to hide it, then ... when you need to display a new one on screen, use the next "available" (hidden) sprite in the array (keep track of the last "used" sprite with an index, and simply increment it by 1 to find the next "available". Once the index exceeds the bounds, reset it to 0 - at this point, that sprite should have been "smashed"). Once you have the next "available" sprite, change it's properties (position, scale, texture?, visibility) and apply any actions that are appropriate (don't forget to "stop all actions" on it when "smashing it" - this is what "cleanup: YES" does).
If your game does not allow you to go around in a "circle" like this, because the user decides what may or may not be visible by interacting with the sprites in a varied order then you can store a reference to the "smashed sprites" in a separate array (while keeping them in the original array as well - then you can just pick anyObject from the "unused" array, remove it from that array and then alter it as mentioned above).
This should reduce your frame rate drops dramatically, as you won't be creating and destroying sprites all the time.
Another thing that may be occurring is that you are using different images, and each image is stored separately (image1.png, image2.png, image3.png) and the creation/destruction of these is causing the textures to be removed and re-added ... to resolve this, create a sprite sheet and add the sprite sheet to the Texture Cache, then create your images with 'spriteFromSpriteCacheName:#"image1.png"'