Все заметки

Как я делал игру на новогодний конкурс

Идея

Я люблю смотреть игровые стримы. Обычно я смотрю их на фоне когда работаю если задача не требует глубокой концентрации или когда занимаюсь своими пет проектами, чтобы сделать процесс более непринужденным и внушить себе, что я уже отдыхаю, а не работаю. Смотрю буквально пару человек, чаще всего стримера с ником WELOVEGAMES, а зовут его Денис.

В конце ноября на одном из стримов Дениса я услышал, что он планирует устроить несколько новогодних конкурсов. Один из них - конкурс рисунков по новогодней тематике с отсылками на канал стримера. Я сразу подумал, что было бы здорово сделать вместо рисунка небольшую игру. Пусть она и пойдет мимо конкурса, зато примажусь к общему мероприятию, да и в игру поиграют, может быть даже прямо на стриме.

Я решил сделать квест в котором стримеру нужно подготовиться к новогодней трансляции: нарядить елку, повесить гирлянду и возможно запастить едой. В качестве сеттинга я выбрал пост-апокалиптическое убежище из игр серии Fallout, поскольку Денис является давним поклонником изометрических игр этой серии.

Fallout 1
Fallout 1

Планируем фронт работ

На разработку у меня был месяц, нужно было реализовать основные механики, задизайнить игровой мир и наполнить его задачами. Ну и конечно же нужно много рисовать: персонажа, предметы, помещения, декорации и интерфейс.

На очередной прогулке с собакой я составил следующий список задач:

  • перемещение персонажа
  • возможность собирать и использовать предметы, инвентарь
  • сохранение прогресса при перезагрузке страницы или переходах между уровнями
  • цепочки квестов, которые нужно выполнить в рамках игры
  • рисовать так много сколько успею

Когда план оказался перед глазами, я сильно запереживал, что времени у меня не хватит. Могло получиться так, что игра к дедлайну будет на половину недоделанной и такое будет стыдно показывать, но желание испытать себя было сильнее, поэтому я принялся за работу. Использовал каждый вечер после работы и все свободное время на выходных.

Первые шаги

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

Взаимодействие с объектами сцены я реализовал через коллизии. Отслеживая столкновения курсора и интерактивных объектов, я проверяю наличие компонента Interactable и смотрю на поле с действием, которое этот объект предполагает. Зная контекст, по клику мыши я отправляю соответствующее событие: переход в другую комнату, поднятие предмета и так далее.

Демо уровень
Персонажа временно взял из другой своей игры, остальное - заглушки в виде цветных прямоугольников и кружков

Чтобы подсказывать игроку, какое действие сейчас можно выполнить на клик, я планировал нарисовать разные варианты курсоров: руку чтобы подобрать предмет, стрелку или ботинок для перехода на другой экран, и так далее. В качестве временной заглушки я нарисовал одну пиксельную стрелку и покрасил ее в разные цвета. Забегая вперед, курсоры я нарисовать не успел, поэтому заглушка так и осталась в финальной версии.

Курсор
Курсор

Добавляем инвентарь

Для инвентаря я решил не делать отдельных модальных окон или выпадающих меню. Комнаты я планировал рисовать небольшие, поэтому на экране должно быть достаточно места чтобы поместилась панель инвентаря с журналом событий. Получится некая смесь интерфейса из Fallout и Братья Пилоты: по следам полосатого слона.

Братья Пилоты
Братья Пилоты

Для разных размеров экрана я предусмотрел разное количество ячеек для инвентаря, а для случаев когда предметов больше чем ячеек, есть стрелки “вперед”-“назад”.

Инвентарь
Добавил инвентарь и журнал событий, чтобы было где отобразить название предметов

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

Переходы между комнатами и сохранение прогресса

Комнаты я сделал отдельными уровнями, поэтому за раз на экране отображается только один, а переходы происходят по клику на дверь. Чтобы переходы не были такими резкими, добавил плавное затемнение экрана. Никаких красивых переходов между сценами у меня в движке нет, поэтому затемнение это обычный div с разными классами состояниями.

