【cocos2dx 3.x】CCSpriteBatchNode

转载自:http://www.apkbus.com/android-854-1.html


之前我们简单地介绍了一下自定义一个精灵,使其在初始化的时候即实现动画,并利用了纹理图册精简代码,今天我们着重介绍一下CCSpriteBatchNode,这是一个相当重要的概念,游戏开发不像应用,大量的动画图片,高速的计算,大量的图形占用,所以我们不得不将图形优化放到一个很高的位置,好在cocos2d在这一块儿上封装得很好,我们只需要了解一下一些类的基本用法,就可以很简单地优化代码;

CCSpriteBatchNode是对绘制精灵进行优化的一个辅助类,看类名我们就可以知道其是一个Node,生成精灵的时候我们需要将其放到层上,如果用CCSpriteBatchNode的话,我们只需要将一个CCspriteBatchNode对象放到该层上,其后将一个一个精灵放到该对象上即可;这样说有些笼统,看一个简单的例子:

有一张png图片"fish.png“,我们需要通过其创建一个精灵添加到层上,那么传统的方式就是:

CCSprite *fishSprite = [CCSprite spriteWithFile:@"fish.png"];

[layer addChild:fishSprite];

如果该层上有10个精灵呢?那就加个for循环,代码上我们感觉效率不低,但在硬件底层,openGL在绘制的时候每次绘制一个精灵,都要有一个准备的过程,形象的说,就像一个画家要画十只鱼,画一只鱼的时候,需要准备调色盘,画笔,画完一只,收起来;画第二只的时候,再准备调色盘,再画,画完再收好;如此十次,画得越多,耽误的越多;这样说的话你就会觉得这个画家有点二,但是传统的绘制精灵还真就是这样,机器不是人,他是不知道自己变通的;所以我们就要用到CCSpriteBatchNode了,上面的代码我们可以这样来改动:

CCSpriteBatchNode *fishBatch = [CCSpriteBatchNode batchNodeWithFile :@"fish.png"];

[layer addChild:fishBatch];

CCSprite *fishSprite = [CCSprite spriteWithFile:@"fish.png"];

[fishBatch addChild:fishSprite];

这样写你可能不觉得有什么优化,但是fishBatch里面添加的精灵越多,其优势就越明显,还是刚才的例子,之前每画一条鱼,都会准备,绘制,收起;现在将精灵添加进fishBatch,就像这个画家知道一次性要画多少条鱼,就不会那么死板的进行一次又一次额外重复的工作了;


如果我们将CCSpriteBatchNode与动画相结合的话,没有关系,假设已生成动画anim;

CCSpriteBatchNode *fishBatch = [CCSpriteBatchNode batchNodeWithFile :@"fish.png"];

[layer addChild:fishBatch];

CCSprite *fishSprite = [CCSprite spriteWithFile:@"fish.png"];

[fishSprite runAction: anim];

[fishBatch addChild:fishSprite];

下面我们来看一个将CCSpriteBatchNode,纹理图册,自定义精灵类(默认初始化运行动作),CCSpriteFrameCache结合起来的例子:

自定义精灵类fishSprite.h:


#import <Foundation/Foundation.h>

#import "cocos2d.h"


@interface fishSprite : CCSprite {

    

}

+(id)fish;

@end


fishSprite.m

#import "fishSprite.h"


@implementation fishSprite
+(id)fish
{
    return [[self alloc]initWithImage];
}

-(id)initWithImage
{
    if ((self=[super init])) {
             [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"fish.plist"];
        // 将所有fish.plist相关的精灵添加到缓存里;
        
      
        
        self = [CCSprite spriteWithSpriteFrameName:@"fish1.png"];
        //这句很关键,不加这句,CCSproteBatchNode和自定义生成的精灵不会采用同一个纹理,这样强行采用这种技术就会报错;
        
        //下面将纹理图册中的纹理组成动画;使用CCSpriteFrameCache和纹理图册结合会很方便;
        NSMutableArray *frameArray = [NSMutableArray array];
        
        for (int i = 1; i<15; i++) {
            [frameArray addObject:
             [[CCSpriteFrameCache sharedSpriteFrameCache ]spriteFrameByName:
              [NSString stringWithFormat:@"fish%d.png",i]]];
        }
       
        CCAnimation *fishAnimation = [CCAnimation animationWithSpriteFrames:frameArray delay:0.05f];
        CCAnimate *animate = [CCAnimate actionWithAnimation:fishAnimation];
        
       
        
               
             
        [self runAction:[CCRepeatForever actionWithAction:animate]];
        //使该精灵一生成就会运动;
        
     
        
        
        
        
        
        
        


    }
    return self;
}
@end

之后在显示层的init方法中这样添加:
-(id)init
{
    // ask director for the window size
   
    if (self = [super init]) {
        CGSize size = [[CCDirector sharedDirector] winSize];
        
        CCSprite *background;
        
        
        background = [CCSprite spriteWithFile:@"bg.jpg"];
        
        background.position = ccp(size.width/2, size.height/2);
        
        // add the label as a child to this Layer
        [self addChild: background];
        
        
        //    //在层上添加精灵;
        
        
        CCSpriteBatchNode *fishBatch = [CCSpriteBatchNode batchNodeWithFile:@"fish.png"];
        [self addChild:fishBatch];
        
        CCSprite *fish = [fishSprite fish];
        fish.position = ccp(140, 150);
        
        [self addChild:fish];
        [self scheduleUpdate];
        

    }
   
    return self;
}

这样,代码中的注释很明白,这里再强调一下几点:

1、CCSpriteBatchNode中添加的精灵所依赖的生成纹理必须是一样,包括生成CCSpriteBatchNode对象时所使用的纹理;

2、所有添加进去的精灵,z轴都是一样的,即都依赖于CCSSpriteBatchNode对象的z轴;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值