As promised, we will now start adding features to yesterday’s particle simulation. What we wound up with was pretty basic, but is a good starting point for building on. Today, we’ll be adding several main features:
A decent day’s work, I think. If you want to look at the full script as you follow along, you can find it here: https://www.bit-101.com/jscanvas/mar16.js
The emitter, as just mentioned, is merely an x, y point. Here’s the beginning of the function:
[php lang=“JavaScript”]$(function() {
var points = [], numPoints = 100, i, canvas, context, width, height, gravity = 0.1, emitter;
canvas = $("#canvas")[0];
width = canvas.width;
height = canvas.height;
context = canvas.getContext(“2d”);
emitter = {x:width / 2, y:height};[/php]
You see we have a var for emitter, and it’s at the center of the canvas horizontally, and the bottom of the screen vertically. You can also see the var for gravity, and some of the vars from yesterday have been removed as they are no longer needed.
Then we have a function called initPoint.
[php lang=“JavaScript”] function initPoint(p) {
p.x = emitter.x;
p.y = emitter.y;
p.vx = Math.random() * 4 – 2;
p.vy = Math.random() * -5 – 3;
p.radius = Math.random() * 5 + 1;
}[/php]
This takes a point object and sets various properties on it. x and y get set to emitter.x, emitter.y. vx is random in both directions, and vy is random, but always a negative value, making particles go up. Finally, we give the point a random radius.
Now we jump to the new update function. If you’re following along on the full script file, you may notice that we’ve lost the for loop that creates all the particles. As mentioned, particles will be created one at a time a bit later.
[php lang=“JavaScript”] function update() {
var i, point, len = points.length;
for(i = 0; i < len; i += 1) { point = points[i]; point.vy += gravity; point.x += point.vx; point.y += point.vy; if(point.x > width ||
point.x < 0 || point.y > height ||
point.y < 0) { initPoint(point); } } }[/php] This has gotten a bit shorter, but has a few importand additions. First, rather than looping from 0 to numPoints, we now loop from 0 to points.length. This is because to start with, there will be zero points, then 1, then 2, etc. We don’t need to be trying to update scores of non-existent particles. Next change, we add gravity to point.vy. This pulls it down. Finally, instead of dealing with each boundary separately, we just see if it’s hit any one, and if so, re-initialize the point. This puts it back on the emitter point, with a new random size and velocity. Next up is the draw method, which isn’t much different than before: [php lang=“JavaScript”] function draw() { var i, point, len = points.length; context.clearRect(0, 0, width, height); for(i = 0; i < len; i += 1) { point = points[i]; context.beginPath(); context.arc(point.x, point.y, point.radius, 0, Math.PI * 2, false); context.fill(); } }[/php] Mainly, we just switch to using points.length instead of numPoints, and the point’s radius with a black fill rather than a set radius with a stroke. I want to jump ahead slightly, to the setInterval call: [php lang=“JavaScript”] setInterval(function() { addPoint(); update(); draw(); }, 1000/24);[/php] This just has one additional line, a call to a function named addPoint. And here is that function: [php lang=“JavaScript”] function addPoint() { var point; if(points.length < numPoints) { point = {}; initPoint(point); points.push(point); } }[/php] This checks to see if we have reached the required number of points in the points array. If not, it creates a point object, initializes it and then pushes it into the points array. Thus, on the first frame, points will start out empty and a single point will be added. On the next frame, another one will be added, and so on until we have 100 (or whatever you set numPoints to). After that, this function will do nothing. It’s probably more optimal to do the conditional in the setInterval callback, so this function is never even called, but we’re working on clarity not optimization for the time being. And that’s it for today. To see it in action: https://www.bit-101.com/jscanvas/mar16.html
Also, this marks the halfway point of this series. I hope you are enjoying it and maybe learning a thing or two. Maybe even getting over a bit of JS anxiety or AS1 trauma. I know I’m sure learning a lot and having fun with it myself. Still shooting for finishing out the month. but I’ve covered a lot more ground already than I thought I would have. I still think I can dig up enough material to get through the rest of the month, bug it’s going to be a scramble as time goes on. I’m open to suggestions.