Game Development Reference
In-Depth Information
We also need to add some code to the ParticleSystem to prune old particles. We will do this in a very
simple way by using a new array for the particles that are still alive. This is not very efficient (it produces
quite a bit of garbage), but it is very easy to implement and often good enough. The updated update()
function will look like this:
ParticleSystem.prototype = {
update: function(td) {
var alive = [];
for(var i = 0; i < this.particles.length; i++) {
var particle = this.particles[i];
for(var j = 0; j < this.forces.length; j++) {
var force = this.forces[j];
force(particle, td);
}
if(particle.update(td)){
alive.push(particle);
}
}
this.particles = alive;
}
};
The last step is simply to define a maxAge for our firework particles. As always, making the value a bit fuzzy
will make it look much more realistic.
particle.velocity.x = Math.cos(alpha)*radius;
particle.velocity.y = Math.sin(alpha)*radius;
particle.image = spark;
particle.maxAge = fuzzy(0.5, 2);
Rendering
Our fireworks now behave quite realistically. But they still don't look very good. Luckily, we can change this
with a few little tweaks.
Our firework particles are emitting light; because of this, we should change the blend mode to be additive, so
two lights on top of each other will be brighter than one alone. When using the canvas tag, we can do additive
blending by setting the globalCompositeOperation to lighter. The globalCompositeOperation is very similar
to layer modes in image editing software. It's important that we reset the globalCompositeOperation back to
its default value of ' source-over ' after drawing the particles to avoid side effects.
ctx.globalCompositeOperation = 'lighter';
renderCanvasImage(ctx, system.particles);
ctx.globalCompositeOperation = 'source-over';
Moving bright lights on a dark background usually leaves a trail because of motion blur. We can emulate
this effect by changing the alpha of the background value that we use to clear the frame.
system.update(1/30);
ctx.fillStyle = 'rgba(0, 0, 0, 0.4)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
 
Search WWH ::




Custom Search