Игра доступна по ссылке
Профессор Мяуриций, гений в области кото-науки, всегда мечтал о простом способе транспортировки ценностей. Его последнее изобретение, "Монетопорт", должно было решить эту задачу. Но во время тестового запуска произошел взрыв энергии, разбросавший все монеты по причудливым и опасным мирам. Теперь, с вашей помощью, Мяуриций должен восстановить порядок и доказать, что даже самые гениальные умы иногда совершают ошибки!
Brainoid - это аркада-статегия, в которой вам предстоит решить загадки уровней и собрать все монеты.
В мире Brainoid ученый кот, профессор Мяуриций, изобрел портативное устройство для телепортации монет. Но что-то пошло не так! Монеты разлетелись по лабиринтам загадочных уровней, и теперь Мяурицию нужно их собрать! Помогите ему, управляя платформой и направляя кота, чтобы он вернул все монеты и исправил свою ошибку!
Можно как установить игру локально, так и задеплоить её, чтобы играть вместе с друзьями и соревноваться по скорости прохождения!
Для запуска сервера с Базой данных необходимо установить Deno согласно инструкции.
В склонированном репозитории убедитесь, что в файле config.json флаг
enable_kv_database выставлен на true:
"enable_kv_database": trueЗапустить сервер можно через run.sh или run.bat скрипт.
Если вы не видите необходимости в таблице рекордов, то вы можете развернуть локальный сервер вообще без установки каких-либо зависимостей.
В таком случае кнопка "Сохранить результат" будет отключена, а лидерборды будут отсутствовать.
Во-первых, убедитесь, что в склонированном репозитории, в файле config.json,
флаг enable_kv_database выставлен на false:
"enable_kv_database": falseТеперь достаточно развернуть локальный хост.
Лично автор использовал для этого Python-модуль http.server:
python -m http.server 8000 --bind 127.0.0.1Для деплоя вы можете сделать форк
исходного репозитория и добавить
проект в систему Deno. В качестве entrypoint-файла
выберите server.ts корневого каталога.
Разработка сайта велась с абсолютного нуля.
Игра может закончиться победой или поражением. Результат игрока будет зафиксирован в таблице рекордов только в том случае, если он собрал все монеты на уровне. Если же игрок потерял все жизни и не собрал все монеты, уровень считается непройденным, и результат, естественно, не будет записан в таблицу.
Во время разработки использовался линтер от Deno.
Были проведены размещение сайта на Deno Deploy и интеграция с KV-базой данных.
Серверная часть располагается в entrypoint-скрипте server.ts.
В игре реализована система таблиц лидеров, по одной для каждого уровня. Каждая таблица отображает имя пользователя, время прохождения уровня и время установления этого результата. Пользователи могут сортировать таблицу по любому столбцу в возрастающем или убывающем порядке. Также можно ограничить количество отображаемых результатов.
Ранее автор имел опыт в разработке игр. Архитектура кода построена следующим образом:
Основным управляющим элементом является GameInstance — экземпляр игры, который
сопровождает клиента на протяжении всей игровой сессии, начиная с главного меню.
GameInstance управляет состоянием игры, которое может принимать одно из
следующих значений:
| State | Desc |
|---|---|
| Pending | Начальное состояние игры, загрузка игровых ассетов |
| Main menu | Главное меню |
| Leaderboard | Таблица лидеров с результатами игроков |
| About | Окно "About" |
| Select level | Окно выбора уровня для игры |
| Playing | Состояние активного игрового процесса |
| Game results | Состояние победы/поражения |
Все константы игры вынесены в отдельный файл scripts/constants.js. Этот файл
позволяет настраивать различные аспекты игры, такие как:
- Физика (Physics): Параметры, определяющие физическое поведение объектов в игре.
- Игровой процесс (Game Process): Настройки, влияющие на логику и правила игры.
- Усиления (Boosters): Характеристики различных усилений, доступных игроку.
- Режим отладки: Включение режима отладки позволяет визуализировать ray-casting для отладки взаимодействия объектов (подробнее об этом ниже).
Все игровые ресурсы (изображения, звуки и т.д.) и данные об уровнях хранятся в
файле scripts/assets.js. Разделение логики игры и данных об уровнях делает
игру легко расширяемой. Добавление новых уровней не представляет собой сложной
задачи и обычно занимает всего несколько минут (экспорт уровня и добавление его
в файл scripts/assets.js).
Уровни создаются в программе Tiles. Процесс создания уровня выглядит следующим
образом:
- Создайте тайлсет размером тайлов 16x16 пикселей на основе изображения
dev/tileset_v4.png. - Создайте уровень, используя созданный тайлсет.
- Экспортируйте уровень в формат JSON, который представляет собой список номеров тайлов.
- Используйте скрипт
dev/level_encoder.pyдля кодирования полученного списка номеров тайлов. Это уменьшит размер данных уровня для оптимизации. - Добавьте уровень в константу
LEVELSскриптаscripts/assets.js.
Во время игры отрисовкой уровня занимается класс Level в файле
scripts/level.js. При инициализации уровня данные уровня декодируются и на их
основе создаются игровые сущности. Класс Level также отвечает за обновление
состояния этих сущностей и их отрисовку на экране.
Система коллизий является важной частью проекта. Для имитации движения и
обработки столкновений используется метод raycasting, который часто встречается
в современных играх со сложной геометрией. Суть его в том, что каждое обновление
движения игрока сводится к проверке: "Столкнется ли игрок с каким-либо объектом
в течение заданного промежутка времени? И если да, то как он должен
среагировать?" Во время движения просчитываются несколько отрезков (лучей),
исходящих из прямой, ортогональной движению, и направленных параллельно этому
движению. Количество лучей, определяющее точность проверки коллизий, задается
константой RAYS_PER_RAD в файле scripts/constants.js. При необходимости это
значение можно изменить (главное - не перестараться :D ). Для каждого луча
вычисляется параметр, определяющий точку столкновения с ближайшим объектом.
Минимальное значение этого параметра указывает на первое столкновение, которое и
обрабатывается: определяется, с чем столкнулся игрок, и вычисляется вектор
отскока или иное действие.
Автором работы приходится студент 1 курса МФТИ Савельев Александр. Проект сделан в рамках итоговой аттестации курса "Фронтенд. Продвинутый уровень".
Всё аудио сопровождение заимствовано из интернета:
- a_BeautifulRuinSummerSalt
- a_BeautifulDays
- a_mainmenu
- a_CoolMorning
- a_HopeOfSpring
- a_BoosterApply, a_CoinCollect из GeometryDash SubZero