HTML and CSS Reference
In-Depth Information
}());
};
</script>
</body>
</html>
Here, you are simply using the double-nested iteration to perform collision detection. In this case, the
reaction might need some additional explanation. Here's the collision reaction code located in the
checkCollision function:
if (dist < min_dist) {
var angle = Math.atan2(dy, dx),
tx = ballA.x + Math.cos(angle) * min_dist,
ty = ballA.y + Math.sin(angle) * min_dist,
ax = (tx - ballB.x) * spring * 0.5,
ay = (ty - ballB.y) * spring * 0.5;
ballA.vx -= ax;
ballA.vy -= ay;
ballB.vx += ax;
ballB.vy += ay;
}
Remember that this occurs once a collision is found between ballA and ballB . Essentially, it starts out
the same as the earlier example with the unmoving center ball. For now, let ballA take the place of that
center ball. You find the angle between the two, and get a target x and y. This is the point that you would
need to place ballB so that the two balls would not be touching. Based on that, you get the x and y
acceleration that would cause ballB to spring to that point, then we cut it in half (which I explain next).
These are ax and ay .
But then you do something a little tricky. In this case, not only does ballB need to spring away from
ballA , but ballA must spring away from ballB . The acceleration would be the same force and exactly
the opposite direction. So rather than calculate it twice, you just add ax and ay to ballB 's velocity, and
subtract them from ballA 's velocity! You get the same result, and you just saved a bunch of calculation.
You might be thinking that this doubles the final acceleration, as it's being applied twice; and that's true. To
compensate, we cut the the spring product in half, multiplying it by 0.5, when we calculated ax and ay .
You can remove these two multiplication operations by halving the spring variable when you declare it,
to 0.015.
While we're discussing optimization tricks, here's another one here. The preceding code calculates the
angle using Math.atan2 , and then uses Math.cos and Math.sin to find the target point:
var angle = Math.atan2(dy, dx),
tx = ballA.x + Math.cos(angle) * min_dist,
ty = ballA.y + Math.sin(angle) * min_dist;
But remember that sine is opposite over hypotenuse, and cosine is adjacent over hypotenuse. And since
the opposite side of the angle is dy , the adjacent side is dx , and the hypotenuse is dist . Thus, you could
actually shorten these three lines to just two:
Search WWH ::




Custom Search