Учимся делать 2D-игры с нуля
Курсы и туториалы по созданию двумерных игр — вторая статья из цикла «Разработка».
Автор: Дмитрий Старокожев. Начал программировать на пятом курсе университета, влюбился в Objective-C и разработку под iOS, после чего попал в Pixonic. Работает ведущим разработчиком на проекте War Robots, а в свободное время преподаёт.
Вероятно, в ближайшее время кто-то из читателей этого цикла статей напишет первую строчку кода своего будущего прототипа. Потому что с движком мы уже определились и переходим к практике.
Учить программированию в одной статье нет смысла. К тому же, руководств в интернете множество. Многие наверняка будут делать свои первые прототипы в 2D — на этой теме и сконцентрируемся сегодня.
Если вы решили делать сразу в 3D, не спешите закрывать страницу — знания всё равно пригодятся. Приступим.
2D. Звучит олдскульно, правда? В наши дни разработка двумерных игр приобретает какой-то особый шарм. Чувствуешь себя ценителем, которому открылась недоступная другим истина. Но одного чувства прекрасного недостаточно — у разработки в 2D есть множество нюансов.
Очевидно, что главная особенность двухмерных игр — отсутствие третьего измерения. Как определить, кто ближе к зрителю: машина, куст или огромный боевой робот? Чтобы решить эту проблему, во всех 2D-движках предусмотрен механизм сортировки спрайтов — то есть двумерных графических объектов — по оси Z. Он может называться Z-order или Sorting Layers — в любом случае, с его помощью можно перемещать объекты со слоя на слой.
Другими словами, проблема уже решена за нас. Можно не тратить силы на изобретение велосипеда, а обратить свое внимание на особенности конкретных движков и жанров.
Для разработки прототипа звуки и анимация в большинстве случаев не так важны. Но нужно понимать, что работа с ними в 2D значительно отличается от 3D. В трёхмерном мире анимация скелетная: у каждой модели есть «скелет» (rig). Двигая его участки, разработчик анимирует модель.
А в 2D анимация создаётся покадрово: нужно создать атлас изображений, чтобы они стали последовательностью кадров анимации (sprite sheet). Уолт Дисней всё делал кистью и роллером, и это были шедевры (с). Этим же способом можно создавать очень красивых рисованных персонажей. Как в Cuphead, которая разрабатывалась на Unity.
А вот со звуком в 2D всё проще. Если при отрисовке мира отсутствие третьего измерения накладывает ограничения, то работа со звуком, наоборот, упрощается. Не нужно учитывать расстояние от слушателя (персонажа в игре) до источника звука — слушателем всегда будет выступать сам игрок.
Но нужна ли вообще прототипу музыка? Не думаю, что можно дать однозначный ответ (как и с анимацией). Давайте посмотрим на Hidden Folks. Это не просто 2D-игра, а настоящее произведение искусства.
Весь звук в Hidden Folks состоит из странных похрюкиваний и притопываний её разработчика, что само по себе USP — уникальное торговое предложение игры. Каждое прикосновение к экрану смартфона заставляет улыбнуться. Ладно, если запись похрюкиваний вам не подходит, в Asset Store Unity можно найти огромное количество платных и бесплатных ассетов для прототипа, а иногда и для релизной версии игры.
Рекомендации по выбору жанра можно прочитать в статье прошлого цикла. Здесь же мы будем говорить о некоторых путях, по которым можно пойти начинающему разработчику. Кому-то кажется, что вариантов не так много и обязательно надо закончить профильный университет с хорошей профессурой. Но если копнуть глубже, то обнаруживается бесконечный океан знаний, которые лежат прямо перед носом — остается только ухватиться за предоставленную интернетом возможность. Из доступного на ум сразу приходят:
- Туториалы.
- Онлайн-курсы.
Туториалы (tutorial) отличаются от курсов тем, что дают чёткий алгоритм действий для воспроизведения результата. Они не выходят за рамки поставленной задачи и отлично подходят, когда нужно сделать что-то конкретное, пока не пропал энтузиазм.
При первом поиске браузер выдаст миллионы ссылок с видеоуроками, статьями и готовыми проектами. Я подобрал несколько хороших вариантов по разным игровым жанрам. К тому же, среди других работ авторов можно найти ещё больше годного контента.
Есть YouTube-канал Brackeys. На нём — отличное вводное видео о том, с чего начать разработку платформера с плиточной графикой (tile based). Если сложно воспринимать на слух, можно включить английские субтитры.
Автор ролика приводит много примеров существующих проектов и объясняет, чем отличаются два различных подхода к созданию двумерных игр: sprite и tile based. В плейлистах канала можно найти староватый, но не потерявший актуальность туториал по созданию полноценного 2D-платформера с нуля — пошагово и со всем кодом, который можно повторить у себя и получить такой же результат.
На канале интересно практически каждое видео: даже если вы не планируете прямо сейчас врываться в разработку, стоит посмотреть хотя бы ролики о том, что нового появляется в Unity от версии к версии. Кстати, некоторые выпуски спонсирует сама Unity Technologies.
Еще один канал от энтузиаста — N3K EN. Можно найти ролики как по отдельным механикам или основам C # и Unity, так и плейлисты по разработке проектов с нуля. Например, создание прототипа Fruit Ninja за четыре часа в режиме реального времени со всем кодом.
Если учиться по видеороликам не очень нравится, есть хороший туториал в виде полноценной книги на английском языке. Она проведёт вас от установки Unity пятой версии до конца разработки двумерного скролл-шутера.
Наконец, есть официальные туториалы от Unity. Видео сопровождаются текстовыми описаниями и даже листингами программного кода. В процессе обучения создаётся roguelike RPG в tile based мире.
Чтобы в точности повторить результат, Unity сразу предлагает бесплатно скачать все ассеты этого проекта. Очень удобно и не надо ломать голову над тем, где взять симпатичные спрайты, а не разноцветные прямоугольники. В последнем ролике вы даже научитесь реализовывать управление персонажем под сенсорные экраны мобильных устройств.
Принимаясь за изучение нового туториала, не стоит волноваться о том, какую версию движка использует автор.
Unity везде ведёт себя похожим образом, а функции движка пятой версии доступны и в самой последней. Конечно, инструменты совершенствуются, но авторы обучающих материалов редко копают настолько глубоко, так что об этом можно не беспокоиться.
Если нужно подтянуть навыки программирования, то на арену выходит старый и проверенный игрок — Code School. Всё происходит прямо в интерфейсе сайта, который выглядит свежо и удобно. И не чувствуешь на затылке укоризненный взгляд Лобачевского со старого портрета над доской с графиком дежурств. Точно стоит обратить внимание хотя бы на бесплатные курсы, чтобы понять, насколько удобен такой формат обучения.
Есть официальные курсы от Unity, не надо далеко ходить. Кажется, что они и дальше готовы инвестировать в это направление (а после курсов можно еще получить сертификат).
У GeekBrains есть два отличных курса, разбитых по уровням сложности. Раз уж мы говорим о 2D-играх, нас интересует первый. Оба курса требуют определенной алгоритмической подготовки, программированию там не учат, только разработке на Unity.
Вы научитесь делать игры в 2D буквально с нуля: на первом уроке установите движок, а на восьмом уже запустите проект на Android. Вы даже можете заметить меня в списке преподавателей и случайно попасть на мой поток.
Хотите узнать, насколько глубока кроличья нора? Я падаю, стул тоже падает, здесь всё в 2D, и мне это очень нравится. Присоединяйтесь.
Наступает время самостоятельной работы. Пора писать код своей первой игры!
- Определите главную механику. Например, у Tower Defence это строительство башен и волны врагов.
- Найдите туториал по главной механике или по жанру в целом.
- Реализуйте главную механику на практике, используя примитивную графику.
О нюансах 3D-игр и туториалах для них поговорим отдельно — в следующей статье.
Создаем 2D игру на Python с библиотекой Arcade
Мы продолжаем делится с вами интересными найденными вещами про питончик. Сегодня вот решили разобраться с 2D играми. Это, конечно, немного попроще, чем то, что проходят у нас на курсе «Разработчик Python», но не менее интересно это уж точно.
Python — выдающийся язык для начинающих изучать программирование. Он также идеально подходит тем, кто хочет “просто взять и сделать”, а не тратить кучу времени на шаблонный код. Arcade — библиотека Python для создания 2D игр, с низким порогом вхождения, но очень функциональная в опытных руках. В этом статье я объясню, как начать использовать Python и Arcade для программирования игр.
Я начал разрабатывать на Arcade после преподавания азов библиотеки PyGame студентам. Я очно преподавал PyGames в течение почти 10 лет, а также разработал ProgramArcadeGames.com для обучения онлайн. PyGames отличная, но в какой-то момент я понял, что устал тратить время на оправдание багов, которые никогда не фиксятся.
Меня беспокоило преподавание таких вещей, как событийный цикл, которым уже почти не пользовались. И был целый раздел, в котором я объяснял, почему y-координаты повернуты в противоположном направлении. PyGames обновлялась редко и базировалась на старой библиотеке SDL 1, а не чем-то более современном вроде OpenGL. На светлое будущее я не рассчитывал.
В моих мечтах была простая и мощная библиотека, которая бы использовала новые фичи Python 3, например, декораторы и тайп-хинтинг. Ей оказалась Arcade. Посмотрим, как начать ее использовать.

