animationcocos2d-iphoneccspritesprite-sheet

Cocos2d Two animations for one sprite


I animate my character like that :

-(void) createHero
{


    _batchNode = [CCSpriteBatchNode batchNodeWithFile:@"Snipe1.png"];
    [self addChild:_batchNode];
    [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"Snipe1.plist"];

    //gather list of frames
    NSMutableArray *runAnimFrames = [NSMutableArray array];
    for(int i = 1; i <= 7; ++i) 
    {
        [runAnimFrames addObject:
        [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:
        [NSString stringWithFormat:@"run000%d.png", i]]];
    }

    //create sprite and run the hero
    self.hero = [CCSprite spriteWithSpriteFrameName:@"run0001.png"];
    _hero.anchorPoint = CGPointZero;
    _hero.position = self.heroRunningPosition;

    //create the animation object
    CCAnimation *runAnim = [CCAnimation animationWithFrames:runAnimFrames delay:1/30.0f];
    self.runAction = [CCRepeatForever actionWithAction: [CCAnimate actionWithAnimation:runAnim restoreOriginalFrame:YES]];

    [_hero runAction:_runAction];
    [_batchNode addChild:_hero z:0];
}

This works fine an my character is running, but now i want a second animation when he jumps. At the moment i make it like that:

-(void)changeHeroImageDuringJump 
{
    [_hero setTextureRect:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"run0007.png"].rect]; 
}

But now i want a second plist with a second png, so i get a whole new animation when the character jumps. How can i implement that ?


Solution

  • In my case, i implemented an AnimatedSprite class that will handle this for me. This way, I add files like so:

    NSDictionary* anims = [NSDictionary dictionaryWithObjectsAndKeys:
            @"Animations/Character/idle_anim.plist", @"Idle",
            @"Animations/Character/walk_anim.plist", @"Walk",
            @"Animations/Character/run_anim.plist",    @"Run", nil];
    
    CCNode* myNode = [[AnimatedSprite alloc] initWithDictionary:anims 
                          spriteFrameName: @"character_idle_01.png"
                            startingIndex:@"Idle"];
    

    Changing the animation is as simple as:

    [myNode setAnimation: @"Run"];
    

    Heres my implementation This is the .h

    @interface AnimatedSprite : CCSprite
    {
        NSMutableDictionary* _spriteAnimations;
        CCAction* _currentAnimation;
        NSString* _currentAnimationName;
        bool _initialized;
    }
    - (id) initWithTextureName:(NSString*) textureName;
    - (id) initWithArray: (NSArray*) animList spriteFrameName: (NSString*) startingSprite startingIndex: (int)startingIndex;
    - (id) initWithDictionary:(NSDictionary *)anims spriteFrameName:(NSString *)startingSprite startingIndex:(NSString *)startingAnim;
    
    - (void) addAnimation: (NSString*) animationName andFilename: (NSString*) plistAnim;
    
    - (void) setAnimationIndex: (int) index;
    - (void) setAnimation: (NSString*) animationName;
    @end
    

    And this is the .m

    #import "AKHelpers.h"
    
    @implementation AnimatedSprite
    
    NSMutableDictionary* _spriteAnimations;
    
    - (id) initWithTextureName:(NSString*) textureName
    {
        CCTexture2D* texture = [[CCTextureCache sharedTextureCache] addImage:textureName];
        CCSpriteFrame* frame = [CCSpriteFrame frameWithTexture:texture rect: CGRectMake(0, 0, 1, 1)];
    
        if ((self=[super initWithSpriteFrame:frame]))
        {
            _currentAnimationName = nil;
            _currentAnimation = nil;
            _spriteAnimations = [[NSMutableDictionary alloc] init ];
            _initialized = true;
    
        }
        return self;
    }
    - (id) initWithArray: (NSArray*) animList spriteFrameName: (NSString*) startingSprite startingIndex: (int)startingIndex
    {
        _initialized = false;
        _spriteAnimations = [[NSMutableDictionary alloc] init];
    
        // Add animations as numbers from 0 to animList.count
        int i = 0;
        for (NSString* anim in animList)
        {
            [self addAnimation: [NSString stringWithFormat:@"%d", i] andFilename:anim];
            i++;
        }
    
        if ((self = [super initWithSpriteFrameName:startingSprite]))
        {
            _currentAnimationName = nil;
            _currentAnimation = nil;
            [self setAnimationIndex: startingIndex];  
            _initialized = true;  
        }
    
        return self;
    }
    
    - (id) initWithDictionary:(NSDictionary *)anims spriteFrameName:(NSString *)startingSprite startingIndex:(NSString *)startingAnim
    {
        _initialized = false;
        _spriteAnimations = [[NSMutableDictionary alloc] init];//[[NSMutableArray alloc] init];
    
        // Add animations
        for (NSString* key in anims)
        {
            [self addAnimation: key andFilename: [anims objectForKey: key] ];
        }
    
        if ((self = [super initWithSpriteFrameName:startingSprite]))
        {
            _currentAnimationName = nil;
            _currentAnimation = nil;
            [self setAnimation: startingAnim];
            _initialized = true;
    
        }
        return self;
    }
    - (void) dealloc
    {
        [_currentAnimationName release];
        [_spriteAnimations release];
        [super dealloc];
    }
    
    - (void) setAnimation: (NSString*) animationName
    {
        if (![_currentAnimationName isEqualToString:animationName])
        {
            [_currentAnimationName release];
            _currentAnimationName = [animationName copy];
    
            // Stop current animation
            if (_currentAnimation != nil)
                [self stopAction:_currentAnimation];
            //[self stopAllActions];
    
            // Apply animation
            NSDictionary* clip = [_spriteAnimations objectForKey: animationName];
            if (clip)
            {
                _currentAnimation = [AKHelpers actionForAnimationClip:clip];
                if (_currentAnimation)
                    [self runAction:_currentAnimation];
            }
            else
            {
                _currentAnimation = nil;
            }
        }
    }
    
    - (void) setAnimationIndex: (int) index
    {
        [self setAnimation: [NSString stringWithFormat:@"%d", index]];
    }
    
    - (void) addAnimation: (NSString*) animationName andFilename: (NSString*) plistAnim
    {
        NSDictionary *clip = [AKHelpers animationClipFromPlist:plistAnim];
    
        if (clip)
        {
            [_spriteAnimations setObject:clip forKey:animationName];        
    
            if (_initialized && [_spriteAnimations count] == 1)
            {
                [self setAnimation:animationName];
            }
        }
    }
    
    @end