Browsing articles tagged with " CCAnimation"

How to Animate Sprites in cocos2d

Apr 18, 2010   //   by Derek van Vliet   //   Development  //  41 Comments

One of the most frequently asked questions I see about cocos2d for iPhone is “how do you animate sprites?”. This was also one of the first questions we had when developing Addicus.

It’s actually quite simple to do using cocos2d’s CCSpriteSheet, CCSprite and CCAnimation classes. These classes take a texture atlas and switch between frames at regular intervals. In other words: animation!

Here is how to animate a sprite in cocos2d in 5 steps. You can also download the code for this blog post.

1. Create Your Animation Texture Atlas

First you need to combine all of the frames of your animation into a single graphic, called a texture atlas. You can do this by hand in an image editor like Photoshop, simply by copying and pasting all of the frames of your animation into a single file. Alternatively, there are atlas generating tools that will take a batch of image files and compile them into a texture atlas in just a couple of clicks.

I recommend using a Flash-based tool called Zwoptex because it is officially supported by cocos2d.

Once you’re done, you should have an image that contains all of the frames of your animation such as the one below:

Grossini Dance
Incidentally, this image is included in the cocos2d distribution.

2. Create a CCSpriteSheet

Once we have the texture atlas, it is time to get coding. The following code would go in the init method of a CCScene sub-class.

The first step in code is to create an instance of a CCSpriteSheet using your texture atlas and child it to a node in the scene. In this case we are childing it to the CCScene itself.

CCSpriteSheet *danceSheet = [CCSpriteSheet spriteSheetWithFile:@"grossini_dance_atlas.png"];
[self addChild:danceSheet];

3. Create a CCSprite Using Your CCSpriteSheet

Next we create a CCSprite that uses the texture of the CCSpriteSheet that we just created. We then child it to the CCSpriteSheet. The rect that we initialize the CCSprite with is the first frame of the animation.

CCSprite *danceSprite = [CCSprite spriteWithTexture:danceSheet.texture rect:CGRectMake(0, 0, 85, 121)];
[danceSheet addChild:danceSprite];

4. Create a CCAnimation

Next we need to create a CCAnimation instance and add all frames of the animation to it. In the case of this texture atlas, we know all of the frames are the same size and there are 14 of them, so we can use a nested loop to iterate through them all and break the loop when we finish adding frame #14.

CCAnimation *danceAnimation = [CCAnimation animationWithName:@"dance" delay:0.1f];
 
int frameCount = 0;
for (int y = 0; y < 3; y++) {
	for (int x = 0; x < 5; x++) {
		CCSpriteFrame *frame = [CCSpriteFrame frameWithTexture:danceSheet.texture rect:CGRectMake(x*85,y*121,85,121) offset:ccp(0,0)];
		[danceAnimation addFrame:frame];
 
		frameCount++;
 
		if (frameCount == 14)
			break;
	}
}

5. Run the CCAnimation on the CCSprite

Finally, we need to create a CCAnimate action instance which we can run on the CCSprite. Below, we also wrap the CCAnimate action in a CCRepeatForever action that does what you would expect: repeats the animation… forever.

The last line actually plays the animation on the sprite using the runAction message.

CCAnimate *danceAction = [CCAnimate actionWithAnimation:danceAnimation];
CCRepeatForever *repeat = [CCRepeatForever actionWithAction:danceAction];
[danceSprite runAction:repeat];

Putting it All Together

Here is what the above code looks like in a CCScene init method:

//
//  DanceScene.m
//  GrossiniDance
//
 
#import "DanceScene.h"
 
 
@implementation DanceScene
-(id)init {
	self = [super init];
 
	if (self) {
		// create the sprite sheet
		CCSpriteSheet *danceSheet = [CCSpriteSheet spriteSheetWithFile:@"grossini_dance_atlas.png"];
		[self addChild:danceSheet];
 
		// create the sprite
		CCSprite *danceSprite = [CCSprite spriteWithTexture:danceSheet.texture rect:CGRectMake(0, 0, 85, 121)];
		[danceSheet addChild:danceSprite];
 
		// position the sprite in the center of the screen
		CGSize s = [[CCDirector sharedDirector] winSize];
		danceSprite.position = ccp(s.width/2,s.height/2);
 
		// create the animation
		CCAnimation *danceAnimation = [CCAnimation animationWithName:@"dance" delay:0.1f];
 
		int frameCount = 0;
		for (int y = 0; y < 3; y++) {
			for (int x = 0; x < 5; x++) {
				CCSpriteFrame *frame = [CCSpriteFrame frameWithTexture:danceSheet.texture rect:CGRectMake(x*85,y*121,85,121) offset:ccp(0,0)];
				[danceAnimation addFrame:frame];
 
				frameCount++;
 
				if (frameCount == 14)
					break;
			}
		}
 
		// create the action
		CCAnimate *danceAction = [CCAnimate actionWithAnimation:danceAnimation];
		CCRepeatForever *repeat = [CCRepeatForever actionWithAction:danceAction];
 
		// run the action
		[danceSprite runAction:repeat];
	}
 
	return self;
}
@end

Our Games

Latest Tweets