Создание 2D-игр на Python: Разработка top-down шутера на Ursina Engine

Изучите основы разработки 2D-игр на Python с помощью простого и интуитивно понятного движка Ursina Engine [habr.com](https://habr.com/ru/articles/898354/). В рамках курса мы сфокусируемся на базовой структуре, работе с классом Entity [habr.com](https://habr.com/ru/sandbox/252308/) и пошагово создадим динамичный 2D top-down шутер, не отвлекаясь на 3D-функционал [artean.ru](https://artean.ru/blog/web-development/razrabotka-igr-na-python-sozdanie-2d-i-3d-igr-pod-kljuch/).

1. Введение в Ursina Engine: Установка, базовая структура и инициализация окна

Введение в Ursina Engine: Установка, базовая структура и инициализация окна

Ursina Engine — это современный и легковесный игровой движок для языка программирования Python. Он построен поверх более мощного, но сложного в освоении фреймворка Panda3D. Главная философия инструмента заключается в максимальном упрощении процесса разработки и минимизации шаблонного кода. Разработчику не нужно писать десятки строк для вывода простого квадрата на экран — движок берет всю рутину на себя.

> Игровой движок — это базовая программная среда, предоставляющая разработчику готовые инструменты для рендеринга графики, обработки физики, звука и пользовательского ввода.

Хотя Ursina Engine изначально создавался с прицелом на 3D-графику, его архитектура отлично подходит для создания 2D-игр, таких как платформеры или top-down шутеры. В рамках этого курса мы полностью сфокусируемся на двухмерном пространстве.

Почему именно Ursina Engine?

В экосистеме Python существует несколько популярных библиотек для создания игр. Чтобы понять место Ursina Engine, сравним его с самым известным аналогом.

| Характеристика | Ursina Engine | Pygame | |---|---|---| | Базовая технология | 3D-движок (Panda3D) с поддержкой 2D | 2D-библиотека (обертка над SDL2) | | Объем кода | Минимальный (многое автоматизировано) | Большой (нужно вручную писать циклы отрисовки) | | Система координат | Центр экрана — это точка (0, 0) | Левый верхний угол — это точка (0, 0) | | Встроенный UI | Есть готовые кнопки, панели, текст | Отсутствует, нужно программировать с нуля |

Например, для создания окна, загрузки картинки и вывода ее на экран в Pygame потребуется около 20-25 строк кода. В Ursina Engine та же задача решается всего в 4 строки.

Установка движка

Для начала работы потребуется установленный интерпретатор Python версии 3.6 или выше. Установка движка производится через стандартный менеджер пакетов pip.

Откройте терминал или командную строку и введите следующую команду:

Процесс установки автоматически скачает сам движок, а также все необходимые зависимости, включая Panda3D и библиотеки для работы с изображениями и звуком.

Базовая структура проекта

Любая игра на Ursina Engine начинается с импорта библиотеки и создания главного объекта приложения. Рассмотрим минимальный жизнеспособный код:

Разберем этот код по шагам:

  • from ursina import — импортирует все базовые классы и функции движка. В контексте Ursina* это считается хорошей практикой, так как движок спроектирован для работы в едином глобальном пространстве имен.
  • app = Ursina() — создает экземпляр приложения, инициализирует графическое окно, настраивает аудиосистему и подготавливает внутренние компоненты.
  • app.run() — запускает бесконечный игровой цикл. С этого момента программа не завершится, пока пользователь не закроет окно.
  • Настройка игрового окна

    По умолчанию Ursina Engine открывает игру в полноэкранном режиме или в окне с рамками (в зависимости от операционной системы). Для разработки top-down шутера нам потребуется жестко задать параметры окна, чтобы контролировать видимую область.

    Все настройки окна хранятся в глобальном объекте window. Изменять их нужно строго после вызова Ursina(), но до вызова app.run().

    В этом примере мы отключили полноэкранный режим (fullscreen = False), вернули стандартные рамки операционной системы (borderless = False) и установили разрешение экрана 1280 на 720 пикселей. Свойство position указывает, в какой точке монитора появится окно при запуске (отступ 100 пикселей сверху и слева).

    Если ваш монитор имеет разрешение 1920x1080, то окно размером 1280x720 займет примерно 44% площади экрана, что очень удобно для отладки, так как рядом можно держать открытый редактор кода.

    Адаптация камеры для 2D-игры

    Поскольку под капотом Ursina работает в 3D-пространстве, по умолчанию используется перспективная камера (объекты вдалеке кажутся меньше). Для классической 2D-игры перспективу нужно отключить, переведя камеру в ортографический режим.

    В ортографической проекции размер объектов не зависит от их удаленности от камеры. Это критически важно для top-down шутера, где мы смотрим на поле боя строго сверху.

    Свойство fov (Field of View) в ортографическом режиме работает иначе, чем в 3D. Оно определяет, сколько игровых единиц помещается на экране по вертикали.

    Пусть . Это означает, что от нижнего края экрана до верхнего ровно 10 единиц расстояния. Если мы создадим игрового персонажа высотой в 1 единицу, он займет ровно десятую часть экрана по вертикали.

    !Схема системы координат 2D игры

    Система координат в Ursina Engine центрирована. Точка с координатами всегда находится ровно в центре экрана. Ось направлена вправо, а ось — вверх. Для 2D-игр координата обычно игнорируется или используется исключительно для сортировки слоев (чтобы определить, какой объект рисуется поверх другого).

    Игровой цикл и функция update

    Сердцем любой игры является игровой цикл. Это процесс, который повторяется десятки раз в секунду: он считывает нажатия клавиш, обновляет координаты объектов и рисует новый кадр на экране.

    В Ursina Engine вам не нужно писать цикл while True вручную. Достаточно создать функцию с именем update(). Движок автоматически найдет ее и будет вызывать каждый кадр.

    Важнейшим понятием в игровом цикле является дельта времени — время, прошедшее с момента отрисовки предыдущего кадра. В Ursina оно доступно через переменную time.dt.

    Время между кадрами вычисляется по формуле , где — количество кадров в секунду. Если игра работает со скоростью кадров в секунду, то секунд. Если компьютер слабый и выдает только кадров, то секунд.

    Умножение любых изменений (например, скорости перемещения пули) на time.dt гарантирует, что игра будет работать с одинаковой скоростью на компьютерах разной мощности. Если пуля летит со скоростью 10 единиц в секунду, мы будем прибавлять к ее позиции каждый кадр.

    Теперь у нас есть полностью настроенное окно и понимание того, как работает базовый цикл. Фундамент для нашего top-down шутера заложен.