I am currently writing a game for android where there are enemies that fly across the screen and then disappear, to be replaced by other enemies. Now, this happens very fast, and my code currently performs a lot of memory allocation and deallocation to create and delete these enemy objects, so I'm trying to find a way to optimize this. I got this Pool class implementation from a book on android game dev:
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);
}
}
Now, the way to use this class is as follows:
PoolObjectFactory<Enemy> factory = new PoolObjectFactory<Enemy>() {
public Enemy createObject() {
return new Enemy();
}
};
Pool<Enemy> enemyPool = new Pool<Enemy>(factory, 50);
The obvious problem with this method is that you can't input any parameters to the createObject() method, thus forcing you to use classes that take no arguments in their constructor. This will force me to rewrite a lot of code since the Enemy class I'm using takes several different parameters. I can think of a couple of workarounds, like this one:
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);
But it's error-prone and annoying to update. I could also initialize the Enemy object in the createObject() method with bogus values and then set them manually later, or I could create a Pool class for every single object but I would really prefer not doing that.
Any suggestions on how to improve this code? How do you fellow java game developers deal with pooling objects to avoid garbage collection? Thanks very much.
1) You should override the createObject function in your PoolObjectFactory.
2) You will need a initialize() function that actually sets the parameters for each EnemyObject. Just have the constructor for the EnemyObject call the initialize function. Then, when you get the object out of the pool, you should just call initialize with your parameters and it should work perfectly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With