cocos2d-x基础(三)CCSpriteFrameCache,CCSpriteFrame

TexturePacker使用方法:

内存问题, OpenGL ES 纹理的宽和高都要是2次幂数, 以刚才的例子来说, 假如 start.png 本身是 480x320, 但在载入内存後, 它其实会被变成一张 512x512 的纹理, 而start.png 则由 101x131 变成 128x256, 默认情况下面,当你在cocos2d里面加载一张图片的时候,对于每一个像素点使用4个byte来表示--1个byte(8位)代表red,另外3个byte分别代表green、blue和alpha透明通道。这个就简称RGBA8888。 因此,如果你使用默认的像素格式来加载图片的话,你可以通过下面的公式来计算出将要消耗多少内存来加载: 图像宽度(width)×图像高度(height)×每一个像素的位数(bytes per pixel) = 内存大小 此时,如果你有一张512×512的图片,那么当你使用默认的像素格式去加载它的话,那么将耗费512×512×4=1MB(好多啊!)
再看看关於渲染速度方面, OpenGL ES 上来说我们应该尽量减少渲染时切换纹理和 glDrawArray 的呼叫, 刚才的例子每画一个图像都会切换一次纹理并呼叫一次 glDrawArray , 我们这里只画3样东西, 所以不会看到有什麽问题, 但如果我们要渲染几十个甚至几百个图像 , 速度上就会被拖慢. 很明显这并不是我们所想要的..
Publish : 导出资源文件(.plist和png)
Add Folder : 导入图片资源文件夹
Add Sprite : 添加图片
Data Format : 导出什么引擎数据,默认cocos2d,下拉列表中有很多,基本常用的引擎都支持了
Data File : 导出文件位置(后缀名.plist)
Texture Format : 导出的文理格式,默认png
Image format : 图片像素格式,默认RGBA8888...根据对图片质量的需求导出不同的格式
Texture File : 合并好的资源的导出地址
ContentProtection : 加密Texture资源.
做好后直接点击Publish就可以导出文件,然后把plist文件和png文件拷贝到工程目录resource目录下.

CCSpriteFameCache:

把精灵帧保存到缓存中

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

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

static CCSPriteFrameCache* sharedSpriteFrameCache(); //全局共享的缓存单例

void addSpriteFrameWithFile(const char *pszPlist); //通过plist配置文件添加一组精灵帧

void removeUnusedSpriteFrames(); //清理无用缓存

CCSpriteFameCache的addSpriteFrame(CCSpriteFrame *pobFrame, const char *pszFrameName)方法是将文件名为pszFrameName的图片替代CCSpriteFrame。

CCSpriteFameCache的addSpriteFramesWithFile(const char* plist, const char* textureFileName)是通过plist文件和图片文件,将图片文件存入缓存,如果plist文件和texture文件同名,则只需要plist一个参数。注意:图片在存入缓存中已经根据plist分成相应的片了。



CCSpriteFrame:

与CCTexture2D类似,通常使用CCTexture2D和一个矩形边框截得的图生成。

CCTextureCache:

首先是最底层也最有效的纹理缓存CCTextureCache,这里缓存的是加载到内存中的纹理资源,也就是图片资源。其原理是对加入缓存的纹理资源进行一次引用,使其引用计数加一,保持不被清除,其cocos2d-x的渲染机制是可以重复使用同一份纹理在不同的场合进行绘制,从而到达重复使用,降低内存和CPU运算资源的开销的目的。常用的是如下所示的3个接口:

static CCTextureCache* sharedTextureCache();  //返回纹理缓存的全局单例

CCTexture2D* addImage(const char* fileimage);  //添加一张纹理图片到缓存中

void removeUnusedTextures();  //清除不使用的纹理

在这3个接口中,CCTextureCache屏蔽了加载纹理的许多细节;addImage函数会返回一个纹理CCTexture2D的引用,可能是新加载到内存的,也可能是之前已经存在的;而removeUnusedTextures则会释放当前所有引用计数为1的纹理,即目前没有被使用的纹理。

