В этой статье я покажу вам, как создать игру Tappy Plane (похожую на Flappy Bird) с помощью Unity!

Вот что мы собираемся строить:

Получить исходный код игры можно здесь на GitHub.

Что будем использовать:

  • UniRx — для реактивного программирования и для красивого и чистого разделения данных и представлений.
  • Активы Tappy Plane от Кенни.

Добавление повторяющегося фона и земли

Начнем с создания фона, который мы будем использовать в игре. Спрайт для фона Assets/Sprites/background.png .

Создание повторяющихся изображений

Компонент RepeatingBackground присоединен к компоненту Background, который содержит все сегменты фона как дочерние игровые объекты. Сначала мы инициализируем все сегменты повторяющегося фона в очередь в том порядке, в котором они появляются в сцене. Сегменты представляют собой одно и то же изображение, соединенное вместе и движущееся влево от экрана с определенной скоростью. Когда первый сегмент полностью покидает экран, мы отправляем его в конец очереди (чтобы он стал новым последним сегментом) и перемещаем его позицию на крайний правый сегмент экрана, но все еще соединенный с другими сегментами. Мы продолжаем делать это, пока игра не остановится. Делая это, мы создаем иллюзию бесконечного фона.

Вот что на самом деле происходит на сцене:

Это работает из-за того, как был разработан спрайт.

Делаем то же самое для земли, но с большей скоростью, так как она находится на переднем плане (спрайт Assets/Sprites/groundGrass.png)

Создание самолета

Мы будем использовать эти спрайты для самолета:

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

Обнаружение ввода игрока

В компоненте скрипта Plane мы получаем данные от игрока, чтобы заставить самолет прыгать. Когда пользователь щелкает левой кнопкой мыши или нажимает клавишу пробела, мы устанавливаем скорость в направлении Y. Это начальная скорость, с которой самолет теряет скорость из-за гравитации (мы прикрепили к самолету компонент Rigidbody 2D, чтобы включить физику). Игра завершится, когда игрок столкнется с препятствием, поэтому мы перестанем обнаруживать ввод, когда это произойдет, и самолет упадет на землю.

Создание препятствий

Мы используем эти два спрайта для создания препятствий:

Мы заставляем их двигаться вместе, делая их дочерними элементами одного и того же родителя Rock Grass в окне Hierarchy.

У нас есть игровой объект GameController (для реализации шаблона одноэлементного игрового менеджера) в сцене. К нему прикреплен скрипт GameController с сериализованным полем firstRockPair. Мы устанавливаем это поле на Rock Grass в редакторе Unity. Rock Grass — это первое препятствие, с которым игрок столкнется в игре, и это объект, который мы будем клонировать, чтобы создать больше препятствий.

Когда игра начинается, мы создаем клон firstRockPair и размещаем его на случайном расстоянии от firstRockPair. Через случайное количество секунд, в течение которых первый клон значительно сдвинулся влево, мы создаем еще один клон firstRockPair.

Обнаружение столкновений

Мы прикрепляем компонент Polygon Collider 2D к плоскости и к двум дочерним элементам Rock Grass, которые показывают верхний и нижний спрайты камней (rockGrass и rockGrassDown), чтобы включить обнаружение столкновений, которое мы обрабатываем в сценарии Plane:

На данный момент у нас уже есть полнофункциональная игра Tappy Plane!

Добавление подсчета очков

Мы создаем в сцене невидимый игровой объект и делаем его потомком Rock Grass. Мы помечаем этот объект как ScoreIncreaseTrigger. Размещаем его в сцене сразу за парой камней, чтобы при вызове функции OnTriggerExit2D для триггерного столкновения между самолетом и этим объектом это означало бы, что самолет успешно прошел через пару камней и таким образом увеличиваем игроков счет.

Индикатор очков

Вместо шрифта для отображения текущего счета игрока мы будем использовать следующие спрайты (по одному спрайту на каждую цифру счета):

Поэтому нам нужен пользовательский метод для обновления показанных спрайтов в соответствии со счетом компонента Score.

Мы храним Images для каждой цифры в списке. Эти изображения располагаются рядом в сцене. Итак, допустим, текущий счет равен 9. 9 имеет только 1 цифру, это означает, что у нас есть только одно изображение в списке. Что происходит, когда мы обновляем счет до 10? Ну, 10 имеет 2 цифры (1 и 0), поэтому мы обновляем спрайт первого изображения в нашем списке до спрайта, показывающего число 1. Затем мы создаем новое изображение в списке и устанавливаем его спрайт на спрайт, отображающий число 0.

Добавление звезд

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

SpawnStars() заставляет звезды в каждой звездной группе идти по пути полукруга. Каждая из звезд в группе вращается вокруг одной и той же точки под углом, зависящим от их положения в группе.

Когда самолет сталкивается со звездой, мы уничтожаем игровой объект звезды и увеличиваем количество звезд:

Последнее, что нам нужно сделать, это добавить индикатор количества звезд. Компонент StarCount просто определяет изменение количества звездочек и соответствующим образом обновляет текст индикатора в сцене. На этот раз мы использовали шрифт (KenVector Future), поэтому не будем использовать пользовательский метод обновления, как мы делали для индикатора очков. Нам просто нужно установить свойство text.

И это все! У нас запущен Tappy Plane (летает, прыгает?)!

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

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

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