Online Book Reader

Home Category

HTML5 Canvas [74]

By Root 6554 0
tempY we randomly created for it. We will do this with a call to a new function named canStartHere(). If canStartHere() returns true, we drop out of the while() loop; if not, we start all over again:

placeOK = canStartHere(tempBall);

}

The canStartHere() function is very simple. It looks through the ball array, testing the new tempBall against all existing balls to see whether they overlap. If they do, the function returns false; if not, it returns true. To test the overlap, we have created another new function: hitTestCircle():

function canStartHere(ball) {

var retval = true;

for (var i = 0; i if (hitTestCircle(ball, balls[i])) {

retval = false;

}

}

return retval;

}

Circle collision detection


The hitTestCircle() function performs a circle/circle collision-detection test to see whether the two circles (each representing a ball) passed as parameters to the function are touching. Because we have been tracking the balls by the center x and y of their location, this is quite easy to calculate. First, the function finds the distance of the line that connects the center of each circle. We do this using our old friend the Pythagorean theorem (A2+B2 = C2). We use the nextx and nexty properties of the ball because we want to test the collision before it occurs. (Again, if we test after by using the current x and y locations, there is a good chance the balls will get stuck together and spin out of control.) We then compare that distance value to the sum of the radius of each ball. If the distance is less than or equal to the sum of the radii, we have a collision. This is a very simple and efficient way to test collisions, and it works especially well with collisions among balls in 2D:

function hitTestCircle(ball1,ball2) {

var retval = false;

var dx = ball1.nextx - ball2.nextx;

var dy = ball1.nexty - ball2.nexty;

var distance = (dx * dx + dy * dy);

if (distance <= (ball1.radius + ball2.radius) * (ball1.radius + ball2.radius) ) {

retval = true;

}

return retval;

}

Figure 5-9 illustrates this code.

Figure 5-9. Balls colliding

Separating the code in drawScreen()


The next thing we want to do is simplify drawScreen() by separating the code into controllable functions. The idea here is that to test collisions correctly, we need to make sure some of our calculations are done in a particular order. We like to call this an update-collide-render cycle.

update()

Sets the nextx and nexty properties of all the balls in the balls array.

testWalls()

Tests to see whether the balls have hit one of the walls.

collide()

Tests collisions among balls. If the balls collide, updates nextx and nexty.

render()

Makes the x and y properties for each ball equal to nextx and nexty respectively, and then draws them to the canvas.

And here is the code:

function drawScreen () {

update();

testWalls();

collide();

render();

}

Updating positions of objects


The update() function loops through all the balls in the balls array, and updates the nextx and nexty properties with the x and y velocity for each ball. We don’t directly update x and y here, because we want to test collisions against walls and other balls before they occur. We will use the nextx and nexty properties for this purpose:

function update() {

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

ball.nextx = (ball.x += ball.velocityx);

ball.nexty = (ball.y += ball.velocityy);

}

}

Better interaction with the walls


We discussed the interactions between balls and walls in the last example, but there is still one issue. Since we move the balls by the x and y location of their center, the balls would move halfway off the canvas before a bounce occurred. To fix this, we add or subtract the radius of the ball object, depending on which walls we are testing. For the right side and bottom of the canvas, we add the radius of the ball when we test the walls. In this way, the ball will appear to bounce exactly when its edge hits a wall. Similarly, we subtract the radius when we test the left side and the top of

Return Main Page Previous Page Next Page

®Online Book Reader