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.    … …     
  • 相关阅读:
    IO 单个文件的多线程拷贝
    day30 进程 同步 异步 阻塞 非阻塞 并发 并行 创建进程 守护进程 僵尸进程与孤儿进程 互斥锁
    day31 进程间通讯,线程
    d29天 上传电影练习 UDP使用 ScketServer模块
    d28 scoket套接字 struct模块
    d27网络编程
    d24 反射,元类
    d23 多态,oop中常用的内置函数 类中常用内置函数
    d22 封装 property装饰器 接口 抽象类 鸭子类型
    d21天 继承
  • 原文地址:https://www.cnblogs.com/iOS-Blog/p/3740922.html
Copyright © 2011-2022 走看看