实际上,我们很少需要调用addImage这个接口,因为引擎内部所有的纹理加载都是通过这个缓存进行的,换句话说,载入的每一张图片都被缓存了,所以我们更需要关心什么时候清理缓存。引擎会在设备出现内存警告时自动清理缓存,但是这显然在很多情况下已经为时已晚了。一般情况下,我们应该在切换场景时清理缓存中的无用纹理,因为不同场景间使用的纹理不同的。如果确实存在着共享的纹理,将其加入一个标记数组来保持其引用计数,以避免被清理。


CCTexture2D:

纹理的内部信息,相当于一张bmp或者png图片的内部编码。


CCTextureCache *pTextureCache=CCTextureCache::sharedTextureCache();
    CCTexture2D *pTexture=pTextureCache->addImage("Bear.png");         //将图片放入缓存中
        CCSprite *pBear=CCSprite::createWithTexture(pTexture);



CCAnimationCache:

最后一个是CCAnimationCache动画的缓存。通常情况下,对于一个精灵动画,每次创建时都需要加载精灵帧,按顺寻添加到数组,在创建对应动作类,这是一个非常烦琐的计算过程。对于使用频率高的动画,比如鱼的游动,将其加入缓存可以有效降低每次创建的巨大消耗。由于这个类的目的和缓存内容都非常简单直接,所以其接口也是最简单了的,如下所示:

static CCAnimationCache* sharedAniationCache(); //全局共享的单例

void addAnimation(CCAnimation *animation, const char *name); //添加一个动画到缓存

void removeAnimationByName(const char *name); //移除一个指定的动画

CCAnimation* animationByName(const char *name); //获得事先存入的动画

唯一不一样的是,这次动画缓存需要我们手动维护全部动画信息。也因为加载帧动画完全是代码操作的,目前还没有配置文件指导,所以不能像另外两个缓存那样透明化。实际上,如果考虑到两个场景间使用的动画基本不会重复,可以直接清理整个动画缓存。

所以,在场景切换时我们应该加入如下的清理缓存操作:

void releaseCaches()

{

CCAnimationCache::purgeSharedAnimationCache();

CCSpriteFrameCache::sharedSpriteFrameCache()->removeUnusedSpriteFrames();

CCTextureCache::sharedTextureCache()->removeUnuserdTextures();
}

值得注意的是清理的顺序,应该先清理动画缓存,然后清理精灵帧,最后是纹理。按照引用层级由高到低,以保证保释引用有效。


  1.     CCAnimation *pAnimation=CCAnimation::createWithSpriteFrames(pArray,0.1f); 
  2. //将CCAnimation加到CCAnimationCache缓冲区中  
  3.     CCAnimationCache::sharedAnimationCache()->addAnimation(animation, "animation");  
  4.   
  5.     //将CCSpriteFrame加到CCSpriteFrameCache缓冲区中(如果用plist的话,这步可以省略)
  6.     CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFrame(m_frame1, "m_frame1");  
  7.   
  8. }  


  1.         /***第一种方法***/  
  2.         //先取得一个CCSpriteFrame,再通过取得的CCSpriteFrame创建一个CCSprite  
  3.         CCSpriteFrame *m_frame1 = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("m_frame1");  
  4.         CCSprite *m_sprite = CCSprite::createWithSpriteFrame(m_frame1);  
  5.         m_sprite->setPosition(ccp(100, 100));  
  6.         this->addChild(m_sprite);  
  7.   
  8.         /***第二种方法***/  
  9.         //通过名字取得CCSpriteFrame  
  10.         //CCSprite *m_sprite = CCSprite::createWithSpriteFrameName("m_frame1");  
  11.         //m_sprite->setPosition(ccp(200, 200));  
  12.         //this->addChild(m_sprite);  
  13.   
  14.         //通过名字取得CCAnimation  
  15.         CCAnimation *animation = CCAnimationCache::sharedAnimationCache()->animationByName("animation");  
  16.         CCAnimate *animate = CCAnimate::create(animation);  
  17.         m_sprite->runAction(CCRepeatForever::create(animate));  



CCAnimation:

CCAnimation *pAn=CCAnimationCache::sharedAnimationCache()->animationByName("animation");











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值