转自泰然网(Cocos2d-x 3.x官方文档):精灵帧缓存:http://www.tairan.com/archives/6378/   纹理缓存: http://www.tairan.com/archives/6432/

精灵帧缓存

简介

SpriteFrameCache 主要服务于多张碎图合并出来的纹理图片。这种纹理在一张大图中包含了多张小图,直接通过TextureCache引用会有诸多不便,因而衍生出来精灵框帧的处理方式,即把截取好的纹理信息保存在一个精灵框帧内,精灵通过切换不同的框帧来显示出不同的图案。

SpriteFrameCache

SpriteFrameCache的内部封装了一个Map _spriteFrames对象。key为帧的名称。SpriteFrameCache一般用来处理plist文件(这个文件指定了每个独立的精灵在这张“大图”里面的位置和大小),该文件对应一张包含多个精灵的大图,plist文件可以使用TexturePacker制作。

SpriteFrameCache的常用接口和TextureCache类似,不再赘述了,唯一需要注意的是添加精灵帧的配套文件一个plist文件和一张大的纹理图。下面列举了SpriteFrameCache常用的方法:

获取单例的SpriteFrameCache对象。sharedSpriteFrameCache方法在3.0中已经弃用:

SpriteFrameCache* cache = SpriteFrameCache::getInstance();

销毁SpriteFrameCache对象:

SpriteFrameCache::destroyInstance();

使用SpriteFrameCache获取指定的精灵帧,创建精灵对象:

SpriteFrameCache *frameCache = SpriteFrameCache::getInstance();
frameCache->addSpriteFramesWithFile("boy.plist","boy.png");//boy.png里集合了boy1.png,boy2.png这些小图
auto frame_sp = Sprite::createWithSpriteFrameName("boy1.png");//从SpriteFrameCache缓存中找到boy1.png这张图片.
this->addChild(frame_sp,2);

SpriteFrameCache vs. TextureCache

SpriteFrameCache精灵框帧缓存。顾名思义,这里缓存的是精灵帧SpriteFrame,它主要服务于多张碎图合并出来的纹理图片。这种纹理在一张大图中包含了多张小图,直接通过TextureCache引用会有诸多不便,因而衍生出来精灵框帧的处理方式,即把截取好的纹理信息保存在一个精灵框帧内,精灵通过切换不同的框帧来显示出不同的图案。
跟TextureCache功能一样,将SpriteFrame缓存起来,在下次使用的时候直接去取。不过跟TextureCache不同的是,如果内存池中不存在要查找的图片,它会提示找不到,而不会去本地加载图片。

  • TextureCache时最底层也是最有效的纹理缓存,缓存的是加载到内存中的纹理资源,也就是图片资源。
  • SpriteFrameCache精灵框帧缓存,缓存的时精灵帧。
  • SpriteFrameCache是基于TextureCache上的封装。缓存的是精灵帧,是纹理指定区域的矩形块。各精灵帧都在同一纹理中,通过切换不同的框帧来显示出不同的图案。

纹理缓存

在游戏中需要加载大量的纹理图片,这些操作都是很耗内存和资源的。

当游戏中有个界面用到的图片非常多,第一次点进这界面时速度非常慢(因为要加载绘制很多图片)出现卡顿,我们可以使用TextureCache提前异步加载纹理,等加载结束,进入到这个界面再使用这些图片速度就会非常快。

Texture2D: 纹理,即图片加载入内存后供CPU和GPU操作的贴图对象。
TextureCache(纹理缓存),用于加载和管理纹理。一旦纹理加载完成,下次使用时可使用它返回之前加载的纹理,从而减少对GPU和CPU内存的占用。

常用的方法

当你创建一个精灵,你一般会使用Sprite::create(pszFileName)。假如你去看Sprite::create(pszFileName)的实现方式,你将看到它将这个图片增加到纹理缓存中去了:

Sprite* Sprite::create(const std::string& filename)
{
Sprite *sprite = new Sprite();
if (sprite && sprite->initWithFile(filename))
{
sprite->autorelease();
return sprite;
}
_SAFE_DELETE(sprite);
return nullptr;
} bool Sprite::initWithFile(const std::string& filename)
{
ASSERT(filename.size()>0, "Invalid filename for sprite"); Texture2D *texture = Director::getInstance()->getTextureCache()->addImage(filename);
if (texture)
{
Rect rect = Rect::ZERO;
rect.size = texture->getContentSize();
return initWithTexture(texture, rect);
} // don't release here.
// when load texture failed, it's better to get a "transparent" sprite then a crashed program
// this->release();
return false;
}

