Cocos2D-iphone 开发之(7) 纹理 精灵 动画

首先介绍一下纹理的相关概念。

Image ----》 纹理 (Texture)  ---》内存  ---》GPU

游戏在运行过程中要把所有要使用到的图片都加载成GPU可以理解执行的OpenGL ES纹理,注意图像填充到纹理中时,其长度和宽度都应该是2的N次方。

CCTexture2D 这是cocos2d中内置的一个纹理类,用于管理纹理的相关信息,它知道如何将自己绘制到屏幕上,我们可以通过这个类创建纹理的实例对象。

CCTextureCache 纹理缓存管理,负责加载图片并对生成的纹理进行管理。通过“字典”来进行快速的查询,作为单例使用。

CCTextureAtlas 纹理图集,就是把多个纹理合并成的一个大的纹理图。


CCTexture2D *text2d = [[CCTextureCache sharedTextureCache] addImage:file]; 



下面介绍一下与精灵有关的内容。

Cocos2D-iphone 开发之(7) 纹理 精灵 动画_第1张图片


通过上面的这个关系图,我们可以知道,CCSprite 精灵和  CCSpriteFrame 精灵帧都是由Texture 纹理绘制的,CCTexture2D就是封装了Texture纹理的类,精灵和精灵帧都必须被赋予一个CCTexture2D的对象才能工作。所以,通过CCTextur2D的实例对象可以创建精灵和精灵帧。

CCSpriteBatchNode精灵表单是用于管理CCSprite精灵的,它其实是很多精灵的集合。那么它有什么作用呢?

一般我们使用精灵sprite的时候,我们是通过addChild的方式把精灵添加到一个layer中,sprite的draw函数在每一帧调用时都会执行opengl es调用来完成

sprite的渲染。那么当你有多个精灵都通过addChild的方式添加到layer的时候,就会单独绘制多次,就会调用多次的opengl es对精灵进行渲染,那这样的话是很

浪费资源和时间的。

而有了精灵表单CCSpriteBatchNode 后,我们是先把任意个的精灵添加到精灵表单之后,再把精灵表单addChild到layer,这个时候才调用opengl es对精灵

表单中所有的精灵进行渲染。

举个例子,假如我们需要添加100个精灵

①如果不使用精灵表单,那么底层的绘制过程我们可以这样理解     for(int i= 0;i<100;i++){open-draw-close;}

②使用精灵表单的话,那么就是对这100个精灵集合的精灵表单进行一次渲染,也即  open-draw(100次绘制)-close

从以上两种方式可以看出两者的区别了,第二种使用精灵集合省去了99次open和close的过程,从而达到优化处理的作用;


CCSpriteFrame  精灵帧

CCSpriteFrameCache  精灵帧缓存

精灵帧主要是用来制作动画的,cocos2d用CCAnimation保存一个精灵帧序列,然后用CCAnimate这个行为类根据序列定时切换精灵的当前帧实现动画效果,而精灵帧缓存就是主要存放精灵帧的,其主要作用也是优化精灵帧。


下面介绍一下动画,其实动画也是属于CCAction。

Cocos2D-iphone 开发之(7) 纹理 精灵 动画_第2张图片


通过上面这张关系图讲解动画。

1、首先要了解三个概念:

CCAnimate 动画动作  在sprite对象上执行的动画动作

CCAnimation 动画  在CCAnimate动作的对象

CCAnimationCache 这个类是单例,缓存CCAnimation动画,也是用于优化的。

2、普通创建动画的步骤:

①首先创建sprite,并add到当前节点

②创建CCAnimation动画动作的对象,添加帧内容(精灵帧)

③创建CCAnimate动画动作,并指定动作的对象animation

④sprite执行动作

示例代码如下:

