0

why CCSpriteBatchNode is not explicitly used with CCAnimation ? instead we use the following : (instead of adding each image to the batchNode and let the batchNode print those images, the code only uses spriteFrameByName) :

CCSpriteBatchNode *chapter2SpriteBatchNode = [CCSpriteBatchNode batchNodeWithFile:@"scene1atlas.png"];
CCSprite *vikingSprite = [CCSprite spriteWithSpriteFrameName:@"sv_anim_1.png"];
[chapter2SpriteBatchNode addChild:vikingSprite];


// Animation example with a CCSpriteBatchNode
CCAnimation *exampleAnim = [CCAnimation animation];
    [exampleAnim addFrame:
    [[CCSpriteFrameCache sharedSpriteFrameCache] 
    spriteFrameByName:@"sv_anim_2.png"]];

Thanks for your answer

Paul
  • 6,108
  • 14
  • 72
  • 128

1 Answers1

0

A batchNode is just a texture draw artefact ... has no knowledge whatsoever about what frames the texture contains, nor whether it embeds multiple 'logical' files in a single texture. You must create that association, typically by adding spriteFrame's to the spriteFrameCache, each spriteFrame providing metadata about a 'fragment' of the batchNode. Here is an example from one of my games:

-(void) setupIdleAnimation{

    [self setupAnimations];
    NSString* animationName = @"Idle";
    NSString* framesFileName = [self getPlistFileNameForAction:animationName];
    CCSpriteBatchNode *bn = [CCSpriteBatchNode batchNodeWithFile:[self getTextureFileNameForAction:animationName]];
    [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:framesFileName texture:bn.texture];

// create array of frames for the animation

    self.idleBatchNode=bn;

    NSMutableArray *animFrames = [NSMutableArray array];
    for(NSUInteger i = 1; i <= 8; ++i) {

        NSString *sfn = [self getFrameNameForAnimation:animationName
                                    andFrameNumber:i];

        CCSpriteFrame *sf = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:sfn];
        if(sf) {
            [animFrames insertObject:sf atIndex:i-1];
        } else {
            CCLOGERROR(@"%@<setupIdleAnimation> : *** Sprite frame named [%@] not found in cache, bailing out.",self.class,sfn);
            return;
        }
    }


    CCAnimation *anim=[CCAnimation animationWithFrames:walkAnimFrames delay:ANIM_FRAME_DELAY];
    [animFrames removeAllObjects];
    anim.name=animationName;

    self.idleAction = [CCRepeatForever 
                   actionWithAction:[CCAnimate actionWithAnimation:anim 
                                              restoreOriginalFrame:NO]] ;

    self.idleSprite = [CCSprite spriteWithSpriteFrameName:[self getFrameNameForAnimation:animationName
                                                                      andFrameNumber:1]];  
    self.idleSprite.visible=NO;
    [self.idleBatchNode addChild:self.idleSprite];
} 

So i have prepared in a .plist the data that describes where each frame is located in the texture, and add these definitions to the frame cache. The batchNode per say is a container that will optimise rendering performance. In the above example it is well suited singe the texture embeds the idle sprites for 16 character classes that are often in view and idling simultaneously.

You can find a good introduction in this tutorial.

YvesLeBorg
  • 9,070
  • 8
  • 35
  • 48
  • thanks YvesLeBorg for the answer, and the link ;) i better understand how this works, however: we can add a `CCSprite` instance to the batch node, but we cannot pass it a `CCAnimation` instance? both contain "frames" though, so both should use the same technique to optimize rendering performance? thanks – Paul Apr 18 '12 at 00:07
  • about performance, read Andrew's answer here http://stackoverflow.com/questions/10234570/suitability-of-using-core-animation-on-ios-vs-using-cocos2d-and-opengl-es – YvesLeBorg Apr 20 '12 at 11:19