Всем доброго времени суток!
Давно читаю Пикабу и вот, когда нашелся настоящий повод, решил оформить свой первый пост :)
С 2020 года я занимаюсь разработкой игры под названием "Ensora" - это 2D-шутер с видом сбоку про путешествия на далёкой пустынной планете в поисках еды и ресурсов. Вдохновленный такими проектами как Fallout, The Outer Worlds и This War of Mine, я приступил к делу.
Для работы выбрал как мне показалось самый удобный игровой движок для 2D - GameMaker Studio 2 (GMS 2). В 3D разработку сразу лезть не стал, так как большого опыта за спиной у меня тогда не было. Решил, что лучше брать посильные задачи, чем в погоне за ультра графикой и реализмом бросить дело на полпути.
Спустя два года бессонных ночей, когда всякую художественную книгу мне полностью заменил мануал GMS 2, а вместо развлекательных ресурсов я переселился на его официальный форум, мне есть чем поделиться с людьми. Хотя я не удивлюсь, если в сюда зайдут профессиональные разработчики игр из игровых студий и станут нервно хохотать над данным постом.
Итак, несколько пунктов о том, как я решал поставленные перед собой задачи.
Как и любой другой геймер, я обожаю, когда в игре ты можешь выписать врагу хэдшот. Однако в обычной функции обнаружения столкновений движок не сообщает, какую часть ты задел.
Для реализации этой идеи пришлось создать "невидимые части тела" - объекты, такие же по размеру, как и часть тела. Например, невидимый для игрока круг летает там же, где находится голова врага. И именно столкновение пули с этим кругом фиксирует попадание в голову.
Кстати, игрока это тоже касается. Попадание тяжелого снаряда охранной пушки базы воспринимается очень больно.
Для понимания того, в какую часть тела ты попадаешь при выстреле во врага, также созданы разные "реакции на урон" - цель согнется пополам или откинет голову назад. Вряд ли Вы запутаетесь, куда именно попали.
Здесь я воспользовался встроенной в движок системой физики. Байк создается как три физических тела: корпус и два колеса. Они связываются пружинами, которые в зависимости от моих настроек отражают мягкость подвески. Можно гонять по скалам и не отбить задницу главного героя.
Как оказалось, нельзя просто нарисовать байк и два колеса, начать их крутить и получить хорошую анимацию. Нет. Сначала рисуем корпус, затем тормозной диск, колесо, суппорты, водителя. Детали должны быть независимы друг от друга и только так получается приятное глазу движение.
О, как много времени я провел в работе над этой адской вещью! Существует, пожалуй, бесчисленное множество вариантов того, как можно создать систему инвентаря и хранения игровых предметов.
Я же не придумал ничего лучше, чем создать ДВЕ сетки 5х4 клеток (как в крестиках-ноликах). В первой сетке я храню название предмета, который там лежит. Во второй сетке - количество этого предмета. И при любом перетягивании лута у меня происходит пересчет двух этих сеток. У ящиков, соответственно, по две такие же сетки 4х4. В игре, разумеется, всё видно так, словно в клетке лежит один объект с таким-то количеством.
Не самое элегантное решение, но оно работает. Что ж...
Для торговли, крафта, улучшений и прочего в игре создано более 50 предметов лута.
Здесь пришлось много импровизировать, поскольку игру я хотел сделать в разрешении FullHD, с большим количеством графики и анимации. Движок GMS 2 лучше подходит для создания пиксель-арт игр или небольших проектов высокого разрешения (хотя при большом желании в нем можно создавать даже 3D игры).
Сам по себе движок шустрый и поддерживает текстуры с разрешением вплоть до 8k, но когда в игровой комнате перемешивается большое количество графики на разных "слоях", начинаются проблемы с производительностью. У меня это горы, холмы, облака, корабли, здания, длинные анимации персонажа - всё вместе огромное количество спрайтов.
Здесь на помощь пришел существующий в GMS 2 инструмент разбивки текстур на группы. Я написал свой скрипт загрузки, а каждой игровой комнаты создал список нужных текстур. При загрузке уровня скрипт сравнивает 2 списка:
- список уже загруженных текстур в память;
- список текстур, которые потребуются в локации, куда пришел игрок.
Проще говоря, проверяется: что сейчас нужно в комнате? Лишнее выгружаем из памяти, нужное догружаем. Мы вернулись на корабль? Догружаем группу "ship". Мы покинули пустыню и она больше не отображается? Убираем из памяти группу "desert".
Да, это звучит так просто и логично, но сам по себе движок этого не сделает - он грузит всё, что добавлено в комнату налету и сохраняет в памяти до момента выхода из игры. Для меня этот скрипт был настоящей победой в борьбе за высокое разрешение. Всё стало плавно .
На этом пока я остановлюсь. В проекте еще множество других реализованных механик, но в первую очередь хотелось рассказать об этих четырех пунктах. Если Вам будет интересно я расскажу больше - об электронных системах, взломе, ракетах, космическом корабле и другом.
Проект в свет я всё еще не выпустил, однако планирую сделать это совсем скоро - в январе 2023 года.
Если Вам интересно попробовать эту игру - добавляйте её свой список желаемого!
Спасибо за внимание.