Это 4-й этап из 10 Gamedev Canvas tutorial. Вы можете найти исходный код как он должен выглядеть после завершения этого урока в Gamedev-Canvas-workshop/lesson4.html.
Мяч беспрепятственно отражается от стен, и вы можете смотреть на него бесконечно, но в настоящее время нет интерактивности. Это не игра если Вы не можете контролировать его! Так давайте добавим некоторое взаимодействие с пользователем: управление ракеткой.
Определение ракетки, чтобы ударить по мячу
Итак, нам нужна ракетка, чтобы ударить по мячу - давайте определим несколько переменных для этого. Добавьте следующие переменные в верхней части кода, рядом с вашими другими переменными:
var paddleHeight = 10; var paddleWidth = 75; var paddleX = (canvas.width-paddleWidth)/2;
Здесь мы определяем высоту и ширину ракетки, и его начальную точку на оси х, для использования в расчетах далее вниз по коду. Давайте создадим функцию, которая будет рисовать ракетку на экране. Добавьте следующий раз ниже вашей функции 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
. Из этого вы можете получить полезную информацию: ключ содержит информацию о нажатой клавиши. Например, код 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, когда мы начнем добавлять конечное состояние для нашей игры.