how to release cocos2d objects? - iphone

I am doing as follows
-(void)Play {
[CCDirector setDirectorType:kCCDirectorTypeDisplayLink];
CCDirector *director = [CCDirector sharedDirector];
//[director setDeviceOrientation:kCCDeviceOrientationLandscapeLeft];
[director setAnimationInterval:1.0/60];
[director setDisplayFPS:NO];
CGRect rect = CGRectMake(0, 0, 320, 480);
EAGLView *glView = [EAGLView viewWithFrame:rect
pixelFormat:kEAGLColorFormatRGB565 // kEAGLColorFormatRGBA8
depthFormat:0 // GL_DEPTH_COMPONENT16_OES
];
[director setOpenGLView:glView];
[window addSubview:glView];
[window makeKeyAndVisible];
[director setDisplayFPS:YES];
[CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888];
CCScene *scene = [CCScene node];
CCLayer *layer = [PongLayer node];
[scene addChild :layer];
[[CCDirector sharedDirector] runWithScene: scene];
}
After adding layer to scene, I can go and see screen of PongLayer, but now how to destroy its object when you come back on the main screen from where you start game
I did change layers, but previous layer is working on back end, like if I do put some NSLog that I can see that log yet in running conditions, so what to do?
because when I again call play method, then I don't want to refresh all my array and all data for new scene.

Cocos2d objects such as CCLayer and CCSprite are coded to be auto release objects.
You'll see that the 'node' method alloc's inits and autoreleases an object when it's created.
Methods such as 'spriteWithFile:' and 'layerWithColor:' also are coded with autoreleased.
When you add an object as a child to a Layer or any other node for that matter, it creates a pointer to the object, retaining it. When the object is removed as a child, it deallocates itself.
So, when you move from Scene to Scene, the scene that is removed, deallocates it's children (layers) and they in turn their children (sprites).
http://www.cocos2d-iphone.org/wiki/doku.php/start
The only exception is when you create a sprite like this..
CCSprite *mySprite = [CCSprite alloc] init];
You have personally allocated and initialized this sprite, you must release it.
If you have CCLog turned on, it logs out when CCSprites are deallocated.
Another small thing worth mentioning, Scene's won't deallocate themselves if you 'push' the scene, only popping and replacing scene's cause 1 to deallocate.

Related

How to tell what kind of class/scene is runningScene?

