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);


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