This sketch demonstrates how to do this. It starts by creating 200 bullets with randon position and speed and stores them in an array list. When a bullet moves off the screen it is considered dead and is removed from the list. The number of remaining bullets is shown.
int n = 200;
void setup() {
size(640, 480);
textSize(48);
for (int i = 0; i < n; i++) {
bullets.add(new Bullet());
}
}
void draw() {
background(0);
updateBullets();
for (Bullet b : bullets) {
b.render();
}
fill(255, 200, 255, 160);
text("" + bullets.size(), 80, 80, 200, 120);
}
public void updateBullets() {
for (Bullet b : bullets) {
b.move();
}
// Remove dead bullets.
// Start at end of list to avoid concurrent modification exception
for (int i = bullets.size() - 1; i >= 0; i--) {
if (!bullets.get(i).isAlive()) { // in other words dead
bullets.remove(i);
}
}
}
public class Bullet {
float x;
float y;
float vx;
float vy;
boolean alive = true;
public Bullet() {
x = random(30, width -30);
y = random(30, height -30);
vx = random(-0.5, 0.5);
vy = random(-0.5, 0.5);
}
public void move() {
x += vx;
y += vy;
// Still alive (true) if still on screen
alive = (x >= 0) && (x < width) && (y >= 0) && (y < height);
}
public void render() {
noStroke();
fill(0, 255, 0);
pushMatrix();
translate(x, y);
ellipse(0, 0, 6, 6);
popMatrix();
}
public boolean isAlive() {
return alive;
}
}
``
If we look the code to remove dead bullets we are are doing two things
we are iterating over the list (visiting each bullet object in the list) with the for-loop
inside the for-loop we are removing bullets from the list, hence modifying the list
The problem is that under certain circumstance, doing both these things together i.e. concurrently causes an exception. For instance if you replace the code with this
// Remove dead bullets.
// Start at beginning of the list
for (int i = 0; i < bullets.size(); i--) {
if (!bullets.get(i).isAlive()) { // in other words dead
bullets.remove(i);
}
}
Semantically this code does the same as before but because of the way Java handles lists it will cause the exception.
If you want a better way to avoid the exception read on but it involves more advanced concepts.
Generally it is not recommended to write code based on knowledge of how Java works under the hood because the implementation details might be changed in the future and invalidate the code. In this particular instance the implementation of the Java ArrayList is never likely to change so it is quite safe to use the code in my previous reply.
For those interested the totally safe way to do this based on the Java API is
public void updateBullets() {
Iterator<Bullet> iter = bullets.iterator();
while (iter.hasNext()) {
Bullet b = iter.next();
b.move();
if (!b.isAlive()) {
iter.remove();
}
}
}
Would also need to add the import statement import java.util.*
The Vector class has the same API as the ArrayList so yes you can use it instead. I should point out that the Vector class is synchronized (thread safe) so might be slower than ArrayList. Since your code is single threaded you don’t need a synchronized class so I would stick with ArrayList unless there is a good reason not to.