javananotime

Java - ArrayList Objects not deleted properly


I am working on a 2D platformer game for my, last, HS year project. The game is basically about a player walking back & forward, collecting points and reaching goals... The player can shoot bullets and when bullets hit a block, it is destroyed. Now, I wanted to add an explosion effect using so called "particle" objects. I have written the manager class for it and it seemed to have worked the first time but after shooting a few times, i noticed that the particles stopped getting deleted, they just continue and travel out of screen. The life-time limit is 500ns.

I have also noticed that if i shoot bullets as soon as the game starts, the effect finishes as it is supposed to. but after waiting for a few more seconds and then shooting bullets, the effect particles do not behave as they should.

Here is what it looks like when i shoot bullets as soon as i start the game (What it's supposed to look like):
enter image description here

and here is what it looks like, after waiting a few seconds before shooting the bullets. enter image description here

ParticleManager.java

public class ParticleManager {


    private ArrayList<Particle> particles;
    private ArrayList<Particle> removeParticles;

    public ParticleManager() {
        particles = new ArrayList<Particle>();
        removeParticles = new ArrayList<Particle>();
    }


    public int getListSize() {
        return particles.size();
    }

    /*
            Generate particles
     */
    public void genParticle(int x, int y, int amount) {
        for(int i = 0; i < amount; i++) {
            particles.add(new Particle("explosion" , x,y, i));
        }
    }

    public void update() {

         // Iterate trough particle objects
        // update them & check for lifeTime
        for(Particle p: particles) {

            // Updating particle object before 
            // checking for time lapse
            p.update();

            // Append outdated particles to removeParticles
            // if time limit has passed
            if(System.nanoTime() - p.timePassed >= Config.particleLife) {
                removeParticles.add(p);
            }
        }

        // finally, delete all "remove-marked" objects
        particles.removeAll(removeParticles);
    }

    public void render(Graphics2D g) {
        for(Particle p: particles) {
            p.render(g);
        }
    }

}

Particle.java

class Particle {

    private double px, py, x, y; 
    private int radius, angle;
    public long timePassed;
    String type;

    public Particle(String type, double x, double y, int angle) {
        this.x = x;
        this.y = y;
        this.radius = 0;
        this.angle = angle; 
        this.timePassed = 0;
        this.type = type; // explosion, tail

    }

    public void update() {
        px  =   x + radius * Math.cos(angle);
        py  =   y + radius * Math.sin(angle);
        radius += 2;

        this.timePassed = System.nanoTime();
    }

    public void render(Graphics2D g) {
        g.setColor(Color.WHITE);
        g.fillOval((int)px, (int)py, 5, 5); 
    }
}

I haven't figured out what I am doing wrong here, I've googled about some stuff and at one point i came across an answer mentioning that some references don't get deleted directly for some reason...

and my question is "How can I make these particles vanish after a certain amount of time has passed? - as shown in the first GIF"


Solution

  • I think the problem is that you are constantly overwriting timePassed.

    // Updating particle object before 
    // checking for time lapse
    p.update();
    
    // Append outdated particles to removeParticles
    // if time limit has passed
    if(System.nanoTime() - p.timePassed >= Config.particleLife) {
        removeParticles.add(p);
    }
    

    p.update() sets timePassed to now and then the if check checks if time passed is far from now (it will never be since it was just set).

    I think you do want to set timePassed in the constructor (maybe it would be better named timeCreated).

    Additionally, just a heads up, you never clear removeParticles so that list is going to grow forever until it causes the process to run out of memory.