在前面的章节中,我们所涉及到的图片Sprite加载方式都是采用如下方式创建的
auto sp = Sprite::create("sprite.png");
sp->setPosition(Vec2::ZERO);
this->addchild(sp);
那么还有其他的加载方式没有?
其实cocos2dx给我们提供了很多种的图片加载方式,下面来一一介绍下各个加载方式
一、创建方式
1、通过文件创建
这个是最常用,最简单的一种方法,没错,就是上面的又被我复制了一遍
auto sp = Sprite::create("sprite.png");
sp->setPosition(Vec2::ZERO);
this->addchild(sp);
读者A:我等得花儿都谢了,就给我看这个?
读者B:我怀疑作者在凑字数,而且找到了证据。
2、通过图片区域创建
auto frame = SpriteFrame::create("sprite.png", Rect(0, 0, 300, 300));
auto sp= Sprite::createWithSpriteFrame(frame);
this->addChild(sp);
我么可以看到,
3、通过纹理创建
auto image = new Image();
image->initWithImageFile("sprite.png");
Texture2D *texture = new Texture2D();
texture->initWithImage(image);
auto sp = Sprite::createWithTexture(texture);
this->addChild(sp );
4、通过缓存创建
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("a.plist");
auto frame = SpriteFrameCache::getInstance()->getSpriteFrameByName("b.png");
auto sp = Sprite::createWithSpriteFrame(frame);
this->addChild(sp);
上述就是图片常见的创建方式,当然有重载方法,相关方法大家可以参考源码来学习。
二、图片内存优化
我们在游戏中常用的图片格式主要是png和jpeg格式,很多时候我们直接加载一张图片
如:
//加载png
auto sp = Sprite::create("sprite.png");
sp->setPosition(Vec2::ZERO);
this->addchild(sp);
//加载jpeg
auto bg = Sprite::create("bg.jpeg");
bg->setPosition(Vec2::ZERO);
this->addchild(bg);
对于少量的图片这样加载其实并不会出现什么问题,对于一整张背景这样的图片,jpeg格式放心大胆的用吧。
1、图片大小和内存大小
我们知道像PNG,JPEG格式的图片是经过压缩的,不能直接被GPU所识别,这些图片格式当被游戏读入后,还需要经过CPU解压成像素格式,再传送到GPU端进行使用,那么这些经处理后(解压)就是实际所在内存大小.
2、认识图片纹理格式
我们常用的图片纹理格式有(A:透明度,R:红色,G:绿色,B:蓝色)
ARGB_8888,ARGB_4444,RGB_565,ALPHA_8
所占内存大小就只由两个因素决定:
(1)图片的像素点个数(分辨率)
(2)单位像素占用的字节数(像素格式)。
纹理内存大小 = 纹理长度 * 纹理宽度 * 单位像素占用的字节数,
如:一张10241024的RGBA8888(占四个字节)的png图片占用的内存为 10241024*4 = 4M左右。
我们获得了解压后的纹理,占了4M的内存,然后将4M的内存上传到GPU处理。当加载大图时,这个过程会导致内存占用瞬间升高,可能会导致crash崩溃等问题。
注:cocos2dx会自动把它转换为RGBA8888 32位格式解析
那我们如何减少内存的占用呢?
cocos2dx给我们提供了修改默认格式的方法:
Texture2d::setDefaultAlphaPixelFormat(Texture2d::PixelFormat::RGBA4444);
这样就修改了默认纹理格式哦,那么占用的内存小了一半不是么。
3、合图工具,TexturePacker
TexturePacker支持多种碎图打大图的格式,碎图打大图时,使用NPOT纹理,NPOT是“non power of two”的缩写,译作“不是2的幂”。如果纹理图集(texture atlas)使用NPOT的纹理,它将有一个具大的优势:它允许TexturePacker更好地压缩纹理。因此,我们会更少地浪费纹理图集的空白区域。而且,这样的纹理在加载的时候,会少使用1%到49%左右的内存。
同时也可以使用pvr格式纹理。可以直接加载到显卡上(ios原生支持)。
通过上面的方式大家可以实现
(1)减小包的大小(修改图片像素格式)
(2)减小内存使用(设置纹理格式/采用合图等方式)
那么如果要一次性加载许多图片,不是还会出现内存瞬间变化么?cocos2dx给我们提供了一个解决方式,如上面创建图片第4点,通过缓存创建。下一节将会给大家介绍cocos2dx的相关缓存,大家记得关注哈~~。