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

  • 相关阅读:
    IOS Charles(代理服务器软件,可以用来拦截网络请求)
    Javascript中addEventListener和attachEvent的区别
    MVC中实现Area几种方法
    Entity Framework Code First 中使用 Fluent API 笔记。
    自定义JsonResult解决 序列化类型 System.Data.Entity.DynamicProxies 的对象时检测到循环引用
    序列化类型 System.Data.Entity.DynamicProxies 的对象时检测到循环引用
    An entity object cannot be referenced by multiple instances of IEntityChangeTracker 的解决方案
    Code First :使用Entity. Framework编程(8) ----转发 收藏
    Code First :使用Entity. Framework编程(6) ----转发 收藏
    Code First :使用Entity. Framework编程(5) ----转发 收藏
  • 原文地址:https://www.cnblogs.com/hainange/p/6153548.html
Copyright © 2011-2022 走看看