Reputation: 57
I am trying to animate an object in cocos2d and then remove it from the layer once the animation is completed but due to being a complete novice the below is not working for me.
I have two states kStateDead and kStateScore that once called will perform an animation and then be removed from the scene but this is not currently happening
I have checked the animations and they all work so I added a debug label to the object and it does change state to either kStateDead or kStateScore. I also added a CCLOG to the states and have found that in the debug area it keeps repeating the CCLOG that that is in either kStateDead or kStateScore (but does not play the animation) which makes no sense as I have asked it to remove and clean up the object after the animation has played.
Please see below for the output from the console and also the code. Any help to push me in the right direction (don't expect you to solve it for me!) would be greatly appreciated.
2014-02-20 14:29:14.088 TestBallexercise[999:12c03] ball->change state to dead
2014-02-20 14:29:14.089 TestBallexercise[999:12c03] ball->change state to dead
2014-02-20 14:29:14.090 TestBallexercise[999:12c03] ball->change state to dead
2014-02-20 14:29:14.104 TestBallexercise[999:12c03] ball->change state to dead
2014-02-20 14:29:14.105 TestBallexercise[999:12c03] ball->change state to dead
2014-02-20 14:29:14.106 TestBallexercise[999:12c03] ball->change state to dead
-(void)changeState:(CharacterStates)newState {
[self stopAllActions];
[self setCharacterState:newState];
CGSize screenSize1 = [CCDirector sharedDirector].winSize;
characterState = newState;
id action = nil;
switch (newState) {
case kStateScore:
CCLOG(@"ball - score!");
action = [CCSequence actions:
[CCAnimate actionWithAnimation:scoreAnim
restoreOriginalFrame:NO],
[CCDelayTime actionWithDuration:3.5f],
[CCFadeOut actionWithDuration:0.9f],
nil];
break;
case kStateDead:
CCLOG(@"ball->change state to dead");
action = [CCSequence actions:
[CCAnimate actionWithAnimation:deadAnim
restoreOriginalFrame:NO],
[CCDelayTime actionWithDuration:3.5f],
[CCFadeOut actionWithDuration:0.9f],
nil];
break;
}
if (action !=nil)
[self runAction:action];
}
-(void)updateStateWithDeltaTime:(ccTime)deltaTime andListOfGameObjects:(CCArray *)listOfGameObjects {
CGPoint currentSpitePosition = [self position];
CGRect ballBoundingBox = [self adjustedBoundingBox];
if ((currentSpitePosition.x > screenSize3.width*0.95f)) {{
[self changeState:kStateScore];
}
return;
}
if ((currentSpitePosition.y < screenSize3.height*0.10f)) {{
[self changeState:kStateDead];
}
return;
}
if ([self numberOfRunningActions] == 0) {
if (characterState == kStateDead) {
[self setVisible:NO];
[self removeFromParentAndCleanup:YES];
return;
}
if (characterState == kStateScore) {
// [self changeState:kStateDead];
[self setVisible:NO];
[self removeFromParentAndCleanup:YES];
return;
}}}
Upvotes: 0
Views: 54
Reputation: 1271
The update
function is called repeatedly with a certain time interval. Once the criteria for lets say, kStateDead
is met, changeState
is called and update
function returns. Inside the changeState
function the action would start but meanwhile update
function is called again where the condition for kStateDead is still true and therefore changeState is called again which stopsAllActions in the first line. Thus, making it seem that the sprite is not animating. The code never reaches the cleanup code block in the update function.
There are several ways you could work around this problem. Either modify the condition like
if ((currentSpitePosition.y < screenSize3.height*0.10f) && self.characterState != kStateDead) //this will ensure that once dead, changeState to dead is not called again.
However, I would suggest since you want the object to be removed after the animation completes, it would be a good idea to add a callback to let you know the animation has completed and execute the cleanup code in the callback. This could be done by
action = [CCSequence actions:
[CCAnimate actionWithAnimation:deadAnim
restoreOriginalFrame:NO],
[CCDelayTime actionWithDuration:3.5f],
[CCFadeOut actionWithDuration:0.9f],
[CCCallFunc actionWithTarget:self selector:@selector(removeSelf)],
nil];
and you could do the clean up in the removeSelf function
-(void) removeSelf{
//your clean up code
}
Upvotes: 1