При переходе с уровня на уровень, движок не сохраняет своего состояния и все системы полностью сбрасываются. Это проблема, которую нужно будет решать отдельно, но а сейчас за неимением других опций я сложил все в один объект в window, c последующим отложенным сохранением в Local Storage. Туда попали последние координаты персонажа, список всех предметов и их текущих состояний, чтобы при перезапуске игры можно было восстановить последнее состояние. Сохранение происходит в определенным контрольных точках когда происходит хоть сколько-нибудь значимое событие: успешное взаимодействие с предметами или переход в другую комнату.

Переход между комнатами

Квесты

В качестве основных задач игры я выбрал три: собрать все новогодние игрушки и нарядить елку, повесить и зажечь гирлянду, и найти себе поесть.

Поиск игрушек это задача на исследование всех комнат, сбор предметов и последующее их применение на елке. Для разнообразия, я добавил объекты контейнеры, только открыв которые, можно собрать содержимое. Некоторые открываются просто так, некоторые требуют соблюдения определенных условий. К примеру, деревянный ящик можно открыть только после использования на нем монтировки. Содержимое контейнеров заранее добавлено во все уровни и расставлено по позициям, а их скрытие реализовано посредством привязки к текущему состояния контейнера.

Сбор предметов

Квест гирлянды состоит из нескольких этапов. Сначала ее нужно найти, затем повесить и попробовать включить. Первая попытка оказывается провальной и в результате выбивает пробки. Далее нужно найти щиток и пройти мини-игру, выполненную в стиле старой ПК игры про Гарри Поттера. По клику на щиток открывается отдельная сцена на которой отображается контур в виде молнии, который игрок должен успеть достаточно ровно обвести за ограниченное время. Контур состоит из множества круглых коллайдеров с помощью которых отслеживается точность обводки.

Нарисованный контур отображается на отдельном холсте канваса, решение буквально в несколько строчек

Последняя задача - достать еду. Ее я также выполнил в стиле отдельной мини-игры, где игрок должен вовремя перепрыгивать препятствия. Для активации игры, нужно найти аркадный автомат производства известной в пустоши доставки пиццы. Игрок принимает на себя роль курьера, который должен, минуя все преграды, добраться до нашего убежища и привезти заказ. По выполнению квеста, игрок получает дополнительный предмет в инвентарь, который разблокирует финальное условие для завершения игры.

Квест с аркадным автоматом

Рисуем

На рисование у меня ушло полторы недели. Под конец года у меня оставался недогулянный отпуск, поэтому я взял недельку и фуллтайм только и делал, что рисовал. Самое сложное было рисовать отдельные сцены с электрическим щитком и аркадным автоматом, поскольку в таком большом разрешении я еще не рисовал и боялся, что ничего не получится. Ну и конечно же панель инвентаря была моим персональным боссом-вертолетом, не только из-за уровня детализации, но и из-за того, что я просто не знал как ее рисовать чтобы получилось красиво.

Финальная версия игры
Финальная версия игры

Результат

Игру я задеплоил через Netlify и ссылку отправил 25 числа в день дедлайна в той же гугло форме через которую собирались новогодние рисунки. Ну и чтобы избежать недопонимания сразу же написал в предложку в телеге с пояснениями. И стал ждать.

29 декабря Денис начал подводить итоги конкурсов и в самом конце показал мою игру в качестве бонуса. Неожиданно после открытия ссылки с игрой у стримера крашнулась трансляция на несколько минут и чат сразу же заподозрил наличие майнера, но трансляция ожила и дальше все прошло хорошо. Единственная проблема - почему-то текст в игре, который должен был быть темным, посветлел и на сцене с аркадным автоматом Денис долго не мог найти кнопку “Играть”. Мою игру тестировало человек 5 включая меня и ни у кого такой проблемы не было. Подозреваю, что проблема заключалась в расширении хрома, которое могло инвертировать цвет текста. Насколько я знаю, такие расширения могут ставить если очень хочется иметь темную тему на сайтах, где ее нет.

Денис запустил игру
Денис запустил игру

В целом можно сказать, что результатом я доволен. Игра понравилась Денису да и в чате я видел много комплиментов. На момент показа игры, трансляцию смотрело около 5 тыс. человек. Это была моя первая игра таких размеров. Пусть и геймплея в ней всего на 5 минут, но по количеству графики и фич это самое крупное, что я когда-либо делал. Кто знает, может быть в следующем году я решусь повторить нечто подобное, только уже чтобы геймплея было хотя бы на час.

Спасибо что уделили внимание моей статье и с наступающим вас новым годом!

С новым годом