dealloc doesn't work in cocos2d - iphone

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.

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 - how to make individual particles follow the layer, not the emitter?

I have a CCSprite and a CCParticleSystemQuad that are both children of the CCLayer. In my update method, I set the emitter's position to that of the sprite, so it tracks the sprite around. The smoke puff fall out the bottom of the sprite like you'd expect and even though you move the sprite around, the smoke appears to be part of the background layer.
The problem come if I match up their rotations. Now, for example if my sprite is rocking back and forth, the puffs of smoke swing in an arc and appear attached to the sprite.
How can I make the puffs of smoke continue along the parent layer in a straight line and not rotate with the sprite? They don't translate with the sprite when I move it, so why do they rotate with it?
EDIT: adding code...
- (id)init
{
if (!(self = [super init])) return nil;
self.isTouchEnabled = YES;
CGSize screenSize = [[CCDirector sharedDirector] winSize];
sprite = [CCSprite spriteWithFile:#"Icon.png"]; // declared in the header
[sprite setPosition:ccp(screenSize.width/2, screenSize.height/2)];
[self addChild:sprite];
id repeatAction = [CCRepeatForever actionWithAction:
[CCSequence actions:
[CCRotateTo actionWithDuration:0.3f angle:-45.0f],
[CCRotateTo actionWithDuration:0.6f angle:45.0f],
[CCRotateTo actionWithDuration:0.3f angle:0.0f],
nil]];
[sprite runAction:repeatAction];
emitter = [[CCParticleSystemQuad particleWithFile:#"jetpack_smoke.plist"] retain]; // declared in the header - the particle was made in Particle Designer
[emitter setPosition:sprite.position];
[emitter setPositionType:kCCPositionTypeFree]; // ...Free and ...Relative seem to behave the same.
[emitter stopSystem];
[self addChild:emitter];
[self scheduleUpdate];
return self;
}
- (void)update:(ccTime)dt
{
[emitter setPosition:ccp(sprite.position.x, sprite.position.y-sprite.contentSize.height/2)];
[emitter setRotation:[sprite rotation]]; // if you comment this out, it works as expected.
}
// there are touches methods to just move the sprite to where the touch is, and to start the emitter when touches began and to stop it when touches end.
I found the answer on a different site - www.raywenderlich.com
I don't know why this is true, but it seems that CCParticleSystems don't like to be rotated while you move them around. They don't mind changing their angle property. Actually, there may be cases where you want that behavior.
Anyway I made a method that adjusts the emitter's angle property and it works fine. It takes your touch location and scales the y component to be the angle.
- (void)updateAngle:(CGPoint)location
{
float width = [[CCDirector sharedDirector] winSize].width;
float angle = location.x / width * 360.0f;
CCLOG(#"angle = %1.1f", angle);
[smoke_emitter setAngle:angle]; // I added both smoke and fire!
[fire_emitter setAngle:angle];
// [emitter setRotation:angle]; // this doesn't work
}
CCSprite's anchorPoint is {0.5f, 0.5f), while the emitter descends directly from CCNode, which has an anchorPoint of {0.0f, 0.0f}. Try setting the emitter's anchorPoint to match the CCSprite's.

how to release cocos2d objects?

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.

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.

How can we set time delay in animation of images to make them appear smooth?

I have 10 CCSprite images. They are continues images. I am using,
CCSprite *playerH = [CCSprite spriteWithFile:#"Player_01.png" ];
playerH.position = ccp(playerH.contentSize.width/2, windowSize.height/2);
[self addChild:playerH z:1];
CCAnimation* animation = [CCAnimation animationWithName:#"dance" delay:0.20f];
for( int i = 1; i < 11; i++ )
{
[animation addFrameWithFilename: [NSString stringWithFormat:#"Player_%02d.png", i]];
}
NSLog(#"k VALUE: k: %d",k);
id actionA = [CCAnimate actionWithAnimation: animation restoreOriginalFrame:NO];
id actionD = [CCDelayTime actionWithDuration:5.0f];
id actionC = [CCCallFunc actionWithTarget:self selector:#selector(enemyEntranceScreen:)];
id seqActionPlayer = [CCSequence actions:actionA, actionD, actionC, nil];
[playerH runAction: seqActionPlayer];
But the animation is not continues. I have changed the animation delay time. but, I can see only three images appearing. How can we know how much time interval should we keep in animation.
Is there any relationship between this and the frame rate
[[CCDirector sharedDirector] setAnimationInterval:1.0/60];
[[CCDirector sharedDirector] setDisplayFPS:YES];
Thank you.
I got my animation smoothly. I think it depends on the
[[CCDirector sharedDirector] setAnimationInterval:1.0/60];
[[CCDirector sharedDirector] setDisplayFPS:YES];
Previously the setAnimationInterval value is 60.0/60. I changed it to 1.0/60. I could find all the images when the value is 1.0/60. I adjusted the animation time delay between the images.
But, when setAnimationInterval is 60.0/60 even I set the value of animation delay to 1second, I could not see all the 10 images displayed.
But, I need some clarification on the setAnimationInterval:
Thank You.