CCTexture2D *texture = [[CCTextureCache sharedTextureCache] addImage:@"dragon.png"];
        CCSpriteBatchNode *spriteBatchNode = [CCSpriteBatchNode batchNodeWithTexture:texture];
        [self addChild:spriteBatchNode];
        
        NSMutableArray *framesArray = [NSMutableArray array];
        for (int i=0; i<8; i++) {
            for (int j =0; j<10; j++) {
                CCSpriteFrame *frame = [CCSpriteFrame frameWithTexture:texture rect:CGRectMake(j*75, i*70, 75, 70)];
                [framesArray addObject:frame];
            }
        }
        
        CCAnimation *animation = [CCAnimation animationWithSpriteFrames:framesArray delay:0.1];
        CCAnimate *animate = [CCAnimate actionWithAnimation:animation];
        
        CCSpriteFrame *frame1 = [CCSpriteFrame frameWithTexture:texture rect:CGRectMake(0, 0, 72, 70)];
        CCSprite *sprite = [CCSprite spriteWithSpriteFrame:frame1];
        
        id repeatAction = [CCRepeatForever actionWithAction:animate];
        [sprite runAction:repeatAction];
        
        [sprite setPosition:ccp(150, 150)];
        [self addChild:sprite];

Cocos2D-iphone 开发之(7) 纹理 精灵 动画_第3张图片

这个是上面代码中所用到的资源图片。

3、

通过上面的普通创建动画的步骤可以知道,动画中包含着多个精灵帧,如果我们使用单独的精灵,那么每次都需要调用OpenGl ES 绘图命令,当游戏中有很多的精灵时,速度就会大大降低。那么就要考虑如何优化。

通常的方式是--精灵表单 CCSpriteBatchNode

关于精灵表单,就好像一张由很多个精灵的小图片拼接而成的大图,精灵表单会提供一个文件plist,在其中指定单个精灵的边界和大小,使用时从表单中提取单个精灵。

关于制作精灵表单,可以使用Zwoptex这个工具。它可以将我们需要用到的所有精灵图片制作成一个精灵表单大图png和一个plist文件。

有了png和plist就可以创建动画了。

步骤:

①使用plist文件将精灵纹理图添加到CCSpriteFrameCache中

②创建精灵表单CCSpriteBatchNode,添加到当前的节点。

注意:当需要从精灵表单中创建某一精灵对象时,我们应将其添加为精灵表单的子节点,而不能将其直接添加为当前层的子节点。

③从CCSpriteFrameCache(精灵帧缓存)中获取与图片名称相对应的精灵帧,然后创建精灵帧数组

④创建CCAnimation动画对象,传入精灵帧数组作为参数

⑤创建精灵,CCAnimate,执行CCAnimation动画对象

说明:这里动画包含的精灵帧愈多,那么动画的效果会愈好。

//  1.使用plist文件将精灵帧纹理添加到精灵帧缓存中
        [[CCSpriteFrameCache sharedSpriteFrameCache]addSpriteFramesWithFile:@"MyPanda_default.plist"];
        
        //  2.创建一个CCSpriteBatchNode(精灵表单)对象,并把它添加到当前的layer中,就会一次性加载这张精灵表单大图了。
        CCSpriteBatchNode *batchNode = [CCSpriteBatchNode batchNodeWithFile:@"MyPanda_default.png"];
        [self addChild:batchNode];
        
        //  3.创建图片帧列表(数组)
        NSMutableArray *walkAnimFrames = [NSMutableArray array];
        for(int i=1; i<=3;i++){
            [walkAnimFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache]spriteFrameByName:[NSString stringWithFormat:@"pandawalk%d.png",i]]];
        }
        
        //  4.通过精灵帧数组创建动画对象
        CCAnimation *walkAnim = [CCAnimation animationWithSpriteFrames:walkAnimFrames delay:0.5];
        //  5.创建精灵对象,并运行动画动作
        CGSize size = [CCDirector sharedDirector].winSize;
        
        //从精灵表单中的pandawalk1.png图片来创建sprite,项目中并没有这个图片文件
        CCSprite *panda = [CCSprite spriteWithSpriteFrameName:@"pandawalk1.png"];
        
        panda.position = ccp(size.width*0.8,size.height*0.4);
        id walkAction = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:walkAnim]];
        [panda runAction:walkAction];
        
        //注意这里:我们从精灵表单中创建了精灵,所以我们要把它添加为精灵表单的子节点
        [batchNode addChild:panda];


下面简单的解释一下这段代码。

我们通过plist文件初始化了精灵帧缓存,以后我们可以根据精灵帧所对应图片的名称来找到相应的精灵帧(plist中都保存着这些信息),所以注意图片资源文件的命名规则,都是以数字1 2 3 ...结尾的。

接着用纹理大图初始化精灵表单,通过add就可以一次性加载所有的精灵了。



你可能感兴趣的:(Cocos2D-iphone 开发之(7) 纹理 精灵 动画)