Если первая часть была о том, «почему это было сделано»,
то вторая часть – о «как это было сделано».
Лично я чувствую себя гораздо комфортнее, когда работаю с бэкенд-системами, такими как Django, PostgreSQL, Redis и Docker при создании веб-приложений.
Но этот проект был в основном основан на чистом ванильном JS + HTML5 Canvas.
Технологии фронтенда, которые я обычно не углубляюсь, стали ключевыми в этой игре.
И, к моему удивлению…
это было невероятно увлекательно.
Это было техническим фактором, который заставил меня погрузиться в процесс.
Обычно я не «люблю» фронтенд-работу, это скорее «не люблю» – любовь к 豆柴の大群 сделала «неприятные дела» приятными.

1. HTML5 Canvas – мир, похожий на “живопись + анимация”
Суть MAME RUN!! – это HTML5 Canvas.
Это область, созданная на веб-странице, подобная «живописи», где мы создаем игру, рисуя пиксели прямо здесь.
Обычно веб-разработка выглядит следующим образом:
-
Создание кнопок (HTML)
-
Заливка цветом (CSS)
-
Добавление немного действия (JS)
Но для Canvas всё совершенно иначе.
Canvas – это структура, которая перерисовывается от 30 до 60 кадров в секунду.
С каждым кадром:
-
Стирает фон
-
Перерисовывает
-
Рисует персонажа
-
Рисует препятствия
-
Считает столкновения
-
Увеличивает счет
-
Резервирует следующий кадр
Это повторяется десятки раз в секунду.
Современные веб-браузеры невероятно мощные, как игровые движки.
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?» и «Как мы определяли характер каждого участника?»
За кулисами создания мира/истории.
Комментариев нет.