Cocos2d-x游戏中预加载资源和清理缓存的loading场景

前言

游戏中会有一些界面作为进入游戏时或切换场景时的过渡场景,其主要目的是为了预加载资源和清理缓存,使游戏运行的更流畅。

预加载资源

Cocos引擎主要有三种缓存类:

纹理缓存:TextureCache

精灵帧缓存:SpriteFrameCache

动画缓存:AnimationCache

缓存的目的就是:先将所需资源(如纹理图片)加载到内存中,之后再次使用该资源的时候,就可以直接从内存中取出,而不需要重新加载。从而减少了CPU和GPU的内存占用。
在制作游戏过程中,当游戏中有个界面用到的图片非常多,第一次点进这界面时速度非常慢(因为要加载绘制很多图片)出现卡顿,而第二次进入该界面时会流畅很多没有了卡顿,其实是在创建这些纹理精灵后将它们都加入到了缓存中去了。我们可以使用TextureCache提前异步加载纹理,等加载结束,进入到这个界面再使用这些图片速度就会非常快。同理,可以使用SpriteFrameCache预加载多张碎图合并出来的纹理图片,相应的plist文件对应一张包含多个精灵的大图,plist文件可以使用TexturePacker制作。同理将创建好的动画Animation直接放在动画缓存AnimationCache中,当需要执行动画动作时,就直接从动画缓存中拿出来,去创建初始化Animation会非常方便。

1.预加载纹理图片

// addImage 加载纹理图片
Texture2D *texture = Director::getInstance()->getTextureCache()->addImage(filename);
// getTextureForKey 获取纹理图片
Texture2D *texture = Director::getInstance()->getTextureCache()->getTextureForKey(textureKeyName);
TextureCache类还支持异步加载资源的功能,利用 addImageAsync 方法。你可以很方面地给addImageAsync方法添加一个回调方法,这样,当纹理异步加载结束的时候,可以得到通知。

2.预加精灵帧

通过 addSpriteFramesWithFile 加载 plist文件,将plist文件中的多张小图加载到精灵帧缓存中。
// 参数2 可不写
SpriteFrameCache *frameCache = SpriteFrameCache::getInstance();
frameCache->addSpriteFramesWithFile(“boy.plist”, “boy.png”);
//从SpriteFrameCache缓存中找到boy1.png这张图片.
auto frame_sp = Sprite::createWithSpriteFrameName(“boy1.png”);
this->addChild(frame_sp, 2);

3.预加精灵动画

//动画命名为 Explosion,加入到动画缓存中
Animation* animation = Animation::createWithSpriteFrames(arr, 0.04);
AnimationCache::getInstance()->addAnimation(animation, “Explosion”);
//直接从动画缓存中取出 “Explosion” 动画
Animation* animation = AnimationCache::getInstance()->getAnimation(“Explosion”);

3.预加载音乐音效

可以使用preloadBackgroundMusic预加载背景音乐,使用preloadEffect预加载音效。
将需要预加载的图片动画声音都加到一个列表里,增加一个进度条,每加载完成后便更新进度直到全部加载完成时进度条到100。

清理缓存

缓存如果不清理,切换场景越多游戏总内存会越来越大。因为引擎内部所有的纹理加载都是通过这个缓存进行的,换句话说,载入的每一张图片都被缓存了,所以我们需要知道什么时候清理缓存。
缓存的资源有一个引用计数,如果这个引用计数为1的时候就表明当前可能不需要使用这个纹理,可以被清除。
引擎会在设备出现内存警告时自动清理缓存,但是这显然在很多情况下已经为时已晚了。因而可以适当的清理一下没有被使用的资源,从而释放一些资源内存防止app出现闪退的现象。一般情况下,我们应该在切换场景时清理缓存中的无用纹理,因为不同场景间使用的纹理不同的。如果确实存在着共享的纹理,将其加入一个标记数组来保持其引用计数,以避免被清理。也可以在游戏切换账号切换区服时清理一下缓存。
值得注意的是清理的顺序。
首先清理,动画缓存AnimationCache,
然后清理,精灵帧缓存SpriteFrameCache,
最后清理,纹理缓存TextureCache。
按照引用层级由高到低,以保证释放引用有效。

loading场景

使用一个loading场景,同时显示一个动画来表明加载的进度。这样可以在进入下一个场景之前,让前面一个场景销毁,同时释放它所占用的内存资源。也可以在loading场景预加载下一个场景的资源。
因为CCTextureCache类支持异步加载资源的功能,利用addImageAsync方法可以很方便地给addImageAsync方法添加一个回调方法,这样,当纹理异步加载结束的时候,可以得到通知。
这一点非常重要:你必须等待一个资源加载完毕。否则的话,由于“间歇性内存飙高”,可能会引发下列问题:

  1. 程序崩溃
  2. 纹理被加载两次!因为异步加载并不能保证加载顺序。

这样做最大的好处在于,你加载资源的同时,loading场景还可以播放动画,可以添加精灵并运行一些action,这一切可以处理得很平滑。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值