上面代码显示在控制加载纹理。一旦这个纹理被加载了,在下一时刻就会返回之前加载的纹理引用,并且减少加载的时候瞬间增加的内存。

获取TextureCache

在3.0版本中,TextureCache不再作为单例模式使用。作为Director的成员变量,通过以下方式获取:

Director::getInstance()->getTextureCache();

获取纹理

如果文件名以前没有被加载时,它会创建一个新的Texture2D 对象,它会返回它。它将使用文件名作为key否则,它会返回一个引用先前加载的图像。
TextureCache屏蔽了加载纹理的许多细节;
addImage函数会返回一个纹理Texture2D的引用,如果纹理不存在,则新创建一个,否则返回之前已经存在的:

Texture2D *texture = Director::getInstance()->getTextureCache()->addImage(filename);

也可以通过getTextureForKey方法来获得这个key所对应的纹理缓存,如果这个Key对应的纹理不存在,那么就返回NULL:

Texture2D *texture = Director::getInstance()->getTextureCache()->getTextureForKey(textureKeyName);

异步加载纹理

TextureCache类还支持异步加载资源的功能,利用addImageAsync方法。你可以很方面地给addImageAsync方法添加一个回调方法,这样,当纹理异步加载结束的时候,可以得到通知。

你可以选择异步加载方式,这样你就可以为loading场景增加一个进度条。关键代码如下:

TextureCacheTest::TextureCacheTest()
: _numberOfSprites(20)
, _numberOfLoadedSprites(0)
{
auto size = Director::getInstance()->getWinSize(); _labelLoading = Label::createWithTTF("loading...", "fonts/arial.ttf", 15);
_labelPercent = Label::createWithTTF("%0", "fonts/arial.ttf", 15); _labelLoading->setPosition(Point(size.width / 2, size.height / 2 - 20));
_labelPercent->setPosition(Point(size.width / 2, size.height / 2 + 20)); this->addChild(_labelLoading);
this->addChild(_labelPercent); // load textrues
Director::getInstance()->getTextureCache()->addImageAsync("Images/HelloWorld.png", _CALLBACK_1(TextureCacheTest::loadingCallBack, this));
Director::getInstance()->getTextureCache()->addImageAsync("Images/grossini.png", _CALLBACK_1(TextureCacheTest::loadingCallBack, this));
Director::getInstance()->getTextureCache()->addImageAsync("Images/grossini_dance_01.png", _CALLBACK_1(TextureCacheTest::loadingCallBack, this));
.... } void TextureCacheTest::loadingCallBack(cocos2d::Texture2D *texture)
{
++_numberOfLoadedSprites;
char tmp[10];
sprintf(tmp,"%%%d", (int)(((float)_numberOfLoadedSprites / _numberOfSprites) * 100));
_labelPercent->setString(tmp); if (_numberOfLoadedSprites == _numberOfSprites)
{
this->removeChild(_labelLoading, true);
this->removeChild(_labelPercent, true);
addSprite();
}
}

清理缓存

removeUnusedTextures则会释放当前所有引用计数为1的纹理,即目前没有被使用的纹理。比如新场景创建好后,使用此方法释放没有使用的纹理非常方便:

Director::getInstance()->getTextureCache()->removeUnusedTextures();

当没有其它对象(比如sprite)持有纹理的引用的时候,纹理仍然会存在内存之间。基于这一点,我们可以立马从缓存中移除出去,这样,当纹理不存需要的时候,马上就会从内存中释放掉。如下代码所示:

Director::getInstance()->getTextureCache()->removeTextureForKey("Images/grossinis_sister2.png");

当收到"Memory Warning"时,可以调用removeAllTextures()方法。在短期内: 它还将释放一些资源,防止您的应用程序被杀害; 中期: 它将分配更多的资源;从长远来看:它会是相同的:

Director::getInstance()->getTextureCache()->removeAllTextures();

