Particles not deleting at the same time

Hello, I am working on a fireworks project. It seems when I increase the amount of particles to spawn in setup they delete at different times. I have them all updating at the same time so I don’t understand why they are not deleting at the same time.

let gravity;
let airRes;
let particleList = [];
let particle1;
let canvasWidth = 1000;
let canvasHeight = 1000;
let trailNumber = 20

function setup(){
	createCanvas(canvasWidth, canvasHeight);
	background(45);
	gravity = createVector(0, .02);
	airRes = 0.01;
	angleMode(DEGREES);
	for (let i = 0 ; i <= 360 ; i = i + 18){
			new Particle(400, 400, 3*cos(i), 3*sin(i));
		}
}

class Particle {
	constructor(_x,_y,_xVel,_yVel){
		this.position = createVector(_x, _y);
		this.velocity = createVector(_xVel,_yVel);
		this.radius = 1;
		this.duration = 35;
		this.pastPositionArray = [];
		for (let i = 0; i <= trailNumber; i++){
			this.pastPositionArray.push(this.position.copy());
		}
		particleList.push(this);
	}
	update(){
		let negUnitVector = this.velocity.copy().normalize();
		let airResVector = p5.Vector.mult(negUnitVector,airRes); 
		//add crap about airres magnitude
		this.velocity = p5.Vector.sub(this.velocity, airResVector);

		this.velocity = p5.Vector.add(this.velocity, gravity);

		for (let i = trailNumber; i >= 1 ; i --){
			let pastPosition = this.pastPositionArray[i-1].copy();
			this.pastPositionArray[i] = pastPosition;
		}
		this.pastPositionArray[0] = this.position.copy();
		
		this.position = p5.Vector.add(this.position, this.velocity);
		if (this.position.x >= canvasWidth || this.position.x <= 0 || this.position.y >= canvasHeight || this.position.y <= 0 ) {
			this.delete();
		}
		this.duration--;
		if(this.duration == 0){
			this.delete();
		}
	}
	draw(){
		let lineColor = color(43,203,100)
		let color1 = trailNumber;
		for (let i= 0; i <= trailNumber -1; i++){
			lineColor.setAlpha((color1-1)/trailNumber*255)
			let strokeColor = stroke(lineColor);
			line(this.pastPositionArray[i].x, this.pastPositionArray[i].y, this.pastPositionArray[i+1].x, this.pastPositionArray[i+1].y)
			color1--;
		}
	}
	delete(){
		particleList.splice(particleList.indexOf(this), 1);
	}
}


function draw(){
	background(45);
	//fill('red');
	strokeWeight(1.5);

	if (mouseIsPressed){
		for (let i = 0 ; i < 360 ; i = i + 6){
			new Particle(mouseX, mouseY, 3*cos(i), 3*sin(i));
		}
	}
	
	for ( let i of particleList){
		i.update();
	}
	for (let i of particleList){
		i.draw();
	}
}

1 Like

One option would be to change your delete function to this:

delete(){
		particleList = [];
	}

But honestly I think it looks better for them to be deleted at different times. Maybe run with the idea.

Just a guess (untested) – if you are iterating through a list forwards and having things remove themselves, then everything’s index is changing. That’s not a safe way to delete.

Like, if I’m ahead of you in line (#0, #1), and I delete myself (“please delete #0”) and then you delete yourself (“please delete #1”)… you aren’t number 1 anymore, you are now the new number 0. Oops.

To loop over a list and optionally delete, loop over it backwards by index.

let i = particleList.length
while (i--){
    particleList[i].update();
}

For related discussion, see:

Here’s a p5js sketch w/ a backwards loop inside its mousePressed() callback: :loop:
p5js.ProcessingTogether.com/sp/pad/export/ro.CaQVvhrEKxAeXd

function mousePressed() {
  for (let i = balls.length; i--; )
    if (balls[i].isMouseWithinCircle()) {
      const tail = balls.pop();
      if (i !== balls.length)  balls[i] = tail;
      redraw();
      break;
    }
  return false;
}