2

私は、Entity オブジェクト クラスを使用する Android ゲームを作成しています。これは、さまざまなタイプ (敵、弾丸など) に拡張されます。Entity 型のプールを作成し、取得した Entity オブジェクトを実行時に必要なもの (弾丸型など) に変換する方法はありますか? コンストラクターへの引数としてエンティティを渡すと、プールの目的が正しく無効になりますか? 以下に例を示します。

public class EntityPool extends Pool<Entity> { 


public EntityPool (int initialCapacity, int max) {
    super(initialCapacity, max);
}

protected PooledEntity newObject () {
    return new PooledEntity();
}

public Entity obtain (int objectType) {
    Entity ent = super.obtain();
    if (objectType==SOME_OBJECT_TYPE)
                //Do something to make ent into that object type
    return ent;
}

public class PooledEntity extends Entity {
    PooledEntity () {
        super(null, 0, 0);
    }

    public void free () {
        EntityPool.this.free(this);
    }
}

}

4

2 に答える 2

1

通常、オブジェクト プールの目的は、システムの割り当てと割り当て解除のオーバーヘッドを回避することであり、割り当てたいエンティティの種類ごとに「最悪の場合」の制限を知っておく必要があります。したがって、エンティティの有効期間と使用方法がかなり異なると仮定すると、エンティティごとに個別のプールが必要になるでしょう。(@zaskeの回答のように、プールを確実に改善できます。)

一方、本当に単一のEntityプールが必要で、実行時にそれらのエンティティをカスタマイズしたい場合は、Entity サブクラスの使用から次のようなものに変更できます。

class Entity {
   EntityCustomizer custom;
   ...
}

Entity次に、プールから を取得するときに、Bulletまたはその他のShipカスタマイザ オブジェクトを渡します。

public Entity obtain (int objectType) {
  Entity ent = super.obtain();
  if (objectType==SOME_OBJECT_TYPE)
    ent.custom = EntityCustomizer.SOME_OBJECT_TYPE_IMPL;
  return ent;
}

(これはよく知られたパターンであり、パーツを識別するために適切な言語を使用する必要があると確信しています ...)

とはいえ、私の回避策はかなりハックなので、Entity タイプごとに個別のプールを使用するのがよいと思います (実行時の柔軟性のために、コンパイル時のタイプ チェックの束を取引しています)。

于 2012-11-08T19:03:35.477 に答える
0

現在のコードでは、エンティティまたはエンティティのサブクラスである任意のオブジェクトをプールに格納できます。その結果、instanceof具体的なオブジェクトの型を取得するには、またはダウンキャストのみを使用できます。

タイプごとに異なるプールが必要な場合は、プールの宣言を次のように変更することを検討できます。

public class EntityPool<T> extends Pool<T extends Entity>

次に、たとえば次のようにします。

EntityPool<Bullet> bulletsPool = new EntityPool<Bullet>(); //only objects of Bullet of sub classes can be added
于 2012-11-08T18:11:18.450 に答える