2012-11-08 80 views
2

我創建了一個Android遊戲,它使用一個實體對象類,然後在許多不同類型(即敵人,子彈等)中進行擴展。有沒有辦法創建一個實體類型池,然後將獲得的實體對象轉換爲我在運行時需要的任何東西(比如子彈類型)?將實體作爲參數傳遞給構造函數將會破壞池的目的是否正確?下面是一個例子:在Libgdx中使用對象池

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); 
    } 
} 

}

回答

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 
+0

謝謝我與你的建議(不同類型的不同池)一起去。 – Fenster

+0

太棒了!我也想過也許有一個游泳池工廠,但你仍然會陷入低調的問題。 –

1

的點對象池一般是爲了避免系統分配和釋放開銷,並要求你知道你想要分配的每種類型的實體的數量的「最壞情況」限制。因此,假設您的實體在生命週期和使用情況上存在很大差異,那麼您可能希望爲每個實體分配不同的池。 (你可以像在@ zaske的回答中一樣改進游泳池。)

另一方面,如果你真的想要一個Entity池,並且你想在運行時自定義這些實體,你可以改變使用實體子類是這樣的:

class Entity { 
    EntityCustomizer custom; 
    ... 
} 

然後取一個Entity出池,當你傳遞一個BulletShip或任何定製對象:

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

(我敢肯定這是一個衆所周知的模式,我應該使用適當的語言來識別部件......)

所有說,我認爲爲每個實體類型單獨的池是要走的路,因爲我的解決方法是相當hacky(你正在爲一些運行時的靈活性進行一堆編譯時類型檢查)。