NFS на Godot Engine
Игра разрабатывалась на движке Godot v3.5.3.
В игре всего пять типов гонок: спринт, круг, на время, дрифт, на скорость. Каждая гонка допускает только определенный класс авто или привод.
Помимо гонок, есть радары скорости, дуэли с другими гонщиками и сторонняя работа от мафии или полиция. Мафия предлагает вам угнать машину, а полиция просит помочь остановить нарушителя скорости. Иногда с вами может связаться дилер подержанных автомобилей и сообщить, что у него появился новый ассортимент по низкой цене.
Игровой процесс примерно таков: проходишь гонки на одном классе авто, сражаешься с боссом, открываешь новый район города и получаешь машину босса, участвуешь в гонках в другом классе авто. Цикл продолжается, пока не доберешься до главного злодея.
Боты (ИИ)
Оказалось, это непросто - делать перемещение автомобиля в виртуальном пространстве, нежели перемещение человека. Автомобиль имеет инерцию, характеристики разгона и торможения, сцепление с дорогой на разных скоростях и т. д. По сути, вам нужно запрограммировать пилота, который бы действовал на упреждение, анализируя сложность трассы.
Первой мысль было использовать NavigationMesh (встроенная нода в движке). Он сообщает объекту, по чему можно перемещаться, а по чему нельзя. Представьте, что это коллизия, наложенная поверх дороги. Чем детальнее эта коллизия, тем больше ресурсов она потребляет для вычислений.
Но есть проблема: дорожное полотно очень большое, поэтому использование NavigationMesh беспощадно много съедает ресурсов. Особенно это непозволительно, если игра работает в браузере или на телефоне. Масло в огонь подливает количество гонщиков, для которых нужно обрабатывать данные. Короче говоря, fps падает до плинтуса. Решено было использовать RayCast-ы.
Рейкасты меняют свою ориентацию и длину в зависимости от скорости автомобиля, угла поворота колес, расстояния до точки интереса и так далее. Эти рейкасты определяют расстояние до препятствия (стены) и, беря во внимание параметры машины, дают сигналы нашему условному пилоту, как действовать на повороте, с какой скоростью ехать, как сильно поворачивать рулем и где стоит притормозить.
Есть еще один параметр в гонках, которому подчиняются боты. Если бот отстает или опережает игрока, его мощность двигателя начинает изменяться. Игроку будет сложно оторваться от соперника сильно вперед или будет шанс опередить соперника, если где-то была совершена ошибка. Если вы участвуете в гонке на самом топовом авто в своем классе, шансы на проигрыш мизерные. В другом случае, если игрок на самом слабом автомобиле, будет постоянная борьба за лидерство.
Когда я тестировал игру, я всегда брал самые слабые машины, и в 30% случаев мне не удавалось выиграть. Очень часто были моменты, где я обгонял соперника на самом финише. Так же, чем дальше игрок продвигается по сюжету, тем сильнее становятся соперники.
Этот параметр (чит, простыми словами), критически необходим, поскольку у вас никогда не будет шансов выиграть гонку на авто с мощностью 200 л.с., против авто мощностью в 300 л.с. В обратном случае, вы будете ехать всегда впереди и зевать от скуки.
Гонки (трассы)
Трасса стоится из точек, по которым едете вы и ваши соперники. Для удобства город "разукрашен" нодами Label, которые пронумерованы.
Точки расставлены так, чтобы ботам было легче проходить повороты. Эти точки также послужили для спавна полиции, заграждений и других гонщиков.
Оптимизация
В Godot есть система частиц, но эта система не поддерживается GLES2 (рендеринг на основе OpenGL), а только GLES3. Конкретно эта игра строится на GLES2. Обусловлено оптимизацией и поддержкой мобильных устройств.
Тогда можно сделать такую простую вещь - взял цилиндр, натянул на него текстуру дождя, поместил в центр камеры и зациклил падение дождя (тянуть вниз координаты UV цилиндра). Так же текстура растягивается тем больше, чем быстрее едет машина игрока, создавая эффект скорости.
Источники освещения сведены к минимуму. Днем один источник света - солнце; ночью - 2 фары автомобиля игрока. Для ботов используются простые спрайты, имитирующие свет фар. Никаких теней.
Интересным образом состоит дорожный фонарь. На карте примерно 300 дорожных фонарей и светофоров вместе взятых, и было бы большим допущение использовать на них источник света в ночное время суток.
Конечно, есть выход - просто под фонарем разместить полупрозрачный спрайт, имитирующий освещенность дороги. Но для 300 объектов делать это очень долго... А если представить, что вам нужно эти фонари переставлять в ходе разработки игры, то это еще больше работы. Я прибег к не хитрому способу и сделал автоматизацию этого процесса без прямого вмешательства.
Как и в случае с ботами, прикрепил к фонарям такие же рейкасты. При старте игры эти рейкасты узнают точку соприкосновения с асфальтом и загружается спрайт света. Теперь можно расставлять фонари как вздумается, и система все просчитает за вас и нарисует освещение. После этого процесса рейкасты на фонарях удаляются.
Звук
Весь звук преобразован в OGG формат и с битрейтом 32kbps. В итоге музыка с продолжительностью 6 минут весит 1, 7 мегабайта. В общей сложности весь звук в игре занимает 1, 9 мегабайта памяти.
Звук для двигателя писался по туториалу из Ютуба. Вот так это выглядит в Секвенсере (программа для написания музыки):
А вот плагин на котором писались ноты (это стандартный плагин в FL Studio):
Звук движка состоит из двух бочек, которые немного отличаются по характеру звучания. Плюс немного сторонних эффектов и эквализация, что бы придать большего сходства со звуком мотора. Для каждого класса звук двигателя разный. Ко всему прочему для некоторых классов авто добавляется звук турбины или выхлопа.
Город и колеса
Город моделировал и пытался сэкономить на полигонах где только возможно, ужимал разрешение текстур и использовал по минимуму материалов. В целом удалось соблюсти баланс и модель города съела мало памяти. Вместе с текстурами вес города обошелся 8 Мб.
Коллизии города моделил в ручную. Брал за основу полигоны, где предположительно можно ездить, удалил все остальное и поднял края как можно выше, что бы не было возможности перелететь через коллизии.
Спасибо этим ребятам, VertexAsh и Russell_506, которые предоставили модели авто, а также Kentaro за музыку. Для того, чтобы билд весил еще меньше, пришлось повозиться с моделями машин и удалить ненужные полигоны или сократить их количество.
Самыми проблемными были колеса - они брали на себя больше всего треугольников. Поэтому заскринил полигональные колеса всех автомобилей, и эти скрины превратил в текстуры, которые потом легли на новое колесо.
Яндекс.Игры. Проблемы
Я проверял игру на работоспособность с использованием разных команд, и, понятное дело, что проверял на десктопной версии, а не на браузерной. Я проходил игру по нескольку раз, и все отлично работало, но игра настолько комплексная и сложная получилась (в плане разработки), что я не смог углядеть за тем, как у меня написана логика для облачных сохранений.
Мне буквально надо было дополнить код двумя строчками, чтобы все работало корректно. Проблема раскрывается не сразу, а после того, как победишь второго босса. Конечно же, я об этом не догадывался и опубликовал игру.
Узнал я об этой проблеме по отзывам к игре. Но вот прикол - отзывы модерировались и появились спустя НЕДЕЛЮ. Обновил игру и исправил сохранения. Но все равно обидно, что так поздно.
На этом все
NFS с графикой PS1 готов. Отлично подойдет для вашего браузера или смартфона.
Надеюсь, что-то прикольное вы узнали, как и я (например, что можно таким интересным способом записать звук двигателя или провернуть такой прием с дождем).
Godot engine
Буква "а":
- Я, что, для тебя шутка какая-то?
В своё время на пиоатсктх дисках в джевелепродавался мод на Сан Андреас - Токийский дрифт. Очень похоже.
Шикарная работа проделана, респект
Комментарий недоступен
Хорошо сделано! А какой итоговый вес у игры получился ? Насколько удобно делать веб игры на Godot?
35Мб (22Мб zip архив). Очень удобно, но только на 3 версии, у 4 есть проблемы в web. Вроде какое-то обновление для 4-ки вышло и оно вроде правит траблы для web билдов (сам не проверял)