Отскок от стен
==============

* « Предыдущая статья
* Следующая статья »

Это 3-й этап из 10 Gamedev Canvas tutorial (en-US). Вы можете найти исходный код как он должен выглядеть после завершения этого урока в Gamedev-Canvas-workshop/lesson3.html.

Приятно наблюдать за нашим мяч, но он быстро исчезает с экрана, удовольствие длится недолго! Чтобы продлить, мы реализуем некоторое очень простое обнаружение столкновений (о которых будет рассказано далее (en-US) более подробно), чтобы сделать отскок мяча от четырёх краёв холста.

Простое обнаружение столкновений
--------------------------------

Для обнаружения столкновения мы будем проверять - касается ли мяч стены, и если это так, изменим направление его движения в нужную сторону.

Чтобы сделать расчёты проще, давайте определим переменную `ballRadius`, что задаст радиус нарисованного круга и будет использоваться для вычислений. Добавьте это в ваш код, где-то ниже существующих переменных:


```js
var ballRadius = 10;
```


Теперь обновите строку, которая рисует шарик, внутри функции `drawBall()`:


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

### Отскакивание от верхней и нижней стены

Есть четыре стены, от которых мяч будет отскакивать — давайте сначала сосредоточимся на верхней. При каждом кадре нужно проверять, коснулся ли мяч верхней границы — если да, то будет обратное движение мяча, поэтому он начнёт двигаться в противоположном направлении и остановится в пределах видимой границы. Вспомнив, что система координат начинается с левого верхнего угла, мы можем придумать что-то вроде этого:


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


Если значение `y` положения шара ниже нуля, изменить направление движения по оси y установив его с тем же значением но с другим знаком. Если мяч движется вверх со скоростью 2 пикселя на кадр, теперь он будет двигаться "вверх" со скоростью -2 пикселя, что на самом деле означает движение вниз со скоростью 2 пикселя.

Приведённый выше код описывает отражение только от верхней границы, так что теперь давайте думать о нижнем крае:


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


Если положение мяча по оси `y` больше, чем высота полотна (помните, что мы рассчитываем значения `y` от верхнего левого, чтобы верхний край начинался с 0, а нижний край — 480 пикселей, высота нашего `<canvas>`), затем после отскока от нижней кромки обратное движение по оси `y`.

Мы можем объединить эти две конструкции в одну, чтобы уменьшить код:


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


Если одно из двух утверждений верно, тогда направление мяча меняется.

### Отскоки влево и вправо

Мы сделали отражение от верхней и нижней границ, нельзя забывать и про боковины. Задача очень похожа на самом деле, все, что вам нужно сделать, это повторить конструкцию заменив Y на X:


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

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


На этом этапе вы должны вставить этот блок кода в функцию Draw (), непосредственно перед закрывающей фигурной скобкой.

### Мяч продолжает исчезать в стене!

Проверьте сейчас свой код, и вы будете впечатлёны — теперь мяч, отскакивает от всех четырёх краёв нашего `<canvas>`! Однако есть некоторая проблема - когда мяч попадает в любую стену, он немного заходит за границы `<canvas>` перед отскоком:

![](/ru/docs/Games/Tutorials/2D_Breakout_game_pure_JavaScript/Bounce_off_the_walls/ball-in-wall.png)

Это происходит потому, что мы проверяем касание стены и центра мяча, а не его края. Мяч должен отскакивать сразу после касания, а не когда он уже на половину в стене, так что давайте корректировать наш код включив в него небольшое выражение. Обновите последний код добавив к нему:


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


Когда расстояние между центром шара и краем стены равно радиусу шарика, шарик изменит направление движения. Вычитая радиус при отскоке от одной стены и добавляя при отскоке от другой, мы получили простое обнаружение столкновений. Шарик отскакивает от стен как надо.

Сравните ваш код
----------------

Давайте ещё раз проверим готовый код для этой части, и код, что у вас есть, и играйте:

**Примечание:** попробуйте изменить цвет шарика на случайный цвет каждый раз, когда он попадает в стену.

Следующий шаг
-------------

Теперь мы добрались до стадии, где наш мяч одновременно двигается и остаётся на игровом поле. В четвёртой главе мы рассмотрим реализацию управления — см. Paddle and keyboard controls (en-US).

* « Предыдущая статья (en-US)
* Следующая статья » (en-US)