zoukankan      html  css  js  c++  java
  • 10、Libgdx的内存管理

    (官网:www.libgdx.cn

    游戏是非常耗资源的应用。图片和音效可能耗费大量的内存,另一方面来说,这些资源没有被Java垃圾回收,让一个垃圾处理来决定将显存中的5M的图片进行释放也不是一个明知的选择。

    我们希望尽可能的在生命周期内管理好我们的资源。在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

    • 所有的bullet类

    资源文件要在不使用是尽快的释放,访问释放的资源将会导致错误。要确保这样的事情不要发生。
    要判断一个特定的类是否需要释放,可以看一下它有没有disposed()方法,如果有,则需要释放。

    对象轮询

    对象轮询是重复利用未激活或者“死掉”的对象的基本原则,而不是每次都创建新的对象。可以通过创建一个对象池来完成,当你需要一个新的对象是,你可以从对象池中获取。如果池中有可用的对象,就返回,如果池是空的或者不包含可用的对象,将会创建一个新的对象的实例并返回。当你不需要一个对象时,需要进行释放,这就意味着将对象返回到池中。通过这种方式达到分配内存的重复利用。

    这在游戏的内存管理中至关重要。

    Libgdx提供了一系列的工具来实现简单的轮询。

    • Poolable接口

    • Pool

    • Pools
      继承Poolable接口意味着你需要在你的对象中有一个reset()方法。这个方法可以自动调用释放你的对象。

    以下是一个简单的示例:

     public class Bullet implements Poolable {
    public Vector2 position;
    public boolean alive;
    /**
     * 构造器,初始化.
     */
    public Bullet() {
        this.position = new Vector2();
        this.alive = false;
    }
    /**
     * 初始化,从对象池中获取
     */
    public void init(float posX, float posY) {
        position.set(posX,  posY);
        alive = true;
    }
    /**
     * 回调方法
     */
    @Override
    public void reset() {
        position.set(0,0);
        alive = false;
    }
    /**
     *更新
     */
    public void update (float delta) {
        // 更新位置
        position.add(1*delta*60, 1*delta*60);
        // 屏幕之外,设置为dead
        if (isOutOfScreen()) alive = false;
    }
    

    }

    在游戏的world类中:

    public class World {
    // Bullet类
    private final Array<Bullet> activeBullets = new Array<Bullet>();
    // bullet池
    private final Pool<Bullet> bulletPool = new Pool<Bullet>() {
    @Override
    protected Bullet newObject() {
        return new Bullet();
    }
    };
    
    public void update(float delta) {
        // 新的Bullet
        Bullet item = bulletPool.obtain();
        item.init(2, 2);
        activeBullets.add(item);
        //释放bullet
        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);
    

    怎样使用Pool

    一个Pool<>管理一个单独类型的对象。从一个特定的Pool实例中取出,然后释放之后返回到Pool中。对象可能会实现Poolable接口,这将会在对象返回到Pool中自动进行重置。对象将按需分配。

    你必须实现你自己的Pool<>子类,因为newObject方法是抽象的。

    www.libgdx.cn版权所有,如需转载,注明出处)

  • 相关阅读:
    Resource interpreted as Stylesheet but transferred with MIME type application/x-css
    scrapy 的settings.py中设置自定义属性
    scrapy下载图片到指定路径
    scrapy 自动下载图片
    Python处理json的错误 obj, end = self.scan_once(s, idx) ValueError: Expecting property name: line 2 column 17 (char 18)
    [ZJOI2012]数列 题解 [高精]
    [ZJOI2020]传统艺能 题解 [DP+矩阵+分类讨论]
    《终将成为你》简评
    GJGHFD的关键点 题解 [倍增+线段树+贪心]
    GJGHFD的排列 题解 [DP]
  • 原文地址:https://www.cnblogs.com/hainange/p/6153489.html
Copyright © 2011-2022 走看看