Отскок от стен
Это 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>
перед отскоком:
Это происходит потому, что мы проверяем касание стены и центра мяча, а не его края. Мяч должен отскакивать сразу после касания, а не когда он уже на половину в стене, так что давайте корректировать наш код включив в него небольшое выражение. Обновите последний код добавив к нему:
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).