cocos2d-x图片内存

来源:互联网 发布:淘宝钻展在哪里 编辑:程序博客网 时间:2024/05/17 05:04
一、IOS与图片内存
在IOS上,图片会被自动缩放到2的N次方大小。比如一张1024*1025的图片,占用的内存与一张1024*2048的图片是一致的。图片占用内存大小的计算的公式是;长*宽*4。这样一张512*512占用的内存就是512*512*4= 1M。其他尺寸以此类推。(ps:IOS上支持的最大尺寸为2048*2048)。

二、cocos2d-x的图片缓存
cocos2d-x在构造一个精灵的时候会使用spriteWithFile或者spriteWithSpriteFrameName等,无论用哪种方式,cocos2d-x都会将这张图片加载到缓存中,如果是第一次加载这个图片,那就会先将这张图片加载到缓存,然后从缓存读取。如果缓存中已经存在,则直接从缓存中提取,免除了加载过程。
图片的缓存主要由以下两个类来处理:CCSpriteFrameCache,CCTextureCache
CCSpriteFrameCache加载的是一张拼接过的大图,每一个小图只是大图中的一个区域,这些区域信息都在plist文件中保存。用的时候只需要根据小图的名称就可以加载到这个区域。
CCTextureCache是普通的图片缓存,我们所有直接加载的图片都会默认放到这个缓存这那更,以提高调用效率。
因此,每次加载一张图片,或者通过plist加载一张拼接图时,都会将整张图片加载到内存中。如果不去释放,那就会一直占用着。

三、渲染内存
不要以为,计算内存时,只计算加载到缓存中的内存就可以了,以一张1024*1024的图片为例。
CCSprite *pSprite = CCSprite::spriteWithFile("a.png");
调用上边这行代码以后,可以在LEAKS工具中看到,增加了大约4M的内存,然后接着调用addChild(pSprite);
这时,内存又增加了4M,也就是,一张图片,如果需要渲染的话,那它所占用的内存将要*2。

再看看通过plist加载的图片,比如这张大图片为2048*2048。想要加载其中的一张32*32的小图片
CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFrameWithFile("b.plist");
此时内存增加16M
CCSprite *pSpriteFrame =CCSpritewithSpriteFrameName("b1,png");
b.png大小为32*32,想着也就是增加一点点内存,可实际情况是增加16M内存,也就是只要渲染了其中的一部分,那么整张图片都要一起被加载。
但是情况不是那么糟糕,这些已经渲染的图片,如果再次加载的话,内存是不会在继续升高的,比如又增加了100个b.plist的另一个区域,图片内存还是增加16+16=32M,而不会继续上升。

四、缓存释放
如果游戏有很多场景,在切换场景的时候可以把前一个场景的内存全部释放,防止总内存过高。
CCTextureCache::sharedTextureCache()->removeAllTextures(); //释放到目前为止所有加载的图片
CCTextureCache::sharedTextureCache()->removeUnusedTextures();//将引用计数器为1的图片释放掉CCTextureCache::sharedTextureCache()->removeTexture();//单独释放某个图片
CCSpriteFrameCache与CCTextureCache释放的方法差不多。

值得注意的是释放的时机,一般在切换场景的时候释放资源,如果从A场景切换到B场景,调用的函数顺序为B::init()---->a::exit()-------->B::onEnter()可如果使用了切换效果,比如CTransitionJumpZoom::transitionWithDuration这样的函数,则函数的调用顺序变为B::init()---->B::onEnter()------->A::exit()而且第二种方式会有一瞬间将两个场景的资源叠加在一起,若果不采取过度,很可能会因为内存吃紧而崩溃。

有时候强制释放全部资源时,会使某个正在执行的动画失去引用而弹出异常,可以调用CCActionManager::sharedManager()->removeAllActions()来解决。

五、内存的优化
优化的心得就是尽量去拼接图片,使图片变长尽可能的保持2的N次方并且装的很满。但要注意,有逻辑关系的图片尽量打包在一张大图里,另外一点就是打包的时候要考虑到层的分布。因为为了渲染效率可能会用到CCSpriteBatchNode;同一个BatchNode里的图片都是位于一个层级的,因此必须根据各个图片的层级关系,打包到不同的plist里。有时内存和效率不可以兼得,只能尽量平衡了。
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 四个月宝宝没抱住摔了头部怎么办 老公老是跟年轻的小姑娘聊天怎么办 老婆出轨老公想离婚又舍不得怎么办 孕妇打完无痛分娩针就想睡觉怎么办 熟食店开空调菜品吹的很干怎么办 不锈钢锅在液化气烧了发黄怎么办 在小镇门面卤菜店不好卖怎么办? 被辣椒辣到嘴唇了该怎么办 沁园净水机不制水指示灯不亮怎么办 太辣了辣得胃疼怎么办 出现连接问题或mmi码无效怎么办 存折丢了怎么办卡号也不记得了 车内皮子被烂苹果腐蚀有印怎么办 锅被腐蚀后变黑色应该怎么办 后厨炉灶里的炉芯进水了怎么办 小儿九个月老是流黄鼻子该怎么办 肉炖的老了不烂怎么办 吃了凉东西现在一直打嗝应该怎么办 喝了很多水还是觉得口渴怎么办 刚买的猪肝没洗直接炒了怎么办 四个多月的宝宝吃了脏东西怎么办 狗吃了脏东西拉稀呕吐怎么办 五个月宝宝怕吃药导致奶不喝怎么办 蒸锅锅盖吸住了怎么办锅比锅盖要大 豇豆没熟孕妇吃了中毒怎么办 孩子积食拉不出粑粑憋的直哭怎么办 2岁宝宝总是半夜拉粑粑怎么办 金毛拉很臭的稀粑粑怎么办 点餐系统登录后没有菜单怎么办? 环亚在线微交易亏了钱怎么办 钢管舞报了教练班觉得学不会怎么办 微信上聊天被外国人给骗了该怎么办 微信冒充朋友骗走我钱怎么办 凉皮调料水鸡精味精放多了怎么办 吃了地屈孕酮后月经不干不净怎么办 藕片用热水炒后变色了怎么办? 外汇延期收款忘了报告了怎么办 怀孕不小心吃了马生菜怎么办 高压锅的皮圈很容易坏是怎么办 华为应用市场账号密码忘记了怎么办 业主对我们提出批评意见时怎么办