HTML and CSS Reference
In-Depth Information
for (var ballA, i = 0, len = numBalls - 1; i < len; i++) {
ballA = balls[i];
for (var ballB, j = i + 1; j < numBalls; j++) {
ballB = balls[j];
checkCollision(ballA, ballB);
}
}
balls.forEach(draw);
}());
};
</script>
</body>
</html>
The balls are spaced out to ensure that they do not touch each other to start with. If so, they can get stuck
together.
The
drawFrame
function is surprisingly simple; it iterates over the balls three times: one for basic
movement, one for collision detection, and of course, one to draw. The first
forEach
iteration passes each
ball to the
move
function, which updates the ball's position, moving it and bouncing it off the walls. Then,
the double-nested
for
loop performs the collision detection. Here, you get a reference to two balls at a
time and pass them to the
checkCollision
function. The
checkWalls
and
checkCollision
functions
are the same as before, so just add them to this file from the previous example.
To add more balls, just update the
numBalls
variable to the new total and make sure they do not touch at
the start of the animation.
Solving a Potential Problem
One word of warning regarding the setup described in this chapter: It's still possible for a pair of objects to
get stuck together. This usually happens in a crowded environment with many objects bouncing off each
other, and is worse when they are moving at high speeds. You can also occasionally see this behavior if
two or three balls collide in a corner.
If there are three balls on the screen—
ball0
,
ball1
, and
ball2—
and they all happen to be close together,
here's what happens:
The code moves all three according to their velocities.
The code checks
ball0
versus.
ball1
and
ball0
versus
ball2
. It finds no collision.
The code checks
ball1
versus
ball2
. These two happen to be hitting, so it does all the
calculations for their new velocities and updates their positions so that they are no longer
touching. This inadvertently puts
ball1
in contact with
ball0
. However, this particular
combination has already been checked for a collision, so it now goes unnoticed.
On the next loop, the code again moves each according to its velocity. This potentially drives
ball0
and
ball1
even further together.
Now the code does notice that
ball0
and
ball1
hit. It calculates their new velocities and adds
the new velocities to the positions, to move them apart. But, because they were already touching,
this might not be enough to actually separate them. They become stuck.