zoukankan      html  css  js  c++  java
  • 精灵性能优化-使用精灵帧缓存

    精灵帧缓存是缓存的一种,缓存有如下几种:

    纹理缓存(TextureCache)。使用纹理缓存可以创建纹理对象,在上一节我们已经用到了。

    精灵帧缓存(SpriteFrameCache)。能够从精灵表中创建精灵帧缓存,然后再从精灵帧缓存中获得精灵对象,反复使用精灵对象时候,使用精灵帧缓存可以节省内存消耗。

    动画缓存(AnimationCache)。动画缓存主要用于精灵动画,精灵动画中的每一帧是从动画缓存中获取的。

    这一个节我们主要介绍精灵帧缓存(SpriteFrameCache),要使用精灵帧缓存涉及到的类有:SpriteFrame和SpriteFrameCache。使用SpriteFrameCache创建精灵对象的主要代码如下:

            

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. SpriteFrameCache::getInstance()->addSpriteFramesWithFile("SpirteSheet.plist");                              ①  
    2. to 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函数代码如下:

     

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. bool HelloWorld::init()  
    2. {  
    3.    if ( !Layer::init() )  
    4.    {  
    5.        return false;  
    6.    }  
    7.      
    8.    Size visibleSize = Director::getInstance()->getVisibleSize();  
    9.    Point origin = Director::getInstance()->getVisibleOrigin();  
    10.    
    11.     autobackground = Sprite::create("background.png");                                                                 ①  
    12.     background->setAnchorPoint(Point::ZERO);  
    13.    this->addChild(background,0);  
    14.      
    15.     SpriteFrameCache*frameCache = SpriteFrameCache::getInstance();                               ②  
    16.     frameCache->addSpriteFramesWithFile("SpirteSheet.plist");                                                      ③  
    17.    
    18.    auto mountain1 =Sprite::createWithSpriteFrameName("mountain1.png");                              ④  
    19.     mountain1->setAnchorPoint(Point::ZERO);  
    20.    mountain1->setPosition(Point(-200,80));  
    21.    this->addChild(mountain1,0);  
    22.    
    23.     SpriteFrame*heroSpriteFrame = frameCache->getSpriteFrameByName("hero1.png");            ⑤  
    24.     Sprite*hero1 = Sprite::createWithSpriteFrame(heroSpriteFrame);                                              ⑥  
    25.    hero1->setPosition(Point(800,200));  
    26.    this->addChild(hero1,0);  
    27.    
    28.    return true;  
    29. }  

     

    上述代码第①行是创建一个背景精灵对象,这个背景精灵对象,并不是通过精灵缓存创建的,而是直接通过精灵文件直接创建的,事实上我们完全也可以将这个背景图片放到精灵表中。

    第②行代码是获得精灵缓存对象。第③行代码是通过addSpriteFramesWithFile函数为精灵缓存中添加精灵帧。在前面的介绍中我们使用一条语句SpriteFrameCache::getInstance()->addSpriteFramesWithFile("SpirteSheet.plist")替代第②和第③行两条语句。在这里我们分成两条语句是因为后面我们还有使用frameCache变量。

    第④行代码是使用Sprite 的createWithSpriteFrameName函数创建精灵对象,其中的参数是精灵帧的名字。

    代码第⑤~⑥行是使用精灵缓存创建精灵对象的另外一种函数,其中第⑤行代码是使用精灵缓存对象frameCache的getSpriteFrameByName函数创建SpriteFrame对象,SpriteFrame对象就是“精灵帧”对象,事实上在精灵缓存中存放的都是这种类型的对象。第⑥行代码是通过精灵帧对象创建。第⑤和⑥行使用精灵缓存方式主要应用于精灵动画时候,相关的知识我们将在精灵动画部分介绍。

    精灵缓存不再使用后忘记清空或移除相关精灵帧,否则如果有相同名称的精灵帧时候,就会出现一些奇怪的现象。清空或移除精灵帧的缓存函数如下:

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. pvoid removeSpriteFrameByName(conststd::string & name)。指定具体的精灵帧名移除。  
    2. pvoid removeSpriteFrames()。指定清空精灵缓存。  
    3. pvoidremoveSpriteFramesFromFile(const std::string & plist)。指定具体的坐标文件移除精灵帧。  
    4. pvoid removeUnusedSpriteFrames()。移除没有使用的精灵帧。  

    如果为了防止该场景中的精灵缓存对下一个场景产生影响,我们可以在当前场景所在层的onExit函数中调用这些函数,相关代码如下:

     

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. void HelloWorld::onExit()  
    2. {  
    3.     Layer::onExit();  
    4.     SpriteFrameCache::getInstance()->removeSpriteFrames();  
    5. }  

     

    onExit()函数是层退出时候回调的函数,与init函数类似都属于层的生命周期中的函数。我们要在h文件中定义,在cpp文件中声明。HelloWorld.h文件的相关代码如下:

     

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
     
      1. #ifndef __HELLOWORLD_SCENE_H__  
      2. #define __HELLOWORLD_SCENE_H__  
      3.    
      4. #include "cocos2d.h"  
      5.    
      6. class HelloWorld : public cocos2d::Layer  
      7. {  
      8. public:  
      9.    … …  
      10.     virtualbool init();   
      11.         //退出Layer回调函数  
      12.         virtualvoid onExit();      
      13.    … …  
      14.    CREATE_FUNC(HelloWorld);  
      15. };  
      16.    
      17. #endif // __HELLOWORLD_SCENE_H__  
      18. 当然精灵缓存清除工作也可以放到下一个场景创建时候,也就是下一个场景所在层的init函数中实现,相关代码如下:  
      19. bool HelloWorld::init()  
      20. {  
      21.    … …     
      22.    SpriteFrameCache::getInstance()->removeSpriteFrames();  
      23.    SpriteFrameCache::getInstance()->addSpriteFramesWithFile("SpirteSheet.plist");  
      24.    … …     
  • 相关阅读:
    有道翻译js解密(1)
    Python面试题之Python正则表达式re模块
    go语言从例子开始之Example4.常量
    go语言从例子开始之Example3.变量
    go语言从例子开始之Example2.类型
    go语言从例子开始之Example1.helloworld
    python模块打补丁
    gevent协程之猴子补丁带来的坑
    charles抓包小程序
    httptesting HTTP(s)接口自动化测试框架
  • 原文地址:https://www.cnblogs.com/iOS-Blog/p/3740922.html
Copyright © 2011-2022 走看看