Данная статья планируется как пошаговый обзор создания простой JavaScript-игры класса “Ball and Paddle” на Canvas. Примерами такой игры могут послужить старые DOS-е игры наподобие таких - Ball and Paddle.
Пример кода из этой статьи взят из видео-курса достаточно известного Интернет-ресурса, посвященного фронтенд-разработке - Udemy.
Почему Canvas и почему игра? Лично для меня процесс познания JavaScript сильно облегчается благодаря Canvas - так интереснее. А создание игры на Canvas - это еще интереснее!
Итак, с чего начнем? Дальше в меру своих сил буду стараться детально пошагово рассказывать, что делает тот или иной кусок кода. И начнем с базового набора - создания Canvas.
Базовый Canvas
HTML-разметка страницы будет предельно простой:
В JavaScript’е создадим две глобальные переменные - одну для элемента Canvas, вторую - для 2d-контекста Canvas. Когда parser браузера построит DOM-дерево документа (событие
), инициализируем обе переменные, выполним проверку удачного получения 2d-контекста Canvas и если проверка будет пройдена успешно, то динамически зададим размеры Canvas:1
DOMContentLoaded
Базовые элементы игры
Основа Canvas была создана в предыдущем шаге. В этом шаге создадим три фигуры, которые будут учавствовать в игре. Таковыми фигурами будут:
- фон игры
- мячик (ball)
- площадка (paddle)
Ниже я приведу JavaScript-код создания всех трех элементов, но сам код комментировать не буду, так как он очень простой и относится к основам Canvas:
Живой результат вышеприведенного кода можно посмотреть на этой странице - Lesson1-1. Это то, что должно получиться и что послужит заготовкой для игры.
Анимация мячика
В этом шаге предстоит сделать более интересные вещи. Во-первых, мы сделаем так, чтобы мячик начал двигаться как по-горизонтали, так и по-вертикали. А во-вторых, сделаем так, чтобы он вел себя как настоящий резиновый мячик - при ударе о стену отскакивал от нее и мчался в противоположном направлении.
Сделать это достаточно просто. Для этого нам понадобится одна из так называемых тайминговых функций JavaScript -
. А также немного воображения.1
setInterval()
Анимация мячика будем делать по-простому принципу, по которому делается любой мультфильм или кино - мячик будет отрисовываться с заданной частотой (
), но каждый раз в новой позиции. В результате будет создаваться иллюзия его движения. Каждая новая позиция мячика - это его координата по оси X или Y с новым значением соответственно.1
1000/frames
Чтобы мячик двигался достаточно быстро, изменять значения координат (
и 1
ballX += ballStepX
) мячика по оси X и Y будем с определенным шагом (1
ballY += ballStepY
и 1
ballStepX
) - допустим, со значениями 5 или 6:1
ballStepY
Эффект отскакивания от стенок (как резиновый мячик) обеспечивает проверка условий в участке кода:
Здесь все просто - при выполнении условия знак переменной
или 1
ballStepX
будет меняться на противоположный. В результате значение переменной 1
ballStepY
или 1
ballX
будет возрастать или уменьшаться. Как следствие, мячик будет двигаться в одну или в другую сторону.1
ballY
Живой пример приведенного выше кода можно посмотреть и изучить на этой странице - Lesson1-2.
Двигаем paddle
В этом шаге нужно заставить двигаться paddle при помощи мыши. Для этого по событию
внутри элемента Canvas будем получать значение X-координаты курсора мыши. И передавать это значение элементу paddle, его X-координате левого верхнего угла. Тем самым мы заставим paddle двигаться. За все эти действия будет отвечать функция 1
mousemove
:1
mouseCoords()
Обратите внимание на последнюю строку функции -
. Переменная 1
paddleX = mouseX - paddleWidth/2;
необходима для того, чтобы при выходе за границы Canvas элемент paddle скрывался ровно на половину своей ширины.1
paddleX
Также не забудем создать переменные для paddle и передать их в код для отрисовки фигуры:
Живой пример приведенного выше кода можно посмотреть и изучить на этой странице - Lesson1-3. Подвигайте курсором мыши право-влево, чтобы увидеть эффект.
Мячик отскакивает от paddle
На этом этапе нужно сделать так, чтобы мячик отскакивал от paddle, когда последний оказывается на его пути. Выполнить эту задачу просто - ведь мячик уже отскакивает от “стен” Canvas. Следовательно, нужно научить мячик “видеть” еще и paddle.
Для этого сначала нужно опеределить внешние границы paddle - все его четыре стороны:
Когда значения всех сторон будут определены, то можно будет подставить эти значения в условие - и дело сделано:
Живой пример приведенного выше кода можно посмотреть и изучить на этой странице - Lesson1-4. Подвигайте курсором мыши право-влево и постарайтесь поймать мячик с помощью paddle, чтобы увидеть эффект.
Угол отскока мячика
В этом шаге сделаем так, чтобы наша игра смотрелась более правильной с точки зрения физики и обычной природы. То есть, при разном угле попадания на paddle мячик должен отскакивать от него с разной скоростью. Чем острее угол падения, тем с большей скоростью отскакивает от paddle мячик.
Решается эта задача несколькими строками кода:
В первой строке
находится X-координата середины paddle. В строке 1
var paddleCenter = paddleLeftEdge + paddleWidth/2;
определяется расстояние, на котором мячик соприкоснулся с paddle относительно его середины. В строке 1
var ballDistance = ballX - paddleCenter;
полученная дистанция присваивается шагу приращения по оси Х мячика - 1
ballStepX = ballDistance * 0.35;
.1
ballStepX
Логично предположить, что чем больше величина дистанции точки соприкосновения мячика относительно середины paddle, тем выше новая скорость движения мячика по-горизонтали. Чтобы эта скорость не была слишком высокой, ее необходимо уменьшить, умножив на 0.35, к примеру.
Живой пример приведенного выше кода можно посмотреть и изучить на этой странице - Lesson1-5.
Оптимизация кода
На данный момент наша задача по построению игры практически решена. Но остался один организационный момент.
Заключается он в том, что код необходимо реорганизовать в отдельные функции. Такой код будет читаться и поддерживаться значительно лучше.
Одна из таких функций уже была создана ранее - это функция
. Давайте преобразуемся и весь оставшийся код подобным образом:1
mouseCoords()
Готовый пример преобразованного в функции кода можно посмотреть на этой странице - Lesson1-6.
На этом все.