5

私は現在、Android用のゲームを書いています。このゲームでは、画面を横切って飛んで消えて、他の敵に置き換わる敵がいます。現在、これは非常に高速に行われ、私のコードは現在、これらの敵のオブジェクトを作成および削除するために多くのメモリ割り当てと割り当て解除を実行しているため、これを最適化する方法を見つけようとしています。このプールクラスの実装は、Androidゲーム開発者の本から入手しました。

public class Pool<T> {
    public interface PoolObjectFactory<T> {
        public T createObject();
    }
    private final List<T>               freeObjects;
    private final PoolObjectFactory<T>  factory;
    private int                         maxObjects;

    public Pool(PoolObjectFactory<T> factory, int maxObjects) {
        this.maxObjects = maxObjects;
        this.factory = factory;
        freeObjects = new ArrayList<T>(maxObjects);
    }

    public T newObject() {
        T object = null;
        if (freeObjects.isEmpty()) {
            object = factory.createObject();
        } else {
            object = freeObjects.remove(freeObjects.size() - 1);
        }
        return object;
    }

    public void free(T object) {
        if (freeObjects.size() < maxObjects) freeObjects.add(object);
    }
}

現在、このクラスの使用方法は次のとおりです。

PoolObjectFactory<Enemy> factory = new  PoolObjectFactory<Enemy>() { 
    public Enemy createObject() { 
        return  new  Enemy(); 
    } 
}; 
Pool<Enemy> enemyPool = new  Pool<Enemy>(factory, 50); 

このメソッドの明らかな問題は、createObject()メソッドにパラメーターを入力できないため、コンストラクターで引数をとらないクラスを使用する必要があることです。私が使用しているEnemyクラスはいくつかの異なるパラメーターを使用するため、これにより多くのコードを書き直す必要があります。次のようないくつかの回避策を考えることができます。

PoolObjectFactory<Enemy> factory = new  PoolObjectFactory<Enemy>() { 
    public Enemy createObject(Object... args) { 
        return  new  Enemy((Float)args[0], (Float)args[1]); 
    } 
}; 
Pool<Enemy> enemyPool = new  Pool<Enemy>(factory, 50); 

ただし、エラーが発生しやすく、更新するのが面倒です。また、createObject()メソッドでEnemyオブジェクトを偽の値で初期化し、後で手動で設定することもできます。または、すべてのオブジェクトに対してPoolクラスを作成することもできますが、実際にはそうしないほうがよいでしょう。

このコードを改善する方法について何か提案はありますか?仲間のJavaゲーム開発者は、ガベージコレクションを回避するためにオブジェクトのプールをどのように処理しますか?どうもありがとう。

4

1 に答える 1

1

1)PoolObjectFactoryのcreateObject関数をオーバーライドする必要があります。

2)各EnemyObjectのパラメーターを実際に設定するinitialize()関数が必要になります。EnemyObjectのコンストラクターに初期化関数を呼び出させるだけです。次に、オブジェクトをプールから取得するときに、パラメーターを使用してinitializeを呼び出すだけで、完全に機能するはずです。

于 2012-07-08T20:42:08.467 に答える