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:

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











Below is a recap of all of the iPhone app development tips we posted in the month of December advent-style. We hope this serves as a one-stop shop for many aspects of iPhone development that are commonly encountered.
Today’s advent tip is how to open the Messages app (aka the SMS app) with a specific phone number populated in the To: field. This is accomplished with great ease because the iPhone has implemented the sms: URI scheme. Therefore, we can use the UIApplication class’ openURL method, which we have seen before when we discussed how to
If you were watching twitter this week, you might have heard that
If you replaced OpenFeint 2.3.x in your project with the new 2.4 source, you might have gotten a bunch of nasty errors upon building it. This is because the OpenFeint 2.4 requires more libraries to be added to your target. You need to add the following 3 frameworks to your target to get your OpenFeint 2.4 game to build successfully: