Android游戏开发群:290051794
Libgdx游戏开发框架交流群:261954621
游戏是使用资源较多的应用。图像和音效会占用大量的内存。此外,这些资源大部分不是通过java的垃圾回收器管理,而是由本地驱动管理。使用垃圾回收器对纹理等进行回收不是一个明智的做法。
我们需要合理的控制资源的生命周期。在Libgdx中有多个类实现这个功能。它们都实现Disposable接口指明在生命周期结束后要销毁的类的实例。错误的释放资源会导致内存泄露。
下面的类需要手工处理:
AssetManager
Bitmap
BitmapFont
BitmapFontCache
CameraGroupStrategy
DecalBatch
ETC1Data
FrameBuffer
Mesh
ParticleEffect
Pixmap
PixmapPacker
ShaderProgram
Shape
Skin
SpriteBatch
SpriteCache
Stage
Texture
TextureAtlas
TileAtlas
TileMapRenderer
com.badlogic.gdx.physics.box2d.World
当资源不再使用应尽快的进行释放,释放与它们有关的内存。访问一个已经释放的资源会导致未定义错误,所以要处理所有资源的引用。
当你想知道一个类是不是需要释放,检查它是否有dispose()方法。如果有,那么你正在使用本地资源。
对象池
对象池是重新使用闲置的或“死掉”的对象,而不是每次都创建新的对象。这通过一个对象池实现,当你需要一个对象时,从对象池中获得。如果对象池有可用的对象,则返回。如果对象池是空的,或者没有闲置的对象,会创建一个对象的一个新的实例并返回。当你不再需要一个对象,并释放它。就意味着它返回到对象池。通过这种方式,对象分配的内存重新被使用。
对于需要生成大量对象,比如子弹,障碍,怪物等等,的游戏来说,这对内存管理是重要的。
Libgdx对简单池提供了一些工具:
Poolable interface
Pool
Pools
实现Poolable接口意味着你需要在对象中实现reset()方法,它会自动的释放你的对象。
下面是一个简单的例子:
public class Bullet implements Poolable {
public Vector2 position;
public boolean alive;
/**
* Bullet 构造函数,初始化变量。.
*/
public Bullet() {
this.position = new Vector2();
this.alive = false;
}
/**
* 初始化Bullet当从对象池中获取Bullet是调用。
*/
public void init(float posX, float posY) {
position.set(posX, posY);
alive = true;
}
/**
*对象空闲的回调方法,自动被 Pool.free()调用。
*/
public void reset() {
position.set(0,0);
alive = false;
}
/**
* 更新
*/
public void update (float delta) {
// update bullet position
position.add(1*delta*60, 1*delta*60);
// if bullet is out of screen, set it to dead
if (isOutOfScreen()) alive = false;
}
}
在游戏中:
public class World() {
// array containing the active bullets.
private final Array<Bullet> activeBullets = new Array<Bullet>();
// bullet pool.
private final Pool<Bullet> bulletPool = new Pool<Bullet>() {
@Override
protected Bullet newObject() {
return new Bullet();
}
};
public void update(float delta) {
// if you want to spawn a new bullet:
Bullet item = bulletPool.obtain();
item.init(2, 2);
activeBullets.add(item);
// if you want to free dead bullets, returning them to the pool:
Bullet item;
int len = activeBullets.size;
for (int i = len; --i >= 0;) {
item = activeBullets.get(i);
if (item.alive == false) {
activeBullets.removeIndex(i);
bulletPool.free(item);
}
}
}
}
Pools类提供了动态创建任何对象池的静态方法。在上面的示例中,可以这样使用:
private final Pool<Bullet> bulletPool = Pools.get(Bullet.class);
作者:宋志辉
出处:http://blog.csdn.net/song19891121
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
支持: 新浪微博 腾讯微博