MDN wants to learn about developers like you: https://qsurvey.mozilla.com/s3/MDN-dev-survey

这篇翻译不完整。请帮忙从英语翻译这篇文章

本篇是 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;
}

如果球的纵坐标(y轴)值小于零,我们将在球体原有的运动方向上逆转。如果球体向上移动的速度是2像素/帧,现在就是向上移动速度是-2像素。这相当于此时向下移动的速度是2像素/帧。

上面的代码将处理球与画布顶部边缘的反射,现在让我们思考一下底部边缘如何处理:

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,