I'm trying to implement some logic in my application delegate methods. It would be really helpful to know which kind of scene is currently running.
[[CCDirector sharedDirector] runningScene] returns the scene currently running.
Is there some sort of comparison or function to check if it is an instance of my [MainMenuLayer scene] or [gameScene scene] or something like that?
I'm not quite sure to how to use isKindOfClass or isEqual, or if they are applicable in this case. Thanks
As you assumed, you have to use isKindOfClass.
if ([[[CCDirector sharedDirector] runningScene] isKindOfClass:[MySceneClass class]]) {
// Running is scene is of type MySceneClass
}
Been stumped on this for longer than anyone should.
This returns a CCScene:
[[[CCDirector sharedDirector] runningScene]
You want the Instance of that scene which is of type MySceneClass (MenuScene for me), but the easiest way to get that is to tag it:
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];
// 'layer' is an autorelease object.
MenuScene *layer = [MenuScene node];
layer.tag = kTagGameLayer;
// add layer as a child to scene
[scene addChild: layer];
// return the scene
return scene;
Then adjust your statement to use getChildByTag:
if([[[[CCDirector sharedDirector] runningScene] getChildByTag:kTagGameLayer] isKindOfClass:[MenuScene class]]) {
NSLog(#"current is MenuScene");
}

Cocos2D iPhone - removing the black screen between CCTransition

I am using cocos2d on my app. I am doing a transition to another scene using
[[CCDirector sharedDirector] replaceScene:
[CCTransitionFadeDown transitionWithDuration:0.5f scene:otherScene]];
On the init part of this other scene, a menu is being built, using CCMenu. This is a full screen menu.
My problem is this: the transition happens to a black screen and then the menu appears. In other words, the transition is being done before the menu is rendered, so, I see an ugly black screen for 0.5 seconds and then, after the transition is done, I see the menu.
To make things clear imagine the first scene has a picture of a boat and the second scene a picture of a car. What I have now is the boat transitioning to black and then the car pops. I need the boat transition to the car.
how do I do that? thanks.
NOTE: I have found this guy with the same problem, but I have tried that solution without success.
This is worth a try, if you are not already using it; it removes black flickers during scene loads. Run the following method before you switch scenes, in case it affects your issue (un-comment these lines and call the method directly):
- (void) removeStartupFlicker
{
//
// THIS CODE REMOVES THE STARTUP FLICKER
//
// Uncomment the following code if you Application only supports landscape mode
//
// CC_ENABLE_DEFAULT_GL_STATES();
// CCDirector *director = [CCDirector sharedDirector];
// CGSize size = [director winSize];
// CCSprite *sprite = [CCSprite spriteWithFile:#"Default.png"];
// sprite.position = ccp(size.width/2, size.height/2);
// sprite.rotation = -90;
// [sprite visit];
// [[director openGLView] swapBuffers];
// CC_ENABLE_DEFAULT_GL_STATES();
}
I have implemented a transition in my menu (same problem), call it 'fadeInView' by adding a black layer on top of everything in the init, with an opacity of 255, and in onEnter I run an action to fade the opacity to 0. as follows:
-(id) init {
self=[super init];
if(self){
// do your stuff
blackShroudLayer_=[CCLayerColor layerWithColor:ccc4(0, 0, 0, 255) width:K_SCREEN_WIDTH height:K_SCREEN_HEIGHT];
[self addChild:blackShroudLayer_ z:500];
}
return self;
}
-(void) onEnter{
// need to [super onEnter] first to that we are running
[super onEnter];
id sh = [CCFadeTo actionWithDuration:K_FADE_TIME opacity:0];
id seq = [CCSequence actions:sh,[CCCallFunc actionWithTarget:self selector:#selector(onUnshroudComplete)], nil];
[blackShroudLayer_ runAction:seq];
}
-(void) onUnshroudComplete{
[blackShroudLayer_ removeFromParentAndCleanup:YES];
}
the constants and blackShroudLayer_ are defined in the class .h file.

Cocos2d sprite issues

Something weird is happening to my 'menu' scene, no other scenes in my app have this issue.
Sprites from files do not display (only for this scene) for some weird reason, I put them in a sprite sheet and added them to the texture cache to fix this.
However, the problems continue and now CCLabelBMFonts get a bad access error when added to the scene (again only for this scene). Error on line:
glDrawElements(GL_TRIANGLES, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(indices_[0])) );
I'm not sure what makes this scene special, perhaps it is how it is loaded (it is the only one loaded at the start):
- (void)loadScenes
{
EAGLContext *k_context = [[[EAGLContext alloc]
initWithAPI:kEAGLRenderingAPIOpenGLES1
sharegroup:[[[[CCDirector sharedDirector] openGLView] context] sharegroup]] autorelease];
[EAGLContext setCurrentContext:k_context];
menuScene = [[MenuScene alloc] init];
}
Any ideas?

dealloc doesn't work in cocos2d

i have game with cocos2d and method dealloc
i use this to change scene.
CGSize size = [[CCDirector sharedDirector] winSize];
CCMoveTo* move = [CCMoveTo actionWithDuration:1.0f position:CGPointMake(-(size.width), 0)];
CCEaseBackInOut* ease = [CCEaseBackInOut actionWithAction:move];
CCCallFunc* func = [CCCallFunc actionWithTarget:self selector:#selector(changeScene:)];
CCSequence* sequence = [CCSequence actions:ease, func, nil];
[self runAction:sequence];
or this in another scene.
CCScene* scene = [levelScene scene];
[userName removeFromSuperview];
CCTransitionFlipAngular *transitionScene=[CCTransitionFlipAngular transitionWithDuration:1 scene:scene];
[[CCDirector sharedDirector] replaceScene:transitionScene];
whene i changing scene the dealloc method doesn't do anything and onExit method too.
where i can releas my pointers ?or i have and constants wnat to equal to 0 when change scene.
whene i can do it?or why i can use dealloc.
dealloc is only called on an object when the memory management system determines that the object is no longer in use, when the retain count goes to zero. What are you doing to cause that to happen? I don't see any release or autorelease methods in your code samples.
You're going to have to be more specific about what you're doing to change scenes for a better answer.

cocos2d add a 'ready-go!' animation before the game

I want to add a 'ready-go!' animation before game, as well as during game (need to pause the game)
i tried to use [CCDirector sharedDirector] pushScene: [Anim scene]], but although the background of Anim scene is smaller than window size, the transparent area is black instead of see through the scene below.
how can i implement it? (or i don't have to use pushScene at all? )
here is the code for GameScene, onEnter i schedule the 'count' (timer), onExit i unschedule it.
-(void) onEnter {
GameManager* sharedManager = [GameManager sharedManager];
[[CCScheduler sharedScheduler] scheduleSelector:#selector(count) forTarget:sharedManager interval:1.0f paused:NO];
[super onEnter];
}
- (void)onExit {
GameManager* sharedManager = [GameManager sharedManager];
[[CCScheduler sharedScheduler] unscheduleSelector:#selector(count) forTarget:sharedManager];
[super onExit];
}
problem solved. I just create a scene specifically for the 'ready-set-go' animation, pass the necessary parameters to the AnimationScene, then launch the game from the AnimationScene using scheduler.
The result is not as good as 'ready-go' sign on top of GameScene since i am not able to make the transparent effect, but i tried to mimic the background of game scene, and it turns out quite well.
- (void)pauseButtonTapped {
[[CCDirector sharedDirector] pause];
[self pauseSchedulerAndActions];
}
- (void)playButtonTapped {
[[CCDirector sharedDirector] resume];
[self resumeSchedulerAndActions];
}
CCSequence. Before enabling AI timers or whatever runs your game objects, run a CCSequence action.