If you have a CCRepeatForever action, with a CCAnimate as one of the items, and it calls a callback function [CCCallFunc actionWithTarget: self selector: @selector(whatever)] after the animation, if you have the callback function do a [object stopAllActions] and then set up a new CCAnimate (think, idle animation to check for a timeout animation needed), it will actually do the following:
1) Sprite has last frame of animation from animation A
2) (new animation set to play with a runAction)
3) Sprite has first frame of new animation readied up from animation B
4) ***something goes wrong in CCRepeatForever
5) Sprite has last frame of animation from animation A
#5 shouldn't happen. #4 has a bug somewhere.
Can we get this fixed in a future release? It's hard to spot but it's definitely not functioning as it should, seeing how if you get rid of the CCRepeatForever and have the callback function set up animation A again manually, it will work as expected.
SOURCE CODE GO:
-(void) setCharState: (CharState) newState
{
[sChar stopAllActions];
switch (newState)
{
case charState_idle:
{
[sChar setDisplayFrame: [aState[curState].frames objectAtIndex: 0]];
[sChar runAction: [CCRepeatForever actionWithAction: [CCSequence actions: [CCAnimate actionWithAnimation: aState[curState] restoreOriginalFrame: false], [CCCallFunc actionWithTarget: self selector: @selector(checkForTimeout)], nil]]];
break;
}
}
case charState_time_out:
{
[sChar setDisplayFrame: [aState[curState].frames objectAtIndex: 0]];
[sChar runAction: [CCSequence actions: [CCAnimate actionWithAnimation: aState[curState] restoreOriginalFrame: false], [CCCallFunc actionWithTarget: self selector: @selector(enterIdleState)], nil]];
break;
}
}
-(void) checkForTimeout
{
if (timeOutNeeded)
{
timeOutNeeded = false;
[self setCharState: charState_time_out];
}
}
-(void) enterIdleState
{
[self setCharState: charState_idle];
}
Chris.