Online Book Reader

Home Category

HTML5 Canvas [70]

By Root 6524 0
to help manage the multiple balls that will bounce around the canvas:

numBalls

The number of balls to randomly create

maxSize

The maximum radius length for any given ball

minSize

The minimum radius length for any given ball

maxSpeed

The maximum speed any ball can travel

balls

An array to hold all of the ball objects we will create

The following code shows the newly defined variables:

var numBalls = 100 ;

var maxSize = 8;

var minSize = 5;

var maxSpeed = maxSize+5;

var balls = new Array();

We also create a set of temporary variables to hold the values for each ball before we push it into the balls array:

var tempBall;

var tempX;

var tempY;

var tempSpeed;

var tempAngle;

var tempRadius;

var tempRadians;

var tempXunits;

var tempYunits;

Next, in canvasApp(), we iterate through a loop to create all the ball objects. Notice how tempX and tempY are created below. These values represent the ball’s starting location on the canvas. We create a random value for each, but we offset it by the size of the ball (tempRadius*2). If we did not do that, some of the balls would get “stuck” in a wall when the app starts because their x or y location would be “through” the wall, but their speed would not be enough so that a “bounce” would get them back on the playfield. They would be stuck in bouncing limbo forever (which is kind of sad when you think about it).

NOTE

When you try this app, you will see that occasionally a ball still gets stuck in a wall. There is a further optimization we need to make to prevent this, but it is a bigger subject than this little iteration. We will talk about it in the section Multiple Balls Bouncing and Colliding.

The tempSpeed variable is created by subtracting the value of tempRadius from the value of maxSpeed, which we created earlier. The speed is not random, but it is inversely proportional to the size (radius) of the ball. A larger ball has larger radius, so the value you subtract from tempSpeed will be larger, thus making the ball move slower:

NOTE

When you run CH5EX4.html in your web browser, you will notice that this little trick makes the ball appear more “real” because your brain expects larger objects to move slower.

for (var i = 0; i < numBalls; i++) {

tempRadius = Math.floor(Math.random()*maxSize)+minSize;

tempX = tempRadius*2 + (Math.floor(Math.random()*theCanvas.width)-tempRadius*2);

tempY = tempRadius*2 + (Math.floor(Math.random()*theCanvas.height)-tempRadius*2);

tempSpeed = maxSpeed-tempRadius;

tempAngle = Math.floor(Math.random()*360);

tempRadians = tempAngle * Math.PI/ 180;

tempXunits = Math.cos(tempRadians) * tempSpeed;

tempYunits = Math.sin(tempRadians) * tempSpeed;

tempBall = {x:tempX,y:tempY,radius:tempRadius, speed:tempSpeed, angle:tempAngle,

xunits:tempXunits, yunits:tempYunits}

balls.push(tempBall);

}

Now we need to draw the balls onto the canvas. Inside drawScreen(), the code to draw the balls should look very familiar because it is essentially the same code we used for one ball in Example 5-4. We just need to loop through the balls array to render each ball object:

for (var i = 0; i ball = balls[i];

ball.x += ball.xunits;

ball.y += ball.yunits;

context.beginPath();

context.arc(ball.x,ball.y,ball.radius,0,Math.PI*2,true);

context.closePath();

context.fill();

if (ball.x > theCanvas.width || ball.x < 0 ) {

ball.angle = 180 - ball.angle;

updateBall(ball);

} else if (ball.y > theCanvas.height || ball.y < 0) {

ball.angle = 360 - ball.angle;

updateBall(ball);

}

}

When you load Example 5-5 in your web browser, you will see a bunch of balls all moving around the screen independently, as shown in Figure 5-6. For the fun of it, why not change the numBalls variable to 500 or 1,000? What does the canvas look like then?

Figure 5-6. Multiple balls of different sizes bouncing off walls

Example 5-5. Multiple ball bounce

CH5EX5: Multiple Ball Bounce