Bug in CCRepeatForever CCAnimation – watch the Grossinis' synchronized dance !

Forums Programming cocos2d support (graphics engine) Bug in CCRepeatForever CCAnimation – watch the Grossinis' synchronized dance !

This topic contains 4 replies, has 3 voices, and was last updated by  rsanchezsaez 2 years, 7 months ago.

Viewing 5 posts - 1 through 5 (of 5 total)
Author Posts
Author Posts
October 24, 2010 at 5:43 pm #225678

MikeSz
Participant
@mikesz

First of all – the results of this bug are rather miniscule and happen after such a long time that it might not even be worth mentioning. However – I have been able to reproduce it in both simulator and device, release and debug .99.5.b2 and .99.5.b3 so it’s something that does happen. And while it might be something irrelevant, it might also point to something that is wrong within the action code. So I decided to post it here

We’re finishing our next game and my gf noticed something funny happening with animations. We have some characters in game that have the same animation going on, but with a delay at the start. Wouldn’t look too good if they were all having the same frame, right ? ;) So we add some random delay before running the animations with actual animations being run inside a CCCallFunc selector – you can’t use CCRepeatForever in CCSequence. So [CCSequence delay, callfunc] and [ccanimate] in selector. Looks all right, I don’t think there’s anything that can be wrong in the code…

However, if you leave the game for few mins, the animations would synchronize and all the sprites will show the same frame. Magic ? :D Cocos AI ? Not sure, but decided to test it in .99.5.b3 and… Grossinis do dance together !!!

It doesn’t have much negative effect for us, but might be a cause in action system, so I decided to post it here. Go on, check for yourself ;) Just add this class into the SpriteTest.mm:

#pragma mark -
#pragma mark Example SpriteTestDelayAnimation

@implementation SpriteTestDelayAnimation

#define firstSpriteTag 666
static int currSpriteTag = firstSpriteTag;

-(void) startAnimation
{
CCSprite * sprite = (CCSprite*)[self getChildByTag:currSpriteTag];
NSMutableArray *animFrames = [NSMutableArray array];
for(int i = 0; i < 14; i++) {

CCSpriteFrame *frame = CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:@"grossini_dance_%02d.png",(i+1);
[animFrames addObject:frame];
}
CCAnimation *animation = [CCAnimation animationWithName:@"dance" frames:animFrames];

[sprite runAction:[CCRepeatForever actionWithAction: [CCAnimate actionWithDuration:.5f animation:animation restoreOriginalFrame:NO] ]];

currSpriteTag++;
}

-(id) init
{
if( (self=[super init]) )
{
CGSize s = [[CCDirector sharedDirector] winSize];
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"animations/grossini.plist"];
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"animations/grossini_gray.plist"];

int sprites = 6;
for(int i=0;i<=sprites;i++)
{
CCSprite *sprite = [CCSprite spriteWithSpriteFrameName:@"grossini_dance_01.png"];
sprite.position = ccp( s.width/8*(i+1), s.height/2);

CCSprite *point = [CCSprite spriteWithFile:@"r1.png"];
point.scale = 0.25f;
point.position = sprite.position;
[self addChild:point z:1];

[self addChild:sprite z:0 tag:firstSpriteTag + i];
}

for(int i=0;i<=sprites;i++)
{
[self runAction:[CCSequence actions:[CCDelayTime actionWithDuration:CCRANDOM_0_1() * .5f],
[CCCallFunc actionWithTarget:self selector:@selector(startAnimation)],nil]];

}
}
return self;
}

- (void) dealloc
{
[[CCSpriteFrameCache sharedSpriteFrameCache] removeUnusedSpriteFrames];
[super dealloc];
}

-(NSString *) title
{
return @"Sprite test delay";
}
@end

+ of course add @”SpriteTestDelayAnimation” to the static NSString *transitions[] = {}

Run the code, wait a few mins (might take over 5-10 mins…) and observe how all the Grossinis will dance in a perfect sync ! Checked on both device and release builds, on simulator and on actual device

What makes it really interesting is that if you use the following action instead (remember to remove the second loop in the example above, no need to rerun animations):

[sprite runAction:[CCSequence actions:[CCDelayTime actionWithDuration:CCRANDOM_0_1() * .5f],
[CCRepeat actionWithAction:[CCAnimate actionWithDuration:.5f animation:animation restoreOriginalFrame:NO] times:1000000000],
nil]];

It works properly and the animations continue unsynchronized

So… Something strange is happening that makes CCRepeatForever behaves differently than CCRepeat bazillion times

October 24, 2010 at 6:21 pm #302279

riq
Keymaster
@admin

could you open a ticket ? thanks.

October 24, 2010 at 6:33 pm #302280

MikeSz
Participant
@mikesz

Sure, will do in a moment

October 24, 2010 at 7:06 pm #302281

MikeSz
Participant
@mikesz

here it is:

http://code.google.com/p/cocos2d-iphone/issues/detail?id=1020

September 16, 2011 at 12:28 pm #302282

rsanchezsaez
Participant
@rsanchezsaez

This bug is quite scary, and I would not say it’s a minor bug.

Without looking into it with detail, by the symptoms it seems that either CCRepeatForever or CCAnimate are somehow broken, and the animations are either not taking the time that they should or either skipping frames.

Viewing 5 posts - 1 through 5 (of 5 total)

You must be logged in to reply to this topic.