Sprite(精灵)全解

Sprite(精灵)全解

 

精灵是游戏中十分重要的组成部分,随处可见,如:游戏背景、NPC、人物、道具等。在cocos2d-x引擎中,只要是用图片展示的,基本上需要使用精灵类。

 

1. 首先来了解一下跟精灵相关的几个类:

(1) Texture2D

可以把它看成一个纹理,它是cocos2d-x渲染图形的重要参数,用来贴图,因为cocos2d-x使用openglES绘制2d图形的,它的尺寸是2的n次方。一般通过以下方式获得: 

//cocos2d-x3.0beta的用法
Texture2D * texture                                                   
= Director::getInstance()->getTextureCache()->addImage("hero.png"); 

(2) Sprite

这个就是精灵类,是Node的子类,它的内部封装了Texture2D(纹理),可以通过下面几种方式初始化精灵对象。  

static Sprite* create();
static Sprite* create(const std::string& filename);
//Rect表示图片的指定范围,即从图片的指定矩形区域裁剪
static Sprite* create(const std::string& filename, const Rect& rect);
//Texture2D表示精灵包含的图片,范围是整张图片
static Sprite* createWithTexture(Texture2D *texture);

//SpriteFrame表示精灵的某一帧,大多数情况下精灵本身的图片有多帧。它内部封装了Texture2D和Rect,可以从一个大图片取出一部分作为一帧。
static Sprite* createWithSpriteFrame(SpriteFrame *pSpriteFrame);
//SpriteFrameName表示帧的名字,根据帧名从内存中取出SpriteFrame
static Sprite* createWithSpriteFrameName(const std::string& spriteFrameName);

(3) TextureCache

它相当于Texture2D的容器,是内存池,用来缓存Texture2D对象的。当调用它的addImage函数添加图片时,会先根据图片名称去内存中查找是否已存在,是则直接取出返回。

如果需要一次加载多张图片的时候,可以先把图片加载到TextureCache中,这样使用图片的时候速度就会很快了。


(4 SpriteFrameCache

它是管理SpriteFrame的内存池,跟TextureCache功能一样,不过跟TextureCache不同的是,如果内存池中不存在要查找的帧,它会提示找不到,而不会去本地加载图片。SpriteFrameCache一般用来处理plist文件(这个文件指定了每个独立的精灵在这张“大图”里面的位置和大小),该文件对应一张包含多个精灵的大图,plist文件可以使用TexturePacker制作。如下图所示:


创建精灵方法:利用帧缓存中的一帧的名称声称一个对象,适合于plist打包好的文件:

SpriteFrameCache::getInstance()->addSpriteFramesWithFile("animations/grossini.plist", "animations/grossini.png");
sprite* hero = sprite::createWithSpriteFrameName("grossini_dance_01.png");

只要plist文件跟对应的png图片在同一目录下,且名字相同,则addSpriteFramesWithFile(“animations/ grossini.plist”, “animations / grossini.png”);

可以改成addSpriteFramesWithFile(“animations/grossini.plist”);

 

创建精灵方法:利用另外一帧生成一个精灵对象,适合于做帧动画使用。

SpriteFrame* frame = SpriteFrame::create("icon.png", Rect(0, 0, 40, 30));
Sprite* sprite = Sprite::createWithSpriteFrame(frame);

 (5) SpriteBatchNode

它是批处理绘制精灵,主要是用来提高精灵的绘制效率的,需要绘制的精灵数量越多,效果越明显。因为cocos2d-x采用opengl es绘制图片的,opengl es绘制每个精灵都会执行:open-draw-close流程。而SpriteBatchNode是把多个精灵放到一个纹理上,绘制的时候直接统一绘制该texture,不需要单独绘制子节点,这样opengles绘制的时候变成了:open-draw()-draw()…-draw()-close(),节省了多次open-close的时间。注意:因为绘制的时候只open-close一次,所以SpriteBatchNode对象的所有子节点都必须和它是用同一个texture(同一张图片),类似下面这样的图片,4个贝壳都在同一纹理上:

 

1.  直接使用Layer进行添加精灵,Layer上有几个精灵,那么底层就会绘制几次精灵;

简单可以理解成底层绘制方式如下:

for(int i= 0;i<100;i++){open-draw-close;}

但是使用集合的话,Layer只需要对精灵集合进行一次渲染,

简单可以理解成底层绘制方式如下:

open-draw(100次绘制)-close

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

2.使用SpriteBathNode虽然能达到优化,但是要注意一点:

初始化精灵集合SpriteBatchNode的时候会加载一张图片资源(或者pvr文件等),那么限制其精灵集合的子精灵都必须使用集合加载的这张图才行,否则会给出警告;

3.使用SpriteBatchNode还要注意一点,因为精灵都存放在集合中,那么这个集合SpriteBatchNode中的节点(精灵)都将在同一个z轴上,同一深度上;

一般使用TexturePacker工具都会将很多精灵图片或者动作帧放在一起打包成“.pvr.z”、”.plist”、“-hd.pvr.z”和”-hd.plist”的四个文件,其中两个-hd的是使用工具生成的打包资源的高清版本(940*480)使用的,这个不再强调了;


那么肯定会有童鞋说,那么如果把这资源文件与SpriteBathNode结合使用岂不是更嗨皮,没错,可以的,加载的时候只需要将如下创建集合即可:


创建精灵方法:SpriteBathNode与SpriteFrameCache结合使用。

//加载图片资源
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("xx.plist");
SpriteBatchNode aParenet = SpriteBatchNode::create("xx.pvr.z");
this->addChild(aParenet);

Sprite *pFather = Sprite::spriteWithSpriteFrameName("father.gif");
pFather->setPosition(p(s.width / 2, s.height / 2));
aParenet->addChild(pFather);


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章