zoukankan      html  css  js  c++  java
  • 第九章 Libgdx内存管理

    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
    本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 
    支持: 新浪微博 腾讯微博
     

  • 相关阅读:
    ARM IIC接口
    ARM硬件问题转载
    自动排版
    书签
    ARM硬件问题转载
    ATPCS规则1
    开发硬件所需的知识
    今天很崩溃呀
    回顾一下
    ARM汇编条件码
  • 原文地址:https://www.cnblogs.com/hainange/p/6153548.html
Copyright © 2011-2022 走看看