So I am making a game for Android and I have this singleton class called ParticleEmitter
that has a function for adding particles to a CopyOnWriteArrayList
. What gets added to the list is an abstract Particle
, it can either be a Laser
particle or a Meteor
particle. I also have a MainThread
class which acts as the game engine and it handles the drawing and updating of frames.
So this ParticleEmitter
class has an update()
function which handles the updating of all the particles in the list. But what it also does is tell when the particles are going to go offscreen, so they can be removed from the list. The update()
function, in the middle of iterating through all the particles, can also call the checkCollisions(Particle laser)
function to test a laser parameter, to see if it collides with any of the meteors, so they can both be removed from the list.
private Particle checkCollisions(Particle laser) {
Iterator<Particle> iter = particles.iterator();
Particle p;
while (iter.hasNext()) { // looping through all particles
p = iter.next();
if (p instanceof Meteor) { // if particle is a meteor, then see if it collides with the passed in laser
if (p.intersect(laser)) {
setChanged();
notifyObservers(GameController.Event.METEOR_DESTROYED);
return p;
}
}
}
return null;
}
public void update(int screenWidth, int screenHeight) {
// function called by game loop (many times a second)
List<Particle> particlesToRemove = new LinkedList<>();
int meteors = 0;
Iterator<Particle> iter = particles.iterator();
Particle p;
while (iter.hasNext()) {
p = iter.next();
p.update();
if (p instanceof Laser) {
Particle m = checkCollisions(p); // returns the collided with meteor if there was a collision, null if not
if (m != null) {
particlesToRemove.add(p);
particlesToRemove.add(m);
} else if (p.offscreen(screenWidth, screenHeight)) { // no collision with any meteors... still need to check if offscreen
particlesToRemove.add(p);
}
} else {
meteors++;
if (p.offscreen(screenWidth, screenHeight)) { // if meteor went off screen, it meant it hit the earth, so need to alert GameController
setChanged();
notifyObservers(GameController.Event.METEOR_HIT_EARTH);
particlesToRemove.add(p);
}
}
}
particles.removeAll(particlesToRemove);
if (meteors == 0) {
setChanged();
notifyObservers(GameController.Event.NO_METEORS_ON_SCREEN);
}
}
Is this code single-thread safe? I have already tested some and it seems to work good. I just want to make sure I'm not going to run into any exceptions (I've tried many solutions before this; just want to make sure I've stumbled upon the right one). And if you can think of a better way to implement what I'm doing here, I would appreciate that also :)
. Thanks.