MDN’s new design is in Beta! A sneak peek:



本篇是 Gamedev Canvas tutorial 10节教程中的第二节。如果你完成了本篇教程之后,你可以从 Gamedev-Canvas-workshop/lesson3.html 看到源码。




为了运算方便我们定义一个名为 ballRadius 的变量,来存储球的半径。向代码中添加一下内容:

var ballRadius = 10;

现在更新绘制球的 drawBall() 函数:

ctx.arc(x, y, ballRadius, 0, Math.PI*2);

Bouncing off the top and bottom


if(y + dy < 0) {
    dy = -dy;



if(y + dy > canvas.height) {
    dy = -dy;

If the ball's y position is greater than the height of the Canvas (remember that we count the y values from the top left, so the top edge starts at 0 and the bottom edge is at 480 pixels, the Canvas' height), then bounce it off the bottom edge by reversing the y axis movement as before.

We could merge those two statements into one to save on code verbosity:

if(y + dy > canvas.height || y + dy < 0) {
    dy = -dy;

If either of the two statements is true, reverse the movement of the ball.

Bouncing off the left and right

We have the top and bottom edge covered, so let's think about the left and right ones. It is very similar actually, all you have to do is to repeat the statements for x instead of y:

if(x + dx > canvas.width || x + dx < 0) {
    dx = -dx;

if(y + dy > canvas.height || y + dy < 0) {
    dy = -dy;

At this point you should insert the above code block into the draw() function, just before the closing curly brace.

The ball keeps disappearing into the wall!

Test your code at this point, and you will be impressed — now we have a ball that bounced off all four edges of the canvas! We have another problem however — when the ball hits each wall it sinks into it slightly before changing direction:

This is because we're calculating the collision point of the wall and the center of the ball, while we should be doing it for its circumference. The ball should bounce right after if touches the wall, not when it's already halfway in the wall, so let's adjust our statements a bit to include that. Update the last code you added to this:

if(x + dx > canvas.width-ballRadius || x + dx < ballRadius) {
    dx = -dx;
if(y + dy > canvas.height-ballRadius || y + dy < ballRadius) {
    dy = -dy;

When the distance between the center of the ball and the edge of the wall is exactly the same as the radius of the ball, it will change the movement direction. Subtracting the radius from one edge's width and adding it onto the other gives us the impression of the proper collision detection — the ball bounces off the walls as it should do.

Compare your code

Lets again check the finished code for this part against what you've got, and have a play:

Exercise: try changing the color of the ball to a random colour every time it hits the wall.

Next steps

We've now got to the stage where our ball is both moving and staying on the game board. In the fourth chapter we'll look at implementing a controllable paddle — see Paddle and keyboard controls.


 此页面的贡献者: jackblackevo, jiii
 最后编辑者: jiii,