閱讀44 返回首頁    go 技術社區[雲棲]


精靈性能優化-使用精靈幀緩存

精靈幀緩存是緩存的一種,緩存有如下幾種:

紋理緩存(TextureCache)“。使用紋理緩存可以創建紋理對象,在上一節我們已經用到了。

精靈幀緩存(SriteFranmeCache)。能夠從精靈表中創建精靈幀緩存,然後再從精靈幀緩存中獲得精靈對象,反複使用精靈對象時候,使用精靈幀緩存可以節省內存消耗。

動畫緩存(AnimationCache)。動畫緩存主要用於精靈動畫,精靈動畫中的每一幀是從動畫緩存中獲取的。

這一個節我們主要介紹精靈幀緩存(SpriteFrameCache),要使用精靈幀緩存涉及到的類有:SpriteFrame和SpriteFrameCache。使用SpriteFrameCache創建精靈對象的主要代碼如下:

         

 SpriteFrameCache::getInstance()->addSpriteFramesWithFile("SpirteSheet.plist");                              ①
auto mountain1 =Sprite::createWithSpriteFrameName("mountain1.png");                                             ②

上述代碼第①行是通過SpriteFrameCache創建精靈幀緩存對象,它是采用單例設計模式進行設計的,getInstance()函數可以獲得SpriteFrameCache單一實例,addSpriteFramesWithFile函數是將精靈幀添加到緩存中,其中SpirteSheet.plist是坐標文件。我們可以多次調用addSpriteFramesWithFile函數添加更多的精靈幀到緩存中。

第②行代碼Sprite::createWithSpriteFrameName("mountain1.png")是通過Sprite的createWithSpriteFrameName函數創建精靈對象,其中的參數mountain1.png是SpirteSheet.plist是坐標文件中定義的精靈幀名(見SpirteSheet.plist文件代碼中的第②行)。

下麵我們會通過一個實例介紹精靈幀緩存使用,這個實例如下圖所示,在遊戲場景中有背景、山和英雄三個精靈。


在HelloWorldScene.cpp實現的init函數代碼如下:

bool HelloWorld::init()
{
   if ( !Layer::init() )
   {
       return false;
   }
   
   Size visibleSize = Director::getInstance()->getVisibleSize();
   Point origin = Director::getInstance()->getVisibleOrigin();
 
    autobackground = Sprite::create("background.png");                                                                 ①
    background->setAnchorPoint(Point::ZERO);
   this->addChild(background,0);
   
    SpriteFrameCache*frameCache = SpriteFrameCache::getInstance();                               ②
    frameCache->addSpriteFramesWithFile("SpirteSheet.plist");                                                      ③
 
   auto mountain1 =Sprite::createWithSpriteFrameName("mountain1.png");                              ④
    mountain1->setAnchorPoint(Point::ZERO);
   mountain1->setPosition(Point(-200,80));
   this->addChild(mountain1,0);
 
    SpriteFrame*heroSpriteFrame = frameCache->getSpriteFrameByName("hero1.png");            ⑤
    Sprite*hero1 = Sprite::createWithSpriteFrame(heroSpriteFrame);                                              ⑥
   hero1->setPosition(Point(800,200));
   this->addChild(hero1,0);
 
   return true;
}

上述代碼第①行是創建一個背景精靈對象,這個背景精靈對象,並不是通過精靈緩存創建的,而是直接通過精靈文件直接創建的,事實上我們完全也可以將這個背景圖片放到精靈表中。

第②行代碼是獲得精靈緩存對象。第③行代碼是通過addSpriteFramesWithFile函數為精靈緩存中添加精靈幀。在前麵的介紹中我們使用一條語句SpriteFrameCache::getInstance()->addSpriteFramesWithFile("SpirteSheet.plist")替代第②和第③行兩條語句。在這裏我們分成兩條語句是因為後麵我們還有使用frameCache變量。

第④行代碼是使用Sprite 的createWithSpriteFrameName函數創建精靈對象,其中的參數是精靈幀的名字。

代碼第⑤~⑥行是使用精靈緩存創建精靈對象的另外一種函數,其中第⑤行代碼是使用精靈緩存對象frameCache的getSpriteFrameByName函數創建SpriteFrame對象,SpriteFrame對象就是“精靈幀”對象,事實上在精靈緩存中存放的都是這種類型的對象。第⑥行代碼是通過精靈幀對象創建。第⑤和⑥行使用精靈緩存方式主要應用於精靈動畫時候,相關的知識我們將在精靈動畫部分介紹。

精靈緩存不再使用後忘記清空或移除相關精靈幀,否則如果有相同名稱的精靈幀時候,就會出現一些奇怪的現象。清空或移除精靈幀的緩存函數如下:

pvoid removeSpriteFrameByName(conststd::string & name)。指定具體的精靈幀名移除。
pvoid removeSpriteFrames()。指定清空精靈緩存。
pvoidremoveSpriteFramesFromFile(const std::string & plist)。指定具體的坐標文件移除精靈幀。
pvoid removeUnusedSpriteFrames()。移除沒有使用的精靈幀。

如果為了防止該場景中的精靈緩存對下一個場景產生影響,我們可以在當前場景所在層的onExit函數中調用這些函數,相關代碼如下:

void HelloWorld::onExit()
{
    Layer::onExit();
    SpriteFrameCache::getInstance()->removeSpriteFrames();
}

onExit()函數是層退出時候回調的函數,與init函數類似都屬於層的生命周期中的函數。我們要在h文件中定義,在cpp文件中聲明。HelloWorld.h文件的相關代碼如下:

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
 
#include "cocos2d.h"
 
class HelloWorld : public cocos2d::Layer
{
public:
   … …
    virtualbool init(); 
        //退出Layer回調函數
        virtualvoid onExit();    
   … …
   CREATE_FUNC(HelloWorld);
};
 
#endif // __HELLOWORLD_SCENE_H__
當然精靈緩存清除工作也可以放到下一個場景創建時候,也就是下一個場景所在層的init函數中實現,相關代碼如下:
bool HelloWorld::init()
{
   … …   
   SpriteFrameCache::getInstance()->removeSpriteFrames();
   SpriteFrameCache::getInstance()->addSpriteFramesWithFile("SpirteSheet.plist");
   … …   
}
 

 


更多內容請關注Cocos2d-x係列圖書《Cocos2d-x實戰(卷Ⅰ):C++開發》
本書交流討論網站:https://www.cocoagame.net
歡迎加入cocos2d-x技術討論群:257760386、327403678

最後更新:2017-04-03 08:26:15

  上一篇:go 常用WebService接口
  下一篇:go 常用WebService接口