Ракетка и управление клавиатурой
Это 4-й этап из 10 Gamedev Canvas tutorial. Вы можете найти исходный код как он должен выглядеть после завершения этого урока в Gamedev-Canvas-workshop/lesson4.html.
Мяч беспрепятственно отражается от стен, и вы можете смотреть на него бесконечно, но в настоящее время нет интерактивности. Это не игра, если вы не можете управлять мячом. Давайте добавим взаимодействие с игрой: управление ракеткой.
Определение ракетки, чтобы ударить по мячу
Итак, нам нужна ракетка, чтобы ударить по мячу - давайте определим несколько переменных для этого. Добавьте следующие переменные в верхней части кода, рядом с вашими другими переменными:
var paddleHeight = 10;
var paddleWidth = 75;
var paddleX = (canvas.width - paddleWidth) / 2;
Здесь мы определяем высоту и ширину ракетки, и его начальную точку на оси X, для дальнейшего использования в расчётах. Давайте создадим функцию, которая будет рисовать ракетку на экране. Добавьте следующий блок после функции drawBall()
:
function drawPaddle() {
ctx.beginPath();
ctx.rect(paddleX, canvas.height - paddleHeight, paddleWidth, paddleHeight);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
}
Позволяем пользователю управлять ракеткой
Мы можем отобразить ракетку там, где мы хотим, но она должна реагировать на действия пользователя — настало время реализовать управление с помощью кнопок. Нам понадобится:
- Две переменные для хранения информации о том, левая или правая кнопка управления нажата.
- Два обработчика для событий
keydown
иkeyup
— мы хотим запустить некоторый код для обработки движения ракетки при нажатии кнопок. - Две функции обработки события
keydown
иkeyup
код, который будет выполняться при нажатии кнопок. - Возможность перемещения ракетки влево и вправо
Нажатые кнопки могут быть определены и инициализированы булевыми переменными. Добавьте эти строки рядом с остальными вашими переменными:
var rightPressed = false;
var leftPressed = false;
Значением по умолчанию для обоих является false
, так как изначально кнопки не нажаты. Для обработки нажатий клавиш, мы создадим два обработчика событий. Добавьте следующие строки чуть выше функции setInterval()
в нижней части JavaScript:
document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
Когда keydown
событие вызывается любой клавишей клавиатуры (нажатием клавиши), функция keyDownHandler()
будет выполняться. Та же картина верна для второго обработчика: keyup
событие запустит функцию keyUpHandler ()
(когда будет отпущена). Добавьте следующий блок в ваш код ниже addEventListener()
:
function keyDownHandler(e) {
if (e.keyCode == 39) {
rightPressed = true;
} else if (e.keyCode == 37) {
leftPressed = true;
}
}
function keyUpHandler(e) {
if (e.keyCode == 39) {
rightPressed = false;
} else if (e.keyCode == 37) {
leftPressed = false;
}
}
Когда мы нажимаем клавишу, эта информация хранится в переменной. Соответствующая переменная в каждом конкретном случае устанавливается в true
. Когда клавиша отпущена, переменная устанавливается обратно в false
.
Обе функции принимают параметр, представленный переменной e
. Из неё вы можете получить полезную информацию: key
содержит информацию о нажатой клавише. Например, код 37 — это клавиша стрелка влево и 39 — стрелка вправо. Если стрелка влево нажата, то переменная leftPressed
имеет значение true
, когда кнопка отпущена, то переменная leftPressed имеет значение false. Та же схема со стрелкой вправо и переменной rightPressed.
Логика перемещения ракетки
Теперь у нас есть переменные для хранения информации о нажатых клавишах, обработчики событий и соответствующие функции. Теперь мы допишем код, чтобы перемещать ракетку на экране. Внутри функции draw()
, мы будем проверять, нажата левая или правая клавиша, когда каждый кадр отображается. Наш код будет выглядеть следующим образом:
if (rightPressed) {
paddleX += 7;
} else if (leftPressed) {
paddleX -= 7;
}
Если нажата стрелка влево, то ракетка будет двигаться на 7 пикселей влево, а если нажата стрелка вправо то на 7 пикселей вправо. Все хорошо, но, если держать клавишу слишком долго, ракетка уходит за границы холста. Улучшим ситуацию, будем перемещать ракетку только в пределах холста, изменив код следующим образом:
if (rightPressed && paddleX < canvas.width - paddleWidth) {
paddleX += 7;
} else if (leftPressed && paddleX > 0) {
paddleX -= 7;
}
Позиция paddleX
будет двигаться от 0 на левой стороне холста и canvas.width-paddleWidth
на правой стороне. Это будет работать именно так, как нам нужно.
Добавьте вышеприведённый блок кода в функцию draw()
в самый конец, чуть выше закрывающей фигурной скобки.
Единственное, что осталось сделать сейчас, это вызвать drawPaddle()
функцию внутри функции draw()
, чтобы нарисовать ракетку на экране. Добавьте следующую строку внутрь функции draw()
, чуть ниже строки, которая вызывает drawBall()
:
drawPaddle();
Сравните ваш код
Вот работающий код для вас, чтобы сравнить со своим:
Примечание: Сделайте скорость движения ракетки быстрее или медленнее, или измените её размер.
Следующий шаг
Теперь у нас есть что-то похожее на игру. Беда только в том, что пока вы можете лишь бесконечно бить мяч ракеткой. Это все изменится в пятой главе, Game over, когда мы начнём добавлять конечное состояние для нашей игры.
io error: No such file or directory (os error 2) (/home/runner/work/yari/yari/mdn/content/files/en-us/games/workflows/2d_breakout_game_pure_javascript/bounce_off_the_walls/index.md)