Improving the Performance of Animating Sprites in cocos2d

Aug 5, 2009   //   by Derek van Vliet   //   Development  //  11 Comments

cocos2d has proven to be invaluable in enabling us to get our iPhone game up and running fast. But when we started playing with animated sprites, we noticed some performance problems. If you are like us and have many sprites that have to have repeating animations, you may have noticed the same thing.

Conventional wisdom (aka the sample code) says that you would create a RepeatForever action using an Animate action to animate an AtlasSprite. When we tried this, however, we noticed that at the end of each animation cycle, the action would deallocate an AtlasSpriteFrame. This is a by-product of the Animate action being able to restore the original frame of animation once the animation has finished playing. This is also what was causing the performance issues.

To resolve this, we created a cut-down version of the Animate action called FastAnimate. It is very similar to the Animate action with the exception that it does not support restoring the original frame of animation. From what we’ve seen, this simple change greatly increases the performance of animating sprites in cocos2d.

FastAnimate.h:

#import "cocos2d.h"
 
@interface FastAnimate : IntervalAction <NSCopying>
{
	Animation *animation;
}
+(id) actionWithAnimation:(id<CocosAnimation>) a;
-(id) initWithAnimation:(id<CocosAnimation>) a;
@end

FastAnimate.m:

#import "FastAnimate.h"
 
@implementation FastAnimate
 
+(id) actionWithAnimation: (id<CocosAnimation>)anim {
	return [[[self alloc] initWithAnimation:anim] autorelease];
}
 
-(id) initWithAnimation: (id<CocosAnimation>)anim {
	NSAssert( anim!=nil, @"Animate: argument Animation must be non-nil");
 
	if( (self=[super initWithDuration: [[anim frames] count] * [anim delay]]) ) {
 
		animation = [anim retain];
	}
	return self;
}
 
-(id) copyWithZone: (NSZone*) zone {
	return [[[self class] allocWithZone: zone] initWithAnimation: animation];
}
 
-(void) dealloc {
	[animation release];
	[super dealloc];
}
 
-(void) startWithTarget:(id)aTarget {
	[super startWithTarget:aTarget];
}
 
-(void) stop {
	[super stop];
}
 
-(void) update: (ccTime) t {
	NSUInteger idx=0;
 
	ccTime slice = 1.0f / [[animation frames] count];
 
	if(t !=0 )
		idx = t/ slice;
 
	if( idx >= [[animation frames] count] ) {
		idx = [[animation frames] count] -1;
	}
	id<CocosNodeFrames> sprite = (id<CocosNodeFrames>) target;
	if (! [sprite isFrameDisplayed: [[animation frames] objectAtIndex: idx]] ) {
		[sprite setDisplayFrame: [[animation frames] objectAtIndex:idx]];
	}
}
@end

11 Comments

  • Great tip. Tkx!

  • Great tip. Tkx!

  • Thanks Derek

    I was looking for a way for the animation to not restore the original frame after playing a 1 shot animation.

    Not only did you solve this problem, but you improved performance as well.

    Thank you so much!

    Best of luck with your app!

  • Thanks Derek

    I was looking for a way for the animation to not restore the original frame after playing a 1 shot animation.

    Not only did you solve this problem, but you improved performance as well.

    Thank you so much!

    Best of luck with your app!

  • Thanks Derek

    I was looking for a way for the animation to not restore the original frame after playing a 1 shot animation.

    Not only did you solve this problem, but you improved performance as well.

    Thank you so much!

    Best of luck with your app!

  • [...] While working on our coming-soon first iPhone game, we have been having a lot of success with cocos2d. One area in particular that we have been impressed with is the ability to run “Actions” on sprites, string them together in sequences and wrap them in modifiers such as ease-in, ease-out etc. This has made it easy to make our UI lively and animated as well as animate our game objects. [...]

  • You guys rock. This totally solved our performance issue

  • You guys rock. This totally solved our performance issue

  • Cool glad to know we could be of some help. What are you guys working on? Anything you can publicly talk about?

  • Cool glad to know we could be of some help. What are you guys working on? Anything you can publicly talk about?

  • I had exactly the same problem as nalinsharma, so thank you ! Best of luck guys !

Leave a comment

Our Games

Latest Tweets