libgdx thinking之资源生死有命

如果你对游戏资源管理这方面有经验,可以只看API了解Libgdx在这方面的策略和实现。

Disposable

AssetsManager

Poolable,Pool,Pools

/***************************************************************************************************************************************************************************************/

处理好内存释放是编程的任务之一,这对于占用内存不少而又要求运行流畅的游戏更是重要。虽然使用像java这样有良好垃圾回收机制的语言会省了很多功夫,但让垃圾回收器自动回收像图片音乐这样大的资源是不明智的,事实上它们由更底层的驱动来管理,释放这些资源还是需要开发者手动执行。而要做到细粒度地控制资源的生命周期在libgdx中并不是难事,开发者只需知道哪些资源需要释放(实现了Disposable接口),什么时候释放以及重载。如果这个工作有差错的话,你的游戏可能会出现内存泄漏或图片诡异地无法显示。

在libgdx中下面这些类实现了Disposable接口:

  • AssetManager
  • Bitmap
  • BitmapFont
  • BitmapFontCache
  • CameraGroupStrategy
  • DecalBatch
  • ETC1Data
  • FrameBuffer
  • Mesh
  • Model
  • ModelBatch
  • ParticleEffect
  • Pixmap
  • PixmapPacker
  • Shader
  • ShaderProgram
  • Shape
  • Skin
  • SpriteBatch
  • SpriteCache
  • Stage
  • Texture
  • TextureAtlas
  • TileAtlas
  • TileMapRenderer
  • com.badlogic.gdx.physics.box2d.World
  • all bullet classes
如果你创建了这些资源记得释放它们,你也不必强记这些类名,凡是有dispose接口的都需要在不再使用的时候释放,而释放它们的操作很简单:

treeTexture.dispose();
treeTexture=null
访问释放了的资源会出现无法捕捉的错误,所以在释放了之后需要对其引用赋空指针以便在开发调试时发现此类错误,当然这并不是必需的。还有libgdx中有个接口Gdx.app.getJavaHeap()和Gdx.app.getNativeHeap()可以获得虚拟机堆栈和底层堆栈的占用大小,打印它们帮助开发者在调试时了解内存使用情况。

下面讨论何时释放资源,假如你的游戏只是个用了几张图片一个背景音乐这样的小游戏,你大可以在游戏生命周期结束时释放它们,就是在重写ApplicationListener中的dispose方法中释放。如果再复杂点,你的游戏不只一个场景,有开始菜单场景和游戏场景,你使用了libgdx的Game-Screen来管理,而你也想要由开始菜单进入游戏后释放掉开始菜单用的资源,那你可以在重写Screen的hide方法中释放,hide方法会在该场景不再显示时调用。你也许发现了Screen还有个dispose接口但这个接口,但它并不参与场景的生命周期,它是框架作者开放出来的接口,如果开发者没有手动调用它,它将不会执行。至于你想在游戏结束时一次性释放所有资源还是分场景这样按需创建和释放,取决于你的游戏规模。

你有时会不会发现你的游戏在android上重启时图片诡异地无法显示,这是由于android应用的生命周期pause中openGL会自动销毁Texture这样的资源,而pause会在应用切入后台和退出前调用,你的游戏在切入后台后纹理会销毁但恢复时会自动重载(前提是你没做这样的设置Texture.setAssetManager(manager))但如果是退出后重启就不会自动重载纹理需要你再创建一遍,一般这不会有什么问题除非在资源的引用访问上没处理好就会出现诡异现象,例如你将资源声明为静态,这个问题你可以看看这篇博文慎用static

看到这里你已经对资源的释放和重载有些新的认识,但苛刻的你仍觉得要管理资源需要更简洁安全的方案,Libgdx的AssetsManager可以很好满足你的要求(但如果你的游戏使用的资源很少就不必使用它了)。它可以异步加载大部分类型的资源而不一直占用渲染主线程所有可以做一个加载界面;它采用引用计数,资源可以共享即使加载了多次但实际只占用一处内存;持有所有资源的引用;允许透明地实现文件缓存。对于它的学习你可以查看这篇译文AssetsManager资源管理器

对资源的良好管理并不局限于对创建释放的控制,重用池也是很有效的方法,对于子弹,怪物的重复生成更适合,libgdx的Action和particle就用使用到池。对于池的使用可以查看这篇来自宋大的转载对象池


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值