I'm currently developing a mobile game with Kobold2d (cocos2d), but I having some trouble to animate one CCSprite with more than one animation. My question is: With the same CCSprite (player) how to animate it with two different animation. I'm using Kobold2D 2.0.4 and Xcode 4.6, and for animation I have a textureAtlas compressed with pvr.ccz.
I create an animation helper class:
+(CCAnimation *) startFrames:(int) startFrame
endFrame:(int) endFrame
frameName:(NSString *) frameName
delay:(float) delay
{
NSMutableArray *frames = [NSMutableArray arrayWithCapacity:endFrame];
CCSpriteFrameCache *sharedFrameCache = [CCSpriteFrameCache sharedSpriteFrameCache];
for (int i = startFrame; i <= endFrame; i++) {
CCSpriteFrame *frame = [sharedFrameCache spriteFrameByName:[NSString stringWithFormat:@"%@%i.png",frameName,i]];
[frames addObject:frame];
}
return [CCAnimation animationWithSpriteFrames:frames delay:delay];
}
+(CCAnimation *) jumpPoints:(CGPoint[]) points
startFrames:(int) startFrame
endFrame:(int) endFrame
frameName:(NSString *) frameName
delay:(float) delay
{
NSMutableArray *frames = [NSMutableArray arrayWithCapacity:endFrame];
CCSpriteFrameCache *sharedFrameCache = [CCSpriteFrameCache sharedSpriteFrameCache];
for (int i = startFrame; i <= endFrame; i++) {
CCSpriteFrame *frame = [sharedFrameCache spriteFrameByName:[NSString stringWithFormat:@"%@%i.png",frameName,i]];
[frame setOffsetInPixels:points[i]];
[frames addObject:frame];
}
return [CCAnimation animationWithSpriteFrames:frames delay:delay];
}
I got a player class where I initialize the player and create two CCAnimation. In header file I store two CCAnimate type variables:
CCAnimate *jump;
CCAnimate *walk;
In .m file
-(id) init
{
if (self = [super init])
{
sprite = [[Loading shareLoading] loadTempCcsprite];
CGSize screenSize = [[CCDirector sharedDirector] winSize];
localPostion = CGPointMake(screenSize.width, screenSize.height);
CGPoint points[] = {CGPointMake(0, 10),CGPointMake(0, 50),CGPointMake(0, 80),
CGPointMake(0, 10),CGPointMake(0, 0)};
CCAnimation *animationJump = [CCAnimationHelper jumpPoints:points startFrames:0 endFrame:4 frameName:@"cactus" delay:0.10f];
jump = [CCAnimate actionWithAnimation:animationJump];
CCAnimation *animationWalk = [CCAnimationHelper startFrames:0 endFrame:4 frameName:@"cactus" delay:0.10f];
walk = [CCAnimate actionWithAnimation:animationWalk];
[self addChild:sprite];
}
return self;
}
Finally, I have input layer where the user got two jump button and attack and Joystick to move the player.
Here is the code:
-(void) update:(ccTime)delta
{
if ([jump active])
{
CCAnimate *animation = [player jump];
[player runAction:animation];
}
else if (joystick.velocity.x > 0)
{
float velocity = [joystick velocity].x * 700 * delta;
CGPoint playerPosition = CGPointMake([player localPostion].x + velocity * delta, [player localPostion].y );
id animation = [player walk];
[player runAction:animation];
[player setLocalPostion:playerPosition];
}
}
If I compile this code, in Input layer when I press jump button the game crash and the output console says:
* Assertion failure in -[CCActionManager addAction:target:paused:]
You are trying to run the same action again while it is still running.
To avoid this situation, always call stopAction before runAction:
[player stopAction:animation];
[player runAction:animation];