patternjavascriptMinor
Processing.js particle system
Viewed 0 times
particleprocessingsystem
Problem
After about half an hour of fooling around with Processing.js/JavaScript, I got this fairly decent particle system set up:
Now, I think that this could definitely be improved, as the
// main particle constructor class
var Particle = function(position) {
this.velocity = new PVector(random(-0.1, 0.1), random(-0.1, 0.1));
this.acceleration = new PVector(random(-0.01, 0.01), random(-0.01, 0.01));
this.lifeTime = 300;
this.position = position.get();
};
// update the particle
Particle.prototype.update = function() {
this.velocity.add(this.acceleration);
this.position.add(this.velocity);
this.lifeTime--;
};
// render the particle
Particle.prototype.render = function() {
strokeWeight(2);
stroke(161, 153, 153, this.lifeTime);
fill(140, 135, 140, this.lifeTime);
ellipse(this.position.x, this.position.y, 15, 15);
};
// check the bounds of a particle
Particle.prototype.checkBounds = function() {
if(this.position.x >= 385) {
this.acceleration = new PVector(random(-0.02, -0.01), random(-0.01, 0.01));
}
if(this.position.x = 385) {
this.acceleration = new PVector(random(-0.01, 0.01), random(-0.02, -0.01));
}
if(this.position.y 0) {
return false;
} else {
return true;
}
};
// array containing particles
var particles = [];
// main draw loop
var draw = function() {
// draw the background and push a new particle
background(11, 100, 209);
particles.push(new Particle(new PVector(mouseX, mouseY)));
// iterate through particles and run their methods
for(var p = particles.length-1; p >= 0; p--) {
var particle = particles[p];
particle.checkBounds();
particle.update();
particle.render();
if(particle.particleDead()) {
particles.splice(p, 1);
}
}
};Now, I think that this could definitely be improved, as the
Particle.prototype.checkBounds method seems to not work all the time. Anyways, what can I improve here?Solution
Interesting question,
there are few things that could be improved:
-
Read up on the revealing module pattern, it would be excellent to
Something like this:
I obviously did not rewrite the whole thing, but you should catch my drift.
-
-
Do not use an if statement to determine true or false like you do :
do this instead:
If you have time, read up on falsy values, you could also simply do
-
I am still playing with the code, I managed to fix the right hand side bounce with this:
In essence you have to solve both the acceleration and the velocity.
I have to wonder, how do you access
It is too bad that the snippets will now allow for localStorage access, so I can only give you a link to jsbin with my refactored version and the source code here in case jsbin ever dies:
there are few things that could be improved:
-
Read up on the revealing module pattern, it would be excellent to
- Reduce your usage of
this
- Make your class look like 1 piece of code
Something like this:
// main particle constructor class
function Particle(position) {
var velocity = new PVector(random(-0.1, 0.1), random(-0.1, 0.1)),
acceleration = new PVector(random(-0.01, 0.01), random(-0.01, 0.01)),
lifeTime = 300,
position = position.get();
function update() {
velocity.add(acceleration);
position.add(velocity);
lifeTime--;
}
function render() {
strokeWeight(2);
stroke(161, 153, 153, lifeTime);
fill(140, 135, 140, lifeTime);
ellipse(position.x,position.y, 15, 15);
};
return {
update : update,
render: render;
}
};I obviously did not rewrite the whole thing, but you should catch my drift.
- You keep using
random(-0.1, 0.1), I would create a helper function for this
-
fill(140, 135, 140, lifeTime); -
Do not use an if statement to determine true or false like you do :
// check if the particle is dead
Particle.prototype.particleDead = function() {
if(this.lifeTime > 0) {
return false;
} else {
return true;
}
};do this instead:
// check if the particle is dead
Particle.prototype.particleDead = function() {
return this.lifeTime > 0
};If you have time, read up on falsy values, you could also simply do
return !this.lifetime-
I am still playing with the code, I managed to fix the right hand side bounce with this:
if(this.position.x >= 385) {
this.acceleration.x = random(-0.02, -0.01);
this.velocity.x = random(-0.1, -0.01);
}In essence you have to solve both the acceleration and the velocity.
I have to wonder, how do you access
random? I can only access random as a function under the instance of Processing.It is too bad that the snippets will now allow for localStorage access, so I can only give you a link to jsbin with my refactored version and the source code here in case jsbin ever dies:
var canvas = document.getElementById('partikals'),
pjs = new Processing(canvas),
width = 400,
height = 400,
padding = 15;
function Particle2(position) {
var velocity = new PVector(pjs.random(-0.1, 0.1), pjs.random(-0.1, 0.1)),
acceleration = new PVector(pjs.random(-0.01, 0.01), pjs.random(-0.01, 0.01)),
lifeTime = 300;
position = position.get();
function update() {
velocity.add(acceleration);
position.add(velocity);
lifeTime--;
}
function render() {
pjs.strokeWeight(2);
//Each particle is grey
pjs.stroke(161, 153, 153, lifeTime);
pjs.fill(140, 135, 140, lifeTime);
pjs.ellipse(position.x, position.y, 15, 15);
}
function isDead() {
return !lifeTime;
}
//I wonder if just *= -1 would work
function bounce() {
if (position.x > width - padding) {
acceleration.x = -Math.abs(acceleration.x);
velocity.x = -Math.abs(velocity.x);
}
if (position.x height - padding) {
acceleration.y = -Math.abs(acceleration.y);
velocity.y = -Math.abs(velocity.y);
}
if (position.y = 0; p--) {
var particle = particles[p];
particle.bounce();
particle.update();
particle.render();
if (particle.isDead()) {
particles.splice(p, 1);
}
}
};
pjs.setup();Code Snippets
// main particle constructor class
function Particle(position) {
var velocity = new PVector(random(-0.1, 0.1), random(-0.1, 0.1)),
acceleration = new PVector(random(-0.01, 0.01), random(-0.01, 0.01)),
lifeTime = 300,
position = position.get();
function update() {
velocity.add(acceleration);
position.add(velocity);
lifeTime--;
}
function render() {
strokeWeight(2);
stroke(161, 153, 153, lifeTime);
fill(140, 135, 140, lifeTime);
ellipse(position.x,position.y, 15, 15);
};
return {
update : update,
render: render;
}
};// check if the particle is dead
Particle.prototype.particleDead = function() {
if(this.lifeTime > 0) {
return false;
} else {
return true;
}
};// check if the particle is dead
Particle.prototype.particleDead = function() {
return this.lifeTime > 0
};if(this.position.x >= 385) {
this.acceleration.x = random(-0.02, -0.01);
this.velocity.x = random(-0.1, -0.01);
}var canvas = document.getElementById('partikals'),
pjs = new Processing(canvas),
width = 400,
height = 400,
padding = 15;
function Particle2(position) {
var velocity = new PVector(pjs.random(-0.1, 0.1), pjs.random(-0.1, 0.1)),
acceleration = new PVector(pjs.random(-0.01, 0.01), pjs.random(-0.01, 0.01)),
lifeTime = 300;
position = position.get();
function update() {
velocity.add(acceleration);
position.add(velocity);
lifeTime--;
}
function render() {
pjs.strokeWeight(2);
//Each particle is grey
pjs.stroke(161, 153, 153, lifeTime);
pjs.fill(140, 135, 140, lifeTime);
pjs.ellipse(position.x, position.y, 15, 15);
}
function isDead() {
return !lifeTime;
}
//I wonder if just *= -1 would work
function bounce() {
if (position.x > width - padding) {
acceleration.x = -Math.abs(acceleration.x);
velocity.x = -Math.abs(velocity.x);
}
if (position.x < padding) {
acceleration.x = Math.abs(acceleration.x);
velocity.x = Math.abs(velocity.x);
}
if (position.y > height - padding) {
acceleration.y = -Math.abs(acceleration.y);
velocity.y = -Math.abs(velocity.y);
}
if (position.y < padding) {
acceleration.y = Math.abs(acceleration.y);
velocity.y = Math.abs(velocity.y);
}
}
return {
update: update,
render: render,
isDead: isDead,
bounce: bounce
};
}
// array containing particles
var particles = [];
pjs.setup = function() {
pjs.size(width, height);
pjs.frameRate(24);
};
pjs.draw = function() {
//Clear by drawing the background and push a new particle
pjs.background(11, 100, 209);
particles.push(new Particle2(new PVector(pjs.mouseX, pjs.mouseY)));
// iterate through particles and run their methods
for (var p = particles.length - 1; p >= 0; p--) {
var particle = particles[p];
particle.bounce();
particle.update();
particle.render();
if (particle.isDead()) {
particles.splice(p, 1);
}
}
};
pjs.setup();Context
StackExchange Code Review Q#67745, answer score: 3
Revisions (0)
No revisions yet.