Если первая часть была о том, «почему это было сделано»,
то вторая часть – о «как это было сделано».

Лично я чувствую себя гораздо комфортнее, когда работаю с бэкенд-системами, такими как Django, PostgreSQL, Redis и Docker при создании веб-приложений.
Но этот проект был в основном основан на чистом ванильном JS + HTML5 Canvas.
Технологии фронтенда, которые я обычно не углубляюсь, стали ключевыми в этой игре.

И, к моему удивлению…
это было невероятно увлекательно.
Это было техническим фактором, который заставил меня погрузиться в процесс.

Обычно я не «люблю» фронтенд-работу, это скорее «не люблю» – любовь к 豆柴の大群 сделала «неприятные дела» приятными.

Скриншот экрана выбора персонажа


1. HTML5 Canvas – мир, похожий на “живопись + анимация”



Суть MAME RUN!! – это HTML5 Canvas.
Это область, созданная на веб-странице, подобная «живописи», где мы создаем игру, рисуя пиксели прямо здесь.

Обычно веб-разработка выглядит следующим образом:

  • Создание кнопок (HTML)

  • Заливка цветом (CSS)

  • Добавление немного действия (JS)

Но для Canvas всё совершенно иначе.

Canvas – это структура, которая перерисовывается от 30 до 60 кадров в секунду.
С каждым кадром:

  1. Стирает фон

  2. Перерисовывает

  3. Рисует персонажа

  4. Рисует препятствия

  5. Считает столкновения

  6. Увеличивает счет

  7. Резервирует следующий кадр

Это повторяется десятки раз в секунду.

Современные веб-браузеры невероятно мощные, как игровые движки.


2. Прыжок и гравитация: “Магия, создаваемая всего с 3 строками кода”

Основной элемент игры – «прыжок», который на самом деле реализован очень простыми физическими законами.

dino.vy += gravity * dt;  // Применение гравитации
dino.y  += dino.vy * dt;  // Изменение положения

if (dino.y >= ground) {
    dino.y = ground;
    dino.vy = 0;
}

С этим простым логическим расположением
леона может плавно прыгать, приземляться и падать.

В отсутствие игрового движка,
«О, так это базовая физика действительно дает достаточно отзывчивое движение»
вызвало небольшое удивление.

Игра леоны прыгает


3. Спрайт-анимация – момент, когда жизнь на мгновение вручена леонам



Моушн бега леоны – это спрайт-лист из 6 кадров, как на следующем изображении.

(※ Рекомендуется вставить изображение спрайта в блог)

В JS спрайт обрезается и рисуется на каждом кадре:

const frameWidth = sprite.width / 6;
ctx.drawImage(
  sprite,
  frameIndex * frameWidth, 0, frameWidth, sprite.height,
  dino.x, dino.y, dino.width, dino.height
);

Просто меняя индекс кадра,
леона бегает мило.
В этот момент игра, наконец, «получила жизнь».

Aнимация на самом деле невероятно важна для разработки игр.


4. Случайное создание препятствий – "ключ к устранению монотонности"

Существует множество видов препятствий.

  • Оранжевый конус

  • Красный конус

  • Желтый конус

  • Мотоцикл (2 цвета)

  • Автомобили (2 типа)

  • Знаки (три типа)

Если они просто повторяются 1-2 раза, становится быстро скучно,
но если случайно перемешать несколько типов на разных интервалах, то поток игры значительно улучшится.

const key = OBSTACLE_KEYS[Math.random() * length];
const interval = 0.8 + Math.random() * 1.2;

Хотя это очень простой случайный алгоритм,
ощущение от игры кардинально изменяется.


5. Проверка на столкновение – самая сложная, но самая увлекательная часть

Проверка коллизий обычно называется «AABB-бокс-карточная коллизия».

if (dino.x < ob.x + ob.width &&
    dino.x + dino.width > ob.x &&
    dino.y < ob.y + ob.height &&
    dino.y + dino.height > ob.y) {
    // Столкновение!
}

Важными моментами здесь являются

  • Когда проверка слишком жесткая, игра становится раздражающей

  • Когда слишком мягкая, игра становится слишком легкой

Поэтому я уменьшил хитбоксы для леоны и препятствий на 10-15%, чтобы создать «приятный уровень сложности».

Эти небольшие настройки были довольно увлекательными.
Теперь я чуть больше понимаю, почему разработчики игр серьезно относятся к балансу сложности.


6. Система уровней на основе расстояния – 50 секунд для завершения

Этап 1 спроектирован так, чтобы занимать примерно 50 секунд.
Таким образом, предположим, что леона перемещается со скоростью 16 м/с.

Целевое расстояние: 800 м  
Скорость: 16 м/с → около 50 сек  

Это не только в числах, но и фактически на протяжении 30–40 игр,
«Достаточно ли длина, чтобы поиграть и захотеть сыграть снова?»
было непрерывным тестированием.

Это был маленький, но важный элемент, определяющий ощущения от игры.


7. Связь с сервером – рейтинг и хранение результатов

Как разработчик с бэкенд-системами, серверная часть была естественно настроена на Django + DRF.

  • Отправка результатов через POST

  • Проверка данных в сериализаторе

  • Неаутентифицированные пользователи записываются с guest_id

  • Лучшие результаты каждого пользователя управляются в таблице UserScore

  • ТОП-5 возвращается в виде HTML-фрагмента для замены через JS

Поэтому статус ТОП-5 рейтинга обновляется в реальном времени после завершения игры.

Интересно, что внутри игры на Canvas,
стабильность бэкенда и структурированный поток данных оказывают огромную помощь.

Это процесс, при котором данные изображений персонажа и диалогов упорядочиваются на бэкенде и отправляются в браузер.


8. Поддержка мобильных устройств – оказалось намного сложнее

Самым неожиданным препятствием вне создания веб-игры стало мобильное окружение.

  • Поддержка разрешения

  • Тач-движения

  • Соотношение холста

  • Производительность рендеринга

  • Коррекция скорости прокрутки фона

На настольных компьютерах все работает очень гладко,
но на мобильных устройствах возникают проблемы, такие как небольшая потеря кадров, отзывчивость на касания и вычисление размеров Canvas.

В конечном итоге я решил все эти вопросы,
в этом процессе были слова «Я восхищаюсь фронтенд-разработчиками...».


9. Заключительная часть – завершая техническую часть

Мне нравится бэкенд, поэтому я в основном разрабатываю API, и это первый раз, когда я делаю игру с дизайном на JS для веба. Я всегда как бы заставляю себя заниматься фронтендом, и особенно никогда не использовал HTML5 Canvas так глубоко.

Но благодаря этому проекту я смог узнать:

  • Веб, оказывается, намного мощнее, чем я думал,

  • JavaScript, который я когда-то ненавидел за его неопрятность, на самом деле интересный язык,

  • Разработка игр – это «сочетание мелких технологий».

Это был проект, начавшийся из фанатизма,
но несмотря на это, был весьма полезным опытом для роста как разработчика.


Анонс следующей части (Часть 3: Сторителлинг)

В следующем посте я планирую рассмотреть,
«Почему мы начинаем в Сибуя?», «Почему Токио Дôme?» и «Как мы определяли характер каждого участника?»
За кулисами создания мира/истории.