Friday, June 18, 2010

Load animation from a plist file in Cocos2d

For current version of cocos2d(I am using v0.99.1), to construct an animation, you will need to add all those frames for a certain animation from code. You will need to code following.


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" delay:0.2f frames:animFrames];
[sprite runAction:[CCRepeatForever actionWithAction: [CCAnimate actionWithAnimation:animation restoreOriginalFrame:NO]]];


This is quite handy. However, i think this is not neat enough.

What i do is create an CCAnimatedSprite which inherit CCSprite. Which will retrieve all frame information from a plist file.

Advantages:
- clearer code
- a more centralized and flexible approach
- can set delay time between frame
- a future support for Animation Editor

Disadvantage:
- need more loading time
- need to create a plist file for each animation

To use CCAnimatedSprite, you need to first create a animation plist file. Please download the source file and take a look at uggyAnimation.plist.





You can use uggyAnimation.plist as a template and add any animation you need. Basically, the uggyAnimation.plist is based on zwoptex spritesheet. You need to indicate the coordinate file and the image source file generated from zwoptex.
After that, all you need is create animation and add frame for the animation.
You may take a look at the Walk_FlipY aniamtion in the uggyAnimation.plist. It contains 4 items. Each item is a frame for Walk_FlipY aniamtion. What you need to provide for this frame are
1. FrameName - which is the frame name refer to the name in zwoptex spritesheet
2. Time - the delay time for this frame
3. FlipX - should the frame flip horizontal
4. FlipY - should the frame flip vertical


After you create the animation plist file, what left is simple use CCAnimatedSprite to play the aniamtion by the animation name using following code.


animatedSprite3 = [[CCAnimatedSprite alloc] initWithAnimationFile:@"uggyAnimation.plist"];
[animatedSprite3 playAnimation:@"Walk_FlipY"];
animatedSprite3.position = ccp(380,260);
animatedSprite3.shouldLoop = true;
//let the sprite handle the animation
[animatedSprite3 schedule:@selector(tick:)];



FTP: Download Source Here

Thursday, May 27, 2010

Cocos2d support for Motion Welder

Hello. This is a first development post from Paper Plane Studio and please bare our poor english.
I am Jack Ng. I would like to shared some experience and codes about making animation on cocos2d.

In this post, i will shared how to use Motion Welder to make animation and how to play it with CCMWSprite. Motion Welder is an animation editor target on J2ME development.
If your game have complicate animation, adding animation using CCAnimation may need lots of code and waste lots of time. Using Motion welder has following advantages.
- clean code, only several line of code need
- motion welder handle the anchor point, you will never need to set anchor point any more
- what artist see is what will come out on iPhone, the workflow can be more smooth
- z order is handled by Motion Welder

If you know nothing about Motion Welder, check this link and try it  http://www.motionwelder.com/. If you are using Windows simply click the MotionWelder.exe to open it. If you are using mac, you can click the lib.jar to open it.

After you download Motion Welder, load the project test.asd from the file MWTutorial.zip.
Play with it.
You can also find a tutorial in the offical website of Motion Welder.
http://www.motionwelder.com/tutorial.php.  Read through Step1-Step5.


After you export a .anu file.  You can load the file, say test.anu using following code.
//test sprite with two image source, and clips from two images
NSArray* imageSourceList = [NSArray arrayWithObjects:@"uggy.png",@"platform.png",nil];
mwsprite1 = [[CCMWSprite alloc] initWithMWFile:@"test.anu" withImageList:imageSourceList withAnimationIndex:0];
mwsprite1.shouldLoop = true;
mwsprite1.scale = 2.0f;
mwsprite1.rotation = 30;
mwsprite1.position = ccp(240,160);
mwsprite1.delegate = self;


uggy.png and platform.png are the SpriteSheet use in Motion Welder. You need to follow the order you import in Motion Welder.

You also need to schedule a timer to call tick function in CCMWSprite. This is need if you are going make it automatically change frame for you.
Automatically handle playing of animation
[mwsprite1 schedule:@selector(tick:)]


or you can manually switch the frame by
[mwsprite1 setFrameIndex:0]

 How the animation will play can be controlled from Motion Welder using delay frame count for individual frame.

It is advised to use the delay frame count from Motion Welder since you can preview the animation. What you see in motion welder is what you will get on iDevice. The default delay frame duration of Motion Welder is 0.1s, you can change it from Option. You will also need to change the minimum frame interval for CCMWSprite.
mwsprite2.minFrameInterval = 0.2;
       
For every CCMWSprite which extends CCNode, there will be corresponding CCSpriteSheet created and added ass a child CCMWSprite. If you got 10 CCMWSprite, there will at least 10 CCSpriteSheet created. This is not really a good practice. However, CCMWSprite can set a external CCSpriteSheet to shared between different CCMWSprite.

CCSpriteSheet* spriteSheet = [CCSpriteSheet spriteSheetWithFile:@"uggy.png"];
[self addChild:spriteSheet];

 //test sprite with two image source, and clips from two images
NSArray* imageSourceList = [NSArray arrayWithObjects:@"uggy.png",@"platform.png",nil];
mwsprite1 = [[CCMWSprite alloc] initWithMWFile:@"test.anu" withImageList:imageSourceList withAnimationIndex:0];
mwsprite1.shouldLoop = true;
mwsprite1.scale = 2.0f;
mwsprite1.rotation = 30;
mwsprite1.position = ccp(240,160);
mwsprite1.delegate = self;
[self addChild:mwsprite1];

//can set a external sprite sheet
//this can share the SpriteSheet for all CCMWSprite with same image souceto increase performance
[mwsprite1 setExternalSpriteSheet:spriteSheet forImageIndex:0];


In the source file, there is a CCAnimatedSprite which load animation from a .plist file. If anyone is interest at that part and do not understand the code. Plz tell me and i am willing to write a simple tutorial. Hope you enjoy this post.

FTP: Download Source Here
HTTP: Download Source Here