Создание или клонирование браузерных игр - очень полезная практика для энтузиастов веб-разработки. На этот раз мы будем делать знаменитую игру Flappy Bird. Вы можете получить коды этого проекта в репо this.

Прежде чем перейти к разделу кода, давайте рассмотрим необходимые визуальные эффекты. В игре могут использоваться десятки разных изображений. Было бы неэффективно загружать их все по очереди, делать для каждого отдельный запрос, выделять место в памяти. Вместо этого мы объединим все изображения и включим их в нашу игру как один файл изображения и будем использовать его, показывая расположение нужного нам изображения. Для Flappy Bird мы будем использовать это спрайтовое изображение. Вы также можете получить доступ к изображению из репозитория git.

Приступим к кодированию. Как обычно, мы начинаем с нашего файла index.html. Мы добавляем элемент холста в наше дерево DOM. Все наши рисунки будут на этом холсте с javascript. С помощью простых стилей CSS мы центрируем холст и используем изображение спрайта в качестве фона. С помощью background-size мы гарантируем, что изображение совпадает с соответствующей частью.

Наша часть javascript начинается с файла game.js. Мы будем использовать модульную структуру с 4 различными модульными файлами.

  • vars: некоторые глобальные переменные для игры
  • Bird: содержит класс Bird
  • Земля: содержит класс земли, птица которого умрет, если приземлится на нее.
  • Столбец: содержит класс столбца как препятствие

В нашем файле game.js мы сначала берем элемент холста из дерева DOM и устанавливаем его размер в соответствии с размером экрана. Поскольку это игра в портретном режиме, мы указываем максимальную высоту и высоту 16/9 в качестве ширины.

Когда птица падает, требуется сила тяжести, которая притягивает ее к земле. Мы рассчитали это в пикселях на кадр, чтобы весь экран опустился за 5 секунд, и присвоили это переменной GRAVITY.

Мы назначаем iamge нашего спрайта переменной sprite, чтобы использовать его во всех объектах. Мы создаем экземпляр переменных птицы, земли и столбцов из их соответствующих классов. Поскольку нам нужно увеличивать счет, когда столбцы выходят за пределы экрана и снова оживают, мы используем функцию Увеличить счет, поскольку нам нужно привязать для нее событие.

Мы будем рисовать на холсте для каждого кадра с помощью setInterval. С помощью context.clearRect мы сначала очищаем наш экран. Поскольку мы предоставляем наш фон с помощью CSS, наше фоновое изображение будет видно, даже если мы сделаем clearRect. Для каждого из наших экземпляров мы вызываем метод draw, рисуем на холсте и выставляем счет с помощью fillText. Наконец, мы завершаем setInterval, проверяя, касается ли наша птица земли или столбцов.

Птица

Наше изображение птицы имеет 3-кадровую анимацию. Мы передаем координаты каждого шага переменной frames в конструкторе. Вы можете использовать Sprite Cow, чтобы легко найти эти значения положения на изображении спрайта. Мы сохраним положение птицы на холсте в переменной объекта position. Наконец, чтобы масштабировать размер птицы (34 * 24) в соответствии с нашим холстом, мы сравниваем размеры холста с размерами фонового изображения (288 * 512) в нашем спрайтовом изображении.

С помощью метода draw мы повторно вычисляем вертикальное положение (y) для каждого кадра и рисуем его на нашем холсте с помощью drawImage.
Путем сравнения значений относительного положения оба объекта с методами isTouchingGround и isTouchingColumns, мы возвращаем true в случае конфликта и завершения игры.

Земля

Не сильно отличается от класса Bird. Фоновое изображение в спрайте немного длиннее фонового. Мы будем использовать это, чтобы создать впечатление, что мы движемся вперед. Через каждые 22 пикселя присутствует повторяющийся узор. Мы отмечаем каждую пару пикселей и добавляем их в массив frames. Остальные части этого класса работают почти так же, как класс Bird.

Столбец

В методе конструктора этого класса мы назначаем зазор между двумя столбцами переменной gap (25% высоты холста). gapTopPosition указывает вертикальное положение верхнего столбца. Мы изменяем это значение случайным образом в методе reviveColumn, который вызывается каждый раз, когда столбец выходит за пределы холста, поэтому наш промежуток не всегда находится в одном и том же положении.