【Cocos2d-x 3.x】 精灵帧缓存和纹理缓存的更多相关文章

  1. cocos2d心得关于精灵帧缓存

    在cocos2d中,精灵帧缓存CCSpriteFrameCache是用来存储精灵帧的.它没有特别的属性,只存储了一些用来管理CCSpriteFrame的方法. 以一个例子来说明,一般在又纹理图集的程序 ...

  2. SpriteFrameCache 精灵帧缓存

    //获取精灵帧缓存的单例对象 auto  spriteFrameCache = SpriteFrameCache::getInstance(); //从plist文件添加多个精灵帧 spriteFra ...

  3. [一位菜鸟的COCOS-2D编程之路]精灵表单的制作以及简易动画的生成

    1.第一步:使用Zwoptex 制作精灵表单 2.制作的表单的名称为 cocos2Dpng,cocos2D.plist: 3.精灵的动画效果 主要分为五部分. // on "init&quo ...

  4. cocos2d-x中描述精灵帧图片的plist和json文件各个key的含义

    最近在研究cocos,互联网行业中,手游业最近的表现是非常的火,加上本身对游戏有浓厚兴趣,所以便染指了游戏引擎~ 这次的废话就这么简短吧,因为这次记录的东西本身就很少. 在cocos中,为精灵帧添加缓 ...

  5. SpriteBuilder中如何平均拉伸精灵帧动画的距离

    首先要在Timeline中选中所有的精灵帧,可以通过如下2种的任意一种办法达成: 1按下Shift键的同时鼠标单击它们 2鼠标在Timeline空白区拖拽直到拉出的矩形包围住所有精灵帧方块后放开鼠标. ...

  6. 关于精灵帧(Sprite Frame)的尺寸大小

    一个对象的精灵帧(Sprite Frame)有若干关于大小的尺寸. 比较容易混淆,这里记录下来区别: CCSpriteFrame *spriteFrame = self.spriteFrame; CG ...

  7. cocos基础教程(10)纹理缓存技术

    Cocos2d通过调用CCTextureCache或者CCSpriteFrameCache来缓存精灵的纹理. 当这个精灵调用CCTextureCache 或 CCSpriteFrameCache的方法 ...

  8. 纹理缓存(Texture Cache)

    纹理缓存是将纹理缓存起来方便之后的绘制工作.每一个缓存的图像的大小,颜色和区域范围都是可以被修改的.这些信息都是存储在内存中的,不用在每一次绘制的时候都发送给GPU. CCTextureCache C ...

  9. (21)纹理缓存(Texture Cache)

    简介 纹理缓存是将纹理缓存起来方便之后的绘制工作.每一个缓存的图像的大小,颜色和区域范围都是可以被修改的.这些信息都是存储在内存中的,不用在每一次绘制的时候都发送给GPU. CCTextureCach ...

随机推荐

  1. 面试复习(C++)之基数排序

    #include <iostream> using namespace std; int maxbit(int *a,int n) { ;//一位 ;//十进制 ;i<n;i++) ...

  2. 配置DelegatingFilterProxy使用Spring管理filter chain

    项目环境:JDK7 + Maven3.04 0. 项目使用springmvc作为controller层 1. 引入spring-security <dependency> <grou ...

  3. windows8.1下android开发环境搭建(Eclipse+Android sdk+ADT+Genymotion)

    一.基本jdk.eclipse环境 二.android sdk 1.下载安装:https://developer.android.com/sdk/installing/index.html?pkg=t ...

  4. Oracle中SQL查询表字段基本信息、主键、外键(转)

    select utc.column_name, utc.data_type, utc.data_length, utc.data_precision, utc.data_Scale, utc.null ...

  5. eap-md5

    eap-md5       文件路径 用途 示例 备注 #gedit /usr/local/etc/raddb/sites-available/default #gedit /usr/local/et ...

  6. JAVA编程讲座-吴老

    JAVA系列公开课第4讲:多态系列课程:从JAVA编程零基础讲起,同时结合工作中遇到的具体实例,语言清晰易懂,连续10周+深入讲解,打下编程基础,让我们一起打来自动化测试的大门时间:4月25日(周一) ...

  7. html canvas 弹球(模仿)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. [C++中级进阶]001_C++0x里的完美转发到底是神马?

    [C++中级进阶]001_C++0x里的完美转发到底是神马? 转载至:http://www.cnblogs.com/alephsoul-alephsoul/archive/2013/01/10/285 ...

  9. GZipStream 压缩和解压

    GZipSteam: GZip 数据格式,它使用无损压缩和解压缩文件的行业标准算法 类 GZipStream有两种模式:CompressionMode.Compress和CompressionMode ...

  10. knockout.js 简介

    Knockout是一个轻量级的UI类库,通过应用MVVM模式使JavaScript前端UI简单化. Knockout有如下4大重要概念: 声明式绑定 (Declarative Bindings):使用 ...