5、cocos2d-x纹理管理

我们在创建精灵时,cocos2d首先会根据文件名在TextureCache里面找有没有这个纹理,如果有,就直接使用,如果没有,就会加载这块纹理,然后保存在TextureCache里面,而使用createWithSpriteFrameName创建精灵时不会去加载纹理,如果找不到,就会返回空指针。

在TextureCache这个单例有个方法removeUnusedTextures()用来释放未使用的纹理。所以我们一般在Scene的OnExit()里面调用这个函数,来移除未使用纹理。

为什么不在按钮点下的时候就移除纹理,而在OnExit()里面移除呢?这和MainRoop有关,我们不知道触摸事件是在每一帧开始还是结尾处理的。如果在每一帧开始就处理了,这会造成释放未使用的纹理,而在update里面刚好使用了被释放的纹理,并且是使用createWithSpriteFrameName创建的精灵,就会返回空指针,造成异常。而Scene的OnExit在这一帧的所有update执行完后才调用,而且这个场景中和节点绑定的update也会全部被移除,这样就不会出现上述情况了,安全性就大大提高了。

我们再来说说纹理管理,在OnExit()中释放纹理在小项目里面影响不大,但是在大一点的项目里面,我们每次切换场景都移除未使用的纹理就会造成进入下一个页面的时候卡顿一下。这个时候,就需要使用过度场景。过度场景过多会影响玩家的游戏体验。

这里提供一种优化方案来处理这个问题。我们每次在进入场景的时候,只加载必须使用的纹理(如背景图,人物),异步加载其他非必须纹理(如设置界面,这样就可以避免打开子界面的时候卡顿),这样就可以很快进入游戏场景,从而避免使用过度场景。同时异步队列里面加载下一个场景的必须资源,这样,进入下一个场景时就不会去加载资源,只会异步加载其他非必须资源,从而使场景切换变得流畅。

这个方案几个缺点。
1、每个界面使用createWithSpriteFrameName都要去检测这个界面的纹理有没有加载,如果没有加载,立刻同步加载。
2、这里需要注意加载完后占用内存的大小,如果过大,就需要舍弃异步加载部分资源、或者只加载非必须纹理、或者只加载下个场景非必须纹理(如果玩家点开其他子界面过多还是会造成占用内存过高)。同时注意移除下一个不可能进入的场景的纹理。比如,a场景进入b场景,b场景进入c场景,c场景不能直接进入a场景,需要进入b场景才能回到a场景。在进入c场景后就可以把a场景的必须纹理移除掉了。
3、每个场景使用的纹理必须明确。

这里有一个使用模板: https://pan.baidu.com/s/1c2o5lN6

你可能感兴趣的:(5、cocos2d-x纹理管理)