Установка
Arcade, как и многие другие пакеты, доступна на PyPi, а значит, можно установить Arcade при помощи команды pip (или pipenv). Если Python уже установлен, скорее всего можно просто открыть командную строку Windows и написать:
А в Linux и MacOS:
Для более детализированной инструкции по установке, почитайте документацию по установке Arcade.
Простой рисунок
Вы можете открыть окно и нарисовать простой рисунок всего несколькими строчками кода. В качестве примера, нарисуем смайлик, как на картинке ниже:

Скрипт ниже показывает, как это сделать, используя команды рисования Arcade. Заметьте, что вам не обязательно знать, как использовать классы или определять функции. Программирование с быстрым визуальным фидбеком — хороший старт для тех, кто только учится.
Использование функций
Конечно, писать код в глобальном контексте — не лучший способ. К счастью, использование функций поможет улучшить ваш код. Ниже приведен пример того, как нарисовать елку в заданных координатах (x, y), используя функцию:
Для полного примера, посмотрите рисунок с функциями.

Более опытные программисты знают, что современные программы сначала загружают графическую информацию на видеокарту, а затем просят ее отрисовать batch-файлом. Arcade это поддерживает. Индивидуальная отрисовка 10000 прямоугольников занимает 0.8 секунды. Отрисовка того же количества батником займет менее 0.001 секунды.
Класс Window
Большие программы обычно базируются на классе Window или используют декораторы. Это позволяет программисту писать код, контролирующий отрисовку, обновление и обработку входных данных пользователя. Ниже приведен шаблон для программы с Window-основой.
В классе Window есть несколько методов, которые ваши программы могут переопределять для обеспечения функциональности. Вот список тех, что используются чаще всего:
- on_draw: Весь код для отрисовки экрана находится здесь.
- update: Весь код для перемещения объектов и отработки игровой логики находится здесь. Вызывается примерно 60 раз в секунду.
- on_key_press: Обрабатывает события при нажатии кнопки, например, движение персонажа.
- on_key_release: Обрабатывает события при отпускании кнопки, например, остановка персонажа.
- on_mouse_motion: Вызывается каждый раз при движении мышки.
- on_mouse_press: Вызывается при нажатии кнопки мыши.
- set_viewport: Эта функция используется в скроллерах, когда мир значительно больше, чем то что видно на одном экране. Вызов set_viewport позволяет программисту задать ту часть экрана, которая будет видна.
Спрайты
Спрайты — простой способ создания 2D bitmap объектов в Arcade. В нем есть методы, позволяющие с легкостью рисовать, перемещать и анимировать спрайты. Также можно использовать спрайты для отслеживания коллизий между объектами.
Создание спрайта
Создать инстанс Sprite класса Arcade очень легко. Программисту необходимо только название файла изображения, на котором будет основываться спрайт, и, опционально, число раз для увеличения или уменьшения изображения. Например:
Этот код создает спрайт, используя изображение coin_01.png. Картинка уменьшится до 20% от исходной.
Список спрайтов
Спрайты обычно организуются в списки. Они помогают упростить их управление. Спрайты в списке будут использовать OpenGl для групповой batch-отрисовки. Нижеприведенный код настраивает игру, где есть игрок и множество монет, которые игрок должен собрать. Мы используем два списка — один для игрока и один для монеток.
Мы с легкостью можем отрисовать все монетки в списке монеток:
Отслеживание коллизий спрайтов
Функция check_for_collision_with_list позволяет увидеть, если спрайт наталкивается на другой спрайт из списка. Используем ее, чтобы увидеть все монетки, с которыми пересекается спрайт игрока. Применив простой for- цикл, можно избавиться от монетки в игре и увеличить счет.
С полным примером можно ознакомиться в collect_coins.py.
Игровая физика
Во многих играх есть физика в том или ином виде. Самые простое, например, что top-down игры не позволяют игроку проходить сквозь стены. Платформеры добавляют сложности с гравитацией и движущимися платформами. Некоторые игры используют полноценные физические 2D движки с массами, трением, пружинами и тд.
Top-down игры

Для простых игр с видом сверху программе на Arcade необходим список стен (или чего-то подобного), через которые игрок не сможет проходить. Обычно я называю это wall_list. Затем создается физический движок в установочном коде класса Window:
player_sprite получает вектор движения с двумя атрибутами change_x и change_y. Просто пример использования — перемещение игрока с помощью клавиатуры.
Несмотря на то что этот код задает скорость игрока, он его не перемещает. Метод update в классе Window вызывает physics_engine.update(), что заставит игрока двигаться, но не через стены.
Пример полностью можно посмотреть в sprite_move_walls.py.
Платформеры

Переход к платформеру с видом сбоку достаточно прост. Программисту необходимо переключить физический движок на PhysicsEnginePlatformer и добавить гравитационную константу.
Для добавления тайлов и блоков, из которых будет состоять уровень, можно использовать программу вроде Tiled.
Учитесь на примере
Учиться на примере — один из лучших методов. В библиотеке Arcade есть большой список образцов программ, на которые можно ориентироваться при создании игры. Эти примеры раскрывают концепты игр, о которых спрашивали мои онлайн и оффлайн студенты в течение нескольких лет.
Запускать демки при установленной Arcade совсем не сложно. В начале программы каждого примера есть комментарий с командой, которую нужно ввести в командную строку для запуска этого примера. Например:
Как всегда ждём ваши комментарии и вопросы, которые можно оставить тут или зайти к Стасу на день открытых дверей.
Разработка 2D Fantasy Kingdom Sim с нуля. Часть 1: Язык, Движок, Редактор и Графический API
Небольшое введение, задачи прототипа, и разбор технологий которые мне видятся актуальными на 2022 год для основы 2D игры, если вы по каким-то причинам решили не использовать Unity, Unreal или Godot.
Технологии выбирал исходя из задач закончить прототип к ноябрю и личных предпочтений. Поскольку у меня нет опыта коммерчески успешных игр за плечами, то и не стоит воспринимать эту статью в качестве туториала о том как правильно делать игры
В своем первом посте на DTF пару дней назад я задал вопрос стоит ли здесь делиться подробностями разработки прототипа 2D симулятора в духе RimWorld и Majesty. Поскольку мой пост с одним лишь обрезанным скриншотом из прототипа и редактором кода набрал 30+ лайков, то я решил что это явный успех и принялся за написание статей. Иметь хоть и небольшую, на преданную аудиторию для вопросов, обмена опытом, и обратной связи на данном этапе это предел моих мечтаний
Мне 31 год и последние 10 лет я живу в США, сначала в ЛА и Сан Франциско, а в последние 2 года перебрался в Остин в Техасе. По своей основной специальности я программист и математик. Еще я в детстве 10 лет ходил в художественную школу и последние 6 лет занимался съемкой и цвето-кором в качестве хоби, так что есть некоторые навыки не только в техническом направлении. Тем не менее, после учебы я 8 лет проработал в нескольких FANG компаниях и мой основной опыт это программирование нагруженных бекендов и немного ML и роботов. В основном это примерно поровну Go, C++ и Rust. И немного Typescript и Python для интерфейсов и ML.
Хотя многие вещи из моего прошлого, особенно в robotics применимы в играх, собственно, в геймдеве у меня нет нормального опыта. Поэтому обратная связь это одна из причин почему я задумался начать писать на DTF. Играми я интересуюсь давно, еще в 16 лет в физмат лицее программировал поиск пути и простенькие 2d игры, но фуллтайм этим никогда не занимался. До этого момента я несколько раз пробовал писать свою игру в свободное, сначала на голом C++ и Vulkan, потом со своим знакомым на Unity, но как-то эти попытки затухали через несколько месяцев. В этот раз я решил взять что-то не настолько низкоуровневое как чистый Vulkan, и не настолько высокоуровневое как Unity и попробовать заново.
Как я уже писал выше игра будет в жанре симулятора фэнтезийного королевства, эдакая смесь RimWorld и Majesty. Вы управляете поселением в духе RimWorld, а ваши герои выполняют квесты истребляя опасных монстров, прокачивая уровни, зарабатывая опыт, лут и деньги на которые они покупают новое оружие, зелья и прочее. В этом, в целом, и будет основной геймлей. Больше деталей и подробностей буду раскрывать в следующих статьях.
Majesty и RimWorld – идейное вдохновление.
С технической точки зрения, прототип должен уметь делать следующее:
- Загружать мир, сущности и ассеты из файловой системы.
- Уметь рисовать спрайты, gizmos, поддерживать слои, 2D меши.
- 2D анимации через спрайты.
- Камера с ортографической проекцией, возможность менять масштаб.
- Уметь обрабатывать сотни сущностей, и взаимодействий: 1) Герои, фауна, монстры. 2) Собираемые ресурсы. 3) Динамические структуры –постройки, мебель, предметы мира. 4) Здоровье. 5) Подбираемые предметы. 6) Стеки и хранилища предметов. 7) Инвентарь героев. 8) Простая система прокачки – опыт и скиллы. 8) Экономика.
- Состояние сущностей – отдыхает, бодрствует, идет к цели и пр.
- Игровой AI который понимает цепочки подзадач для выполнения целей, может симулировать простые решения и взаимодействия. Собственно это один из основных фокусов игры. То, что, как по мне, сложнее всего концептуализировать и то что должно быть сделано наиболее интересным способом для развития игры: 1) Сбор и обработка ресурсов. 2) Строительство. 3) Ремесло. 4) Простая система квестов для героев. Квесты будут раздавать не-герои поселения, например – собери 10 ресурсов для кузница. 5) Ближний бой. 6) Система выживания – героям нужно что-то есть и отдыхать. 7) Базовая торговля – герои должны покупать предметы и оружие, платить за жилье и еду. 8) Поведение монстров и фауны.
- Свойства проходимости ландшафта, навигация, динамические препятствия. Много разных поисков пути. Как на карте, так и в пространстве задач.
- 2D коллизии.
- Календарь, смена дня и ночи.
- Базовое аудио.
- 2D интерфейс: окна, меню, drag & drop, hotkeys, рендер текста, выделение сущностей, задание целей, инвентарь и карточка сущностей (аватар, описание, состояние, статы), меню строительства, счетчики ресурсов экономики.
- Туман войны.
- Найм героев за ресурсы.
- 2D материалы, эффекты, тени и освещение, системы частиц.
- Водные пространства.
- События мира.
- Процедурная генерации мира. Может только самая базовая для автоматизации.
- Подземелья.
- Мультиплеера, но я буду держать его в уме и добавлю при первой возможности.
- Сюжет, диалоги, сценарии, сюжетные предметы, квесты, локации и персонажи. В прототипе только песочница с симуляцией.
- Магия и дальный бой.
- Симуляция социальных связей.
- Фракции. Пока что только один игрок.
- Биомы и бесконечный мир.
- Поддержки чего то кроме PC и Mac.
- Модификаторы и сложная система здоровья (повреждение частей тела и пр.).
- Партии и гильдии.
- Симуляция погоды.
- Нечеткое принятие решений через нейронные сети. Есть идея сделать что-то в духе идеи из Black & White 2 2006 года, где существа принимали решения через запрос к нейронной сети, без жестко прописанных правил. По сути игра должна генерировать набор всех решений для персонажей, а NN модель должна их ранжировать и выбирать наиболее подходящее исходя из состояния героя и его статов (собирать ресурсы, есть, спать, убегать от монстров, заниматься разведкой и пр.). Цель для NN может быть разной исходя из класса героя, условно для лучника это может быть разведать как можно больше окрестностей и не умереть, для паладина – убить самого опасного монстра рискуя собой. Если прототип с основной механикой будет готов к ноябрю, то это одна из основных идей которые я хочу попробовать используя gym от OpenAI.
Движок. В моем случае, изначально у меня не было процесса где я сидел и думал какая технологическая основа подойдет для реализации. У меня был опыт с Unity и низкоуровневыми графическими интерфейсами, но я все не решался начинать делать на этом игру. В какой-то момент я наткнулся на Bevy, изучил как работает ECS и иерархия сцены и у меня понемногу начали вырисовываться идеи как можно это все использовать. Bevy мне показался довольно простым и понятным эдаким набором деталей Лего из которых можно собрать что угодно. Легковесный, гибкий, не слишком навязывающий свой подход и имеющий достаточно низкую связанность компонентов. При этом нативный и довольно производительный. Хотя производительность пока для прототипа так важна. К тому же я уже давно хотел поработать над чем-то таким на расте. Поскольку игра в 2D, то и большинство фичей больших движков мне казались не сильно нужны. Хотя в Bevy есть, насколько я могу судить, довольно грамотно спроектированный Render Graph, GLTF, PBR. У движка есть примерно 3k пользователей на Reddit и примерно такой же онлайн в Дискорде. Из спонсоров имеется Embark, вполне серьезная студия из бывших авторов серии Battlefield (как я понял из их сайта, они довольно активно используют Rust в новых проектах). Bevy можно скомпилировать под Mac, Windows, Linux, iOS и Android. Здесь можно почитать про поддержку консолей. Из плюсов, для Bevy уже написано несколько хороших плагинов для интеграции физики, инспектора сцены, UI, конечных автоматов и прочего.
Также, Bevy может компилироваться в WASM, поэтому простенькие примеры можно запускать прямо в браузере поддерживающем WebGPU или WebGL:
Графический API. Следущий переломный момент для меня наступил когда я посмотрел лекцию по WGPU. Тогда я понял что это именно те инструменты которые я искал и начал эксперименты. До этого у меня было представление что WebGPU это стандарт для веба. Оказывается это не совсем так. Несколько лет назад стандарт задумывался разработчиками браузеров именно как низкоуровневая альтернатива WebGL. Насколько я понял над WebGPU работают именно разработчики браузеров, и он никак не связан с Kronos. Изначально, библиотека WGPU создавалась для реализации стандарта WebGPU в FireFox, но позже Mozilla и Google стали поставлять свои реализации этого стандарта для нативных языков отдельно от браузера. У Google свой аналог WGPU называющийся Dawn, и в целом устроенный похожим образом, но реализованный на C++. По сути WGPU это очень тонкая низкоуровневая надстройка над графическими API вроде Vulkan, Metal и DX12 написаная на Расте с заголовками под Си. Вам дается есть очень явный доступ к графическим девайсам – очереди, пулы, буферы команд, дескрипторы, графические и вычислительные пайплайны, примитивы для синхронизации и вот это все. По сложности WGPU где-то посередине между Metal и DX12. Это почти 1-в-1 копия подхода низкоуровневых графических API, из отличий в нем упрощена работа с памятью, и требуется немного меньше кода. Главный плюс WGPU по это кроссплатформенность. В зависимости от системы (mac, pc, ios, android) можно указать разный backend – Vulkan, dx12 или metal. В расте многие библиотеки, в том числе bevy, поддерживают вывод через WGPU, поэтому их ресурсы можно переиспользовать как аттачменты в одном пайплайне без трансфера через CPU.
В WGPU пока нет фичей последних поколений графических ускорителей типа умного апкскейла, ускорения рейтрейсинга и прямой загрузки ресурсов из файловой системы в память память графического ускорителя. В качестве языка шейдеров можно использовать WGSL или GLSL которые будут транслироваться в SPRIV или MSL в зависимости от системы. Насколько я понял, главный разработчик WGPU до этого работал над графическим пайплайном в RDR2. Также автор WGPU довольно активно контрибьютил в Bevy.
Редактор мира. Следующий этап был поиск редактора мира чтобы не приходилось работать над картой через редактирование текста. Поскольку в Bevy редактор пока находится на стадии обсуждений, то пришлось искать что-то на стороне. Насколько я понял для 2D игр есть два популярных варианта – Tiled и LDTK (разработчик – студия работавшая над Dead Cells). Я выбрал последний, для моих задач его должно в основном хватать, но в целом они довольно похожи. Идея в том что вы загружаете в редактор свои тайлсеты, создаете из них карту с помощью сеток с разными слоями и затем добавляете сущности на этой карте. Для сущностей можно указывать свои кастомные свойства – примитивы (числа, строки, массивы), другие сущности, места и пути на карте и прочее. После этого карту можно импортировать в JSON файл и загрузить в свою игру. Для Раста уже написан свой парсер LDTK. Добавить парсер в ассет менеджер Bevy заняло примерно 30 минут. Распарсенный файл LDTK затем указывается как ресурс в системе которая собирает мир игры на старте. Эта система обходит ресурс LDTK, слой за слоем собирает карту из спрайтов, просчитывает данные для навигации и спавнит сущности с заданными параметрами. В целом LDTK в Bevy пока что оставляет приятные впечатления.
Для автоматизации в LDTK можно создать свои правила как которые будут выбирать нужные тайлы для точек соприкосновения разных поверхностей. Из минусов – пока что нет какой-то явной поддержки анимаций.
Язык программирования. Думаю будет не лишним упомянуть язык Rust. Язык в целом очень похож на последние итерации C++, особенно в семантике. В расте нет явной поддержки ООП, в этом он в чем по похож на Go, только вместо интерфейсов здесь типажи. Из главных отличий от других языков – borrow-checker который помогает не допускать некорректного доступа к общим ресурсам, и в основном предотвращает многие классы ошибок памяти и много-поточности. Если отбросить субъективные аспекты (которые по-моему крайне важны если вы – соло-разработчик), то Раст сопоставим с Си и Си++ по производительности (также rustc использует один бекэнд с clang – LLVM), добавляет в исполняемый файл минимум рантайма и не использует сборщик мусора. Для меня огромным плюсом также является cargo, в отличие от Си++ и Си, в Расте намного удобнее управлять зависимостями проекта. Также в отличие от Си и Си++ для раста есть только одна реализация и один компилятор под все платформы что облегчает портирование. На этом сайте собраны библиотеки на Расте которые могут быть полезны при разработки игр: arewegameyet. rs.
Собственно на этих четырех технологиях я начал разработку проекта несколько месяцев назад. Думаю на этом пока закончить первую статью. Если будет достаточный интерес к таким материалам, на следующей неделе я напишу про базовый сетап для Bevy и то как устроена загрузка мира из LDTK, ресурсы и ECS. План на следующие несколько месяцев примерно такой:
- Возможности Bevy, LDTK и загрузка ресурсов и ECS.
- 2D Пайплайн, шейдеры, отладка шейдеров, и спрайты.
- Навигация и поиск пути на карте.
- Взаимодействия сущностей через ECS, сбор ресурсов, цепочки задач.
Буду рад обратной связи. Дайте знать насколько глубоко нужно раскрывать тему. Больше или наоборот меньше технических деталей? Спасибо!
Вторая часть здесь:
Первую статью на позапрошлой неделе я посвятил выбору основных технологий для разработки 2D симулятора фэнтезийного королевства в духе RimWorld и Majesty и обрисовал общие *технические* задачи моего прототипа (т.е. не геймплейные, но с оглядкой на геймплей).
Читать интересно, но мне кажется больший акцент на процессе принятия решений (в т.ч. технических) было бы интереснее читать, чем про сами детали реализации.
Несколько заметок по поводу затеи в целом:
— Ментальность. Специалисту трудно выйти из зоны комфорта, когда нужно решать управленческие задачи. Когда в руках привычный молоток — видишь вокруг только гвозди. Программировать — привычно, понятно и интересно. А делать интересную игру — непонятно, непривычно и страшно (вдруг идея окажется неинтересной). В итоге, спустя месяцы выясняется, что лестница, на которую с таким энтузиазмом забирались, была приставлена не к той стене и получается, в лучшем случае, технологическая демка, но не игра. Outer Colony, как пример.
— Определиться с целью: хобби или коммерческая разработка. Если планируете выпустить демо в обозримом будущем и в перспективе — зарабатывать, то примеряйте на себя роль гейм-дизайнера \ продюсера в первую очередь.
— Начинать с геймплея. Почитайте про MDA framework, это задаст правильный настрой. Игроку важен игровой опыт (aesthetics в MDA), а технологии — это лишь инструменты для его создания. То, что вы перечислили — это пока набор механик, без привязки к опыту. Лично я так и не понял из двух статей: 1) в чем именно будет геймплей игры, 2) чем он будет значительно лучше референсов. На кладбище игр полно проектов с эпитафией "хотели сделать как референс". Например, Super Combat Fighter.
— Планы на демку — слишком оптимистичные, на полную версию — нереалистичные. По демке — если у вас по каждой задаче расписаны детали, вплоть до структур данных, алгоритмов и формул, то мб успеете к ноябрю впритык. По полной версии — fuzzy logic, NN — это возведение времени разработки в квадрат. Мультиплеер — в куб. Напрмер, в Project Zomboid два выделенных чувака (+аутсорсеры с недавнего времени) пилят вменяемый мультиплеер уже несколько лет и все не допилят.
Резюмируя, я бы рекомендовал вам переключиться в режим гейм-дизайнера, определить в чем будет геймплей, какой критичный функционал для него нужен (и вырезать все некритичное, например: анимацию, камеру, физику, аудио, меню), реализовать критичные механики максимально просто и быстро (в ущерб качеству \ технологиям, т.к. это прототип на выброс. Скажем, вместо GOAP — использовать FSM или decision tree на if’ках; вместо Astar сразу телепортировать в position) и выдать на растерзание толпе, чтобы проверить интересность идеи игры. А обратная связь от игроков уже подскажет, куда двигаться дальше.
Создание 2D-игры
Прежде чем создавать 2D-игру, необходимо определиться с перспективой игры и художественным стилем.
Чтобы создать 2D-игру, настройте свой проект Unity, а затем ознакомьтесь с соответствующими понятиями в следующем порядке:
Основы
Игровые объекты Фундаментальный объект в сценах Unity, который может представлять персонажей, реквизит , пейзажи, камеры, путевые точки и многое другое. Функциональность GameObject определяется прикрепленными к нему компонентами. Подробнее
См. в Словарь — это основные объекты в Unity, представляющие персонажей, реквизит, декорации, и более. Каждый объект в вашей игре является GameObject.
GameObjects представляют элементы в вашей игре; пространство, в котором вы размещаете их для создания уровня, называется сценой Сцена содержит окружение и меню вашей игры. Думайте о каждом уникальном файле сцены как об уникальном уровне. В каждой сцене вы размещаете свое окружение, препятствия и декорации, по сути проектируя и создавая свою игру по частям. Подробнее
См. в Словарь . Сцены в Unity всегда 3D; когда вы создаете 2D-игру в Unity, вы обычно предпочитаете игнорировать третье измерение (ось Z), но вы также можете использовать его в особых случаях, например при создании 2,5D-игр.
Поведение GameObjects определяется функциональными блоками, называемыми компонентами. Следующие компоненты имеют основополагающее значение для 2D-игр:
Transform: компонент Transform компонент Transform определяет положение, вращение и масштаб каждого объекта в сцене. Каждый GameObject имеет Transform. Подробнее
См. в Словарь определяет положение, вращение и масштаб каждого игрового объекта в сцена. У каждого GameObject есть компонент Transform.
Визуализатор спрайтов Компонент, позволяющий отображать изображения как спрайты для использования как в 2D, так и в 3D сценах. Подробнее
См. в Словаре : компонент Sprite Renderer визуализирует Sprite и управляет его внешним видом. в сцене.
Камеры Компонент, создающий изображение конкретная точка зрения в вашей сцене. Вывод либо рисуется на экране, либо фиксируется в виде текстуры. Подробнее
См. в Словарь : устройства, которые захватывают и отображают мир для игрока. Пометка камеры как ортогональная удаляет всю перспективу из вида камеры. В основном это полезно для создания изометрических или 2D-игр.
2D-коллайдер: этот компонент определяет форму 2D-игрового объекта для физических столкновений. Столкновение происходит, когда физический движок обнаруживает, что коллайдеры двух игровых объектов соприкасаются или перекрываются, когда хотя бы один из них имеет компонент Rigidbody и находится в движении. Подробнее
См. в Словарь . См. раздел 2D-физика.
Компоненты представляют собой UI (пользовательский интерфейс). Позволяет пользователю взаимодействовать с вашим приложением. В настоящее время Unity поддерживает три системы пользовательского интерфейса. Подробнее
Смотреть в Словарь представления классов C#; вы можете использовать сценарии для изменения и взаимодействия с компонентами или для создания новых. Дополнительную информацию см. в разделе Сценарии.
Сценарий
Все 2D-игры нуждаются в скриптах фрагменте кода, позволяющем создавать ваши собственные Компоненты, запускайте игровые события, изменяйте свойства Компонентов с течением времени и реагируйте на ввод данных пользователем любым удобным для вас способом. Подробнее
См. в Словарь . Скрипты реагируют на действия игрока и организуют события в игровом процессе, когда они должны происходить.
Подробнее об использовании сценариев в Unity см. Обзор сценариев. Также см. курс Unity Learn Скрипты для начинающих.
Сценарии присоединяются к GameObjects, и любой создаваемый вами сценарий наследуется от класса MonoBehaviour.
Спрайты
Спрайты – это двухмерные графические объекты. Вы используете спрайты для всех типов 2D-игр. Например, вы можете импортировать изображение своего главного героя в виде спрайта.
Спрайт персонажа
Вы также можете использовать набор спрайтов для создания персонажа. Это позволяет вам лучше контролировать движение и анимацию ваших персонажей.
Несколько спрайтов, составляющих части персонажа, отображаемые в редакторе спрайтов.
Importing and setting up Sprites
Импортируйте свои спрайты с рекомендуемыми настройками Unity; см. Импорт и настройка спрайтов.
Визуализация спрайтов
Используйте компонент Sprite Renderer для визуализации спрайтов. Например, вы можете использовать средство визуализации спрайтов, чтобы изменить цвет и прозрачность спрайта.
Настройка цвета спрайта с помощью средства визуализации спрайтов
См. руководство по изучению Sprite Renderer. . Сортировка спрайтов. Организуя спрайты слоями, вы можете создать иллюзию глубины. Вы можете сортировать спрайты по множеству стратегий. Подробнее см. в разделе Сортировка спрайтов. Например, вы можете отсортировать спрайты по оси Y, чтобы спрайты, находящиеся выше, сортировались позади спрайтов, находящихся ниже, чтобы спрайты, находящиеся выше, отображались дальше, чем спрайты, находящиеся ниже.
Спрайты отсортированы по оси Y
Чтобы задать порядок наложения спрайтов, используйте Слои сортировки.
Чтобы группировать игровые объекты с помощью модулей визуализации спрайтов и управлять порядком, в котором они отображают свои спрайты, используйте группы сортировки.
Атлас спрайтов
Вы можете использовать Атлас спрайтов текстуру, состоящую из несколько небольших текстур. Также называется атласом текстуры, спрайтом изображения, листом спрайта или упакованной текстурой. Подробнее
См. в Словарь объединение нескольких текстур в одну комбинированную текстуру. Это оптимизирует вашу игру и экономит память. Например, вы можете добавить все свои спрайты, связанные с определенным персонажем или целью, в атлас спрайтов.
Атлас спрайтов
Создание игрового окружения
Дизайн окружения — это процесс создания игровых уровней и окружения. Вы можете комбинировать инструменты дизайна окружения в этом разделе так, как это лучше всего подходит для вашей игры; например, вы можете создать игру с видом сверху, используя только 9 фрагментов, или вы можете создать сайд-платформер с помощью Tilemap и SpriteShape.
9-нарезка
9-slicing – это двухмерная технология, позволяющая повторно использовать изображение разных размеров без необходимости подготовки нескольких ресурсов. Unity может динамически растягивать и размещать определенные части спрайта, чтобы один спрайт мог служить границей или фоном для элементов пользовательского интерфейса разных размеров. См. спрайты, разделенные на 9 частей.
Например, вы можете использовать 9-срезы, чтобы растянуть спрайт до нужной формы при создании 2D-уровня.
Спрайт из 9 фрагментов, разделенный на девять секций.
Карта листов
Игровой объект Tilemap GameObject, позволяющий быстро создавать двухмерные уровни с использованием тайлов и наложения сетки. Подробнее
Компонент See in Словарь представляет собой систему, которая хранит и обрабатывает активы Tile для создания 2D уровни. Используйте пакет 2D Tilemap Editor (устанавливается по умолчанию), чтобы использовать Tilemaps.
Например, карты листов можно использовать для рисования уровней с помощью плиток и инструментов кисти, а также для определения правил поведения плиток.
Окно Tile Palette, используемое для редактирования Tilemaps.
Дополнительные возможности 2D-карты листов
Чтобы добавить в проект дополнительные ресурсы Tilemap, установите 2D Tilemap Extras. Этот пакет содержит повторно используемые сценарии 2D и Tilemap Editor, которые вы можете использовать для своих собственных проектов. Вы можете настроить поведение скриптов для создания новых кистей, подходящих для разных сценариев.
Изометрические тайловые карты
Для игр с изометрической перспективой можно создавать изометрические карты листов.
Форма спрайта
Подобно инструменту векторного рисования, SpriteShape обеспечивает более гибкий способ создания более крупных спрайтов, таких как ландшафты и дорожки, выглядящие органично. См. профиль формы спрайта.
Путь, созданный в SpriteShape
Анимация персонажей
Существует три различных способа анимации 2D-персонажей:
| Тип 2D-анимации | Используется для |
|---|---|
| Frame-by-frame | Художественные причины, если вы хотите, чтобы ваша игра имела классический анимационный стиль. Покадровая анимация относительно ресурсоемка как для создания, так и для запуска. |
| Cutout | Плавная скелетная анимация, когда персонажи не требуют реалистичной артикуляции. |
| Skeletal | Плавная скелетная анимация, где спрайты изгибаются в соответствии со структурой костей. Используйте это, когда персонажи нуждаются в более органичном ощущении. |
Покадрово
Покадровая анимация основана на традиционной технике целл-анимации, при которой каждый момент анимации прорисовывается как отдельные изображения, которые воспроизводятся в быстрой последовательности, как перелистывание страниц в флипбуке.
Чтобы выполнить покадровую анимацию, следуйте Рабочий процесс покадровой анимации.
Покадровая анимация в редакторе спрайтов
Вырез
В вырезной анимации несколько спрайтов составляют тело персонажа, и каждая часть движется, создавая визуальный эффект движения всего персонажа. Этот стиль анимации похож на скелетную анимацию (см. ниже), за исключением того, что спрайты не изгибаются.
Анимация вырезания в редакторе спрайтов
Скелет
С помощью скелетной анимации вы сопоставляете спрайт или группу спрайтов со скелетом анимации. Вы можете создавать и определять кости анимации для персонажей и объектов, которые определяют, как они должны изгибаться и двигаться. Такой подход позволяет костям сгибаться и деформировать спрайты для более естественного стиля движения. Чтобы использовать скелетную анимацию, вам необходимо использовать пакет 2D Animation (установлен по умолчанию).
Для рабочего процесса 2D-анимации, включая руководство по работе с редактором костей, см. Документация по 2D-анимации.
Персонаж с костями в Bone Editor
Графика
В этом разделе описываются параметры графики при использовании универсального конвейера рендеринга серии операций, которые берут содержимое сцены и отображает их на экране. Unity позволяет вам выбирать из готовых конвейеров рендеринга или писать свои собственные. Подробнее
См. в Словарь (URP).
Освещение
Поскольку вы используете URP с 2D-рендерером, вы можете использовать компонент Light 2D для применения оптимизированного 2D-освещения к спрайтам. Подробнее см. в Введение в источники света. 2D.
Эти два изображения показывают одну и ту же сцену; на изображении слева 2D-освещение отключено, а на изображении справа 2D-освещение включено. С помощью 2D-освещения вы можете использовать одни и те же спрайты для создания различных погодных условий или настроений.
Чтобы настроить освещение:
Подготовьте спрайты к освещению. Подробнее см. в разделе Подготовка спрайтов к освещению .
Настройка карты нормалей Тип текстуры карты рельефа, который позволяет добавлять детали поверхности, такие как неровности, канавки и царапины на модели, которые отражают свет, как если бы они были представлены реальной геометрией.
Смотрите в Словарь и маскируйте текстуры. 2D Lights может взаимодействовать с картой нормалей и маскировать текстуры, связанные со спрайтами, для создания расширенных эффектов освещения, таких как наложение нормалей . См. раздел Настройка карты нормалей и текстур маски .
Создать игровой объект 2D Light; см. Свойства 2D-освещения.
Настройте ресурс данных 2D-рендерера; см. Настройка объекта 2D-рендерера.
(необязательно), если вы хотите применить эффекты 2D-освещения к пикселю наименьшей единице компьютерного изображения. Размер пикселя зависит от разрешения вашего экрана. Пиксельное освещение рассчитывается для каждого пикселя экрана. Подробнее
См. в Словарь арт-игре, см. 2D Pixel Perfect.
Чтобы определить форму и свойства, которые источник света использует для определения отбрасываемых им теней, используйте 2D-компонент Shadow Caster. Увеличьте интенсивность тени источника света выше нуля.
Интенсивность тени 0,5 в компоненте Shadow Caster 2D.
Улучшенный внешний вид
Системы частиц и постобработка Процесс, улучшающий внешний вид продукта за счет применения фильтров и эффектов до того, как изображение появится на экране. Вы можете использовать эффекты постобработки для имитации физических свойств камеры и пленки, например Bloom и Depth of Field. Дополнительная информация
См. в Словарь дополнительные инструменты, которые можно использовать для придания блеска ваша игра.
Системы частиц
Вы можете использовать системы частиц для создания динамических объектов, таких как огонь, дым или жидкости, в качестве альтернативы использованию спрайтов. Спрайты больше подходят для физических объектов. См. раздел Системы частиц Компонент, моделирующий текучие объекты, такие как жидкости, облака и пламя, с помощью создание и анимация большого количества небольших 2D-изображений в сцене. Подробнее
См. в Словарь .
Эффект огня, созданный с помощью Particle System и Shader Graph для 2D.
Постобработка
Вы можете использовать эффекты постобработки и полноэкранные эффекты, чтобы значительно улучшить внешний вид вашей игры. Например, вы можете использовать эти эффекты для имитации физических свойств камеры или пленки или для создания стилизованных визуальных эффектов.
В демо-версии Lost Crypt используются эффекты постобработки цветения и виньетки.
Физика 2D
Настройки Physics 2D определяют пределы точности физической симуляции в вашей 2D-игре. См. раздел 2D-физика.
В этом видео представлен обзор функций 2D-физики в Unity 2020.1. .
Чтобы узнать, как использовать двухмерный физический движок Unity систему, которая имитирует аспекты физических систем, чтобы объекты могли правильно ускоряться и подвергаться воздействию столкновений, гравитации и других сил. Подробнее
См. в Словарь , см. Учебное пособие по физике 2D.
Следующие инструменты 2D-физики полезны для 2D-игр.
Жесткое тело 2D
Жесткое тело Компонент, позволяющий воздействовать на игровой объект смоделированной гравитацией и другими силами. Подробнее
См. в Словарь 2D-компонент помещает GameObject под контроль физического движка. См. раздел Rigidbody 2D.
Компонент Rigidbody 2D
2D-коллайдер
Компоненты 2D-коллайдера определяют форму 2D-игрового объекта для физических столкновений. Вы также можете использовать Collider невидимую форму, которая используется для обработки физических столкновений объекта. Коллайдер не обязательно должен быть точно такой же формы, как сетка объекта — грубое приближение часто бывает более эффективным и неразличимым в игровом процессе. Подробнее
См. в Словарь 2D-компоненты для обнаружения ввода. Например, в мобильных играх вы можете использовать их для выбора спрайтов.
Типы Collider 2D, которые можно использовать с Rigidbody 2D:
Triggers
Когда вы устанавливаете 2D-коллайдер в качестве триггера (включив его свойство Is Trigger), он больше не ведет себя как физический объект и может пересекаться с другими коллайдерами, не вызывая столкновения. Вместо этого, когда коллайдер входит в свое пространство, Unity вызывает функцию OnTriggerEnter в скриптах Trigger GameObject.
Компонент Circle Collider 2D с выбранным параметром Is Trigger
2D Joints
Соединения соединяют игровые объекты вместе. Вы можете присоединять только двухмерные соединения Физический компонент, обеспечивающий динамическое соединение между компонентами Rigidbody, обычно допускающий некоторую степень движения, например шарнир . Подробнее
См. в Словарь игровые объекты, к которым прикреплен 2D-компонент Rigidbody, или к фиксированное положение в мировом пространстве. См. раздел 2D-соединения.
2D Effectors
Использовать двухмерные компоненты функциональную часть GameObject. GameObject может содержать любое количество компонентов. В Unity есть много встроенных компонентов, и вы можете создавать свои собственные, написав сценарии, которые наследуются от MonoBehaviour. Подробнее
См. в Словарь с помощью Collider 2D для управления силами физики в вашей сцене, когда коллайдеры GameObject соприкасаются друг с другом. См. раздел 2D-эффекторы.
Audio
Вы можете добавить в игру фоновую музыку и звуковые эффекты в Unity; см. Обзор аудио. Используйте стороннее программное обеспечение для создания своего аудио и импортируйте его в Unity с рекомендуемыми настройками.
User interface
Если вы хотите добавить в игру меню или справку, вам необходимо настроить пользовательский интерфейс. Чтобы настроить пользовательский интерфейс, используйте Unity UI.
Profiling, optimizing and testing a build
Profiling
Профилирование позволяет увидеть, насколько ресурсоемкими являются различные части вашей игры. Вы всегда должны профилировать свою игру на целевой платформе выпуска; см. Профилирование вашего приложения.
Оптимизация
После профилирования вы можете использовать результаты для повышения производительности и оптимизации. См. Понимание оптимизации в Unity.
Testing
Протестируйте свою игру и свой код с помощью Unity Test Framework; см. Среда тестирования Unity.
Окно запуска тестов
Publishing
Когда вы закончите свою игру, вы будете готовы ее опубликовать. См. раздел Публикация сборок.
Окно настроек сборки