Разработка Top-Down 2.5D игры на GDScript в Godot

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

1. Основы 2.5D в Godot: Настройка сцены, камеры и проекции

Основы 2.5D в Godot: Настройка сцены, камеры и проекции

Добро пожаловать в курс по разработке Top-Down 2.5D игры! Это первая статья, в которой мы заложим фундамент нашего проекта. Мы не просто создадим пустую сцену, а разберем, как работает восприятие пространства в играх, настроим «правильную» камеру и напишем первый скрипт на GDScript для управления проекцией.

Что такое 2.5D в контексте Godot?

Термин 2.5D может означать разные вещи. Иногда это 2D-спрайты в 3D-мире (как в Don't Starve или Ragnarok Online), иногда — 3D-модели с фиксированной камерой, имитирующей 2D (как в Hades или Diablo). В рамках этого курса мы сосредоточимся на втором подходе: использование 3D-движка Godot для создания игры с видом сверху, которая ощущается как классическая 2D RPG или экшен, но обладает всеми преимуществами трехмерной графики (тени, освещение, физика).

Ключевой элемент, который превращает 3D в 2.5D — это проекция камеры.

!Сравнение перспективной и ортогональной проекций камеры.

Настройка проекта

Перед тем как писать код, создадим проект:

  • Запустите Godot Engine.
  • Нажмите New Project.
  • Выберите рендерер. Для Top-Down игр, где важна четкость, отлично подходит Forward+ (для ПК) или Compatibility (если вы целитесь на старые устройства или веб). Мы выберем Forward+ для лучшего качества освещения.
  • Создание базовой сцены

    В Godot 4 любая сущность является узлом (Node). Для 3D-игры корневой узел сцены должен наследовать от Node3D.

  • Создайте новую сцену и выберите 3D Scene (создастся узел Node3D).
  • Переименуйте его в World.
  • Сохраните сцену как res://scenes/World.tscn (рекомендуется сразу создать папку scenes).
  • Чтобы нам было на что смотреть, добавим пол и куб:

  • Добавьте дочерний узел CSGBox3D к World. В инспекторе установите его размер (Size) на . Это будет наш пол.
  • Добавьте еще один CSGBox3D, поднимите его чуть выше пола. Это будет наш «игрок» или объект для теста.
  • Добавьте узел DirectionalLight3D и включите у него тени (Shadows -> Enabled), чтобы видеть объем.
  • Магия камеры: Перспектива против Ортогональности

    Теперь самое важное. Добавьте узел Camera3D в сцену. По умолчанию Godot использует перспективную проекцию.

    Перспективная проекция

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

    Ортогональная проекция

    В ортогональной проекции размер объекта не зависит от расстояния до камеры. Лучи зрения параллельны друг другу. Это создает тот самый «изометрический» или «классический» вид.

    Выберите узел Camera3D и в Инспекторе найдите свойство Projection. Измените его с Perspective на Orthographic.

    Теперь настроим размер видимой области. За это отвечает свойство Size (вместо FOV в перспективе). Установите Size равным 10 или 15. Чем меньше число, тем ближе «зум».

    Математика изометрии

    Чтобы получить «истинную» изометрию, камеру нужно повернуть под определенными углами. Часто разработчики ставят угол «на глаз» (например, -45 градусов по оси X), но давайте разберем математически идеальный угол.

    Для классической изометрии, где оси X, Y и Z проецируются под равными углами друг к другу на 2D-экране, угол наклона камеры по оси X должен быть равен:

    Где: * — искомый угол поворота камеры вокруг оси X. * — арксинус, обратная тригонометрическая функция. * — отношение, возникающее из геометрии куба (диагональ куба).

    Если вычислить это значение:

    Где: * — знак приблизительного равенства. * — угол в градусах.

    Также камеру нужно повернуть по оси Y на . Однако, для Top-Down игр часто используют более крутой угол, например, по X, чтобы лучше видеть переднюю часть персонажей.

    Пишем скрипт настройки камеры (GDScript)

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

  • Выберите узел Camera3D.
  • Нажмите иконку свитка (Attach Script).
  • Назовите его GameCamera.gd.
  • Вот код для базовой настройки камеры:

    Разбор кода

    * @export — делает переменную доступной в редакторе Godot. Вы можете менять angle_x и видеть результат при запуске. * projection = Camera3D.PROJECTION_ORTHOGONAL — жестко задает режим проекции. * rotation_degrees.x — вращение вокруг красной оси. Значение заставит камеру смотреть строго вниз (как на карте). Значение даст хороший обзор стен и персонажей.

    !Настройка свойств камеры в инспекторе Godot.

    Настройка окружения (WorldEnvironment)

    Чтобы картинка не выглядела серой и скучной, добавим узел WorldEnvironment.

  • Добавьте узел WorldEnvironment в сцену World.
  • В инспекторе создайте новый Environment.
  • Настройте Background Mode на Sky или Color.
  • В разделе Tonemap выберите Filmic — это сделает освещение более мягким и кинематографичным.
  • Включите SSAO (Screen Space Ambient Occlusion), если хотите добавить глубины в углах объектов. В ортогональной проекции это сильно улучшает восприятие объема.
  • Итог

    Мы создали базу для нашей игры: * Настроили 3D-сцену. * Разобрали разницу между перспективой и ортогональностью. * Применили математику для понимания угла обзора. * Написали скрипт на GDScript для управления параметрами камеры.

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

    2. Контроллер персонажа: Векторное движение и управление анимациями

    Контроллер персонажа: Векторное движение и управление анимациями

    В предыдущей статье мы настроили камеру и сцену, создав фундамент для нашей 2.5D игры. Теперь пришло время вдохнуть жизнь в этот мир. Пустая сцена с красивым освещением бесполезна без героя, который может её исследовать.

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

    Подготовка сцены персонажа

    В Godot 4 для создания движущихся объектов, взаимодействующих с физикой, идеально подходит узел CharacterBody3D. Он предоставляет встроенные методы для обработки коллизий (столкновений), что критически важно для RPG или экшен-игры.

    Создание узлов

  • Создайте новую сцену.
  • В качестве корневого узла выберите CharacterBody3D. Переименуйте его в Player.
  • Добавьте дочерний узел CollisionShape3D. Это физическая оболочка персонажа. В инспекторе выберите форму CapsuleShape3D.
  • Чтобы мы могли видеть персонажа, добавьте узел MeshInstance3D. В свойстве Mesh выберите CapsuleMesh (или загрузите простую 3D-модель, если она у вас есть).
  • Важно, чтобы визуальная часть (MeshInstance3D) и физическая (CollisionShape3D) совпадали по размерам и центрам.

    Векторная математика движения

    Самая частая ошибка новичков в Top-Down играх — это реализация движения напрямую через глобальные оси. Если вы нажмете «Вверх» (W), и персонаж просто пойдет по оси , это будет выглядеть нормально только если камера смотрит строго в спину или строго сверху без поворота.

    Однако в 2.5D (особенно в изометрии) камера повернута. Нажатие «Вверх» должно перемещать персонажа «вглубь» экрана, что с точки зрения игрового мира может быть диагональным движением.

    Нормализация вектора ввода

    Сначала получим ввод от игрока. Представим его как двумерный вектор , где — это ось «Влево/Вправо», а — «Вверх/Вниз».

    Если игрок зажмет одновременно «Вверх» и «Вправо», вектор будет равен . Длина такого вектора вычисляется по теореме Пифагора:

    Где — длина вектора, — значение по горизонтали, — значение по вертикали.

    Подставив единицы, получим:

    Где — знак приблизительного равенства, а — полученная длина.

    Это означает, что по диагонали персонаж будет двигаться на 41% быстрее, чем по прямой. Чтобы избежать этого, мы используем нормализацию — приведение вектора к длине 1 с сохранением направления.

    !Визуализация проблемы диагонального движения: без нормализации персонаж движется быстрее при нажатии двух кнопок.

    Преобразование координат: От экрана к миру

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

    Алгоритм следующий:

  • Получаем вектор ввода (2D).
  • Получаем базис (Basis) камеры — набор векторов, определяющих, куда она смотрит.
  • Умножаем ввод на базис камеры, игнорируя наклон камеры вверх/вниз (ось X камеры), так как мы ходим по плоскому полу.
  • Пишем скрипт управления (GDScript)

    Прикрепите скрипт к узлу Player. Вот полный код с подробными комментариями:

    Разбор ключевых моментов

    #### move_and_slide() Это метод класса CharacterBody3D. Он автоматически использует переменную velocity, перемещает тело, обрабатывает столкновения и позволяет персонажу скользить вдоль стен, вместо того чтобы намертво застревать при ударе. Нам не нужно умножать velocity на delta внутри этого метода, Godot делает это внутри движка.

    #### lerp_angle Обычная линейная интерполяция (lerp) плохо работает с углами. Например, переход от к через обычный lerp заставит персонажа сделать почти полный оборот назад. lerp_angle понимает, что и — это одно и то же, и выберет кратчайший путь.

    Формула линейной интерполяции выглядит так:

    Где — новое значение, — начальное значение, — конечное значение, а — коэффициент интерполяции от 0 до 1.

    Связываем сцены

    Теперь, когда скрипт готов, нужно соединить всё вместе.

  • Сохраните сцену Player.tscn.
  • Откройте главную сцену World.tscn (которую мы создали в прошлой статье).
  • Перетащите файл Player.tscn в сцену World, создав экземпляр игрока.
  • Выберите игрока в дереве сцены. В инспекторе вы увидите поле View Camera (благодаря @export).
  • Назначьте туда узел Camera3D, который находится на сцене World.
  • Запустите игру (F5). Теперь, независимо от того, как повернута ваша камера, нажатие «Вверх» будет двигать персонажа визуально вверх по экрану, а «Вправо» — вправо. Персонаж будет плавно поворачиваться в сторону движения.

    Подготовка к анимации

    Пока что наш персонаж — это просто капсула. Но мы уже заложили основу для анимации. В функции _rotate_character мы вращаем сам корневой узел. В будущем, когда мы добавим 3D-модель с костями (скелетную анимацию), нам нужно будет лишь вызывать проигрывание анимации «Бег», когда velocity.length() > 0, и «Покой», когда скорость близка к нулю.

    Если вы планируете использовать 2D-спрайты в 3D-мире (стиль Don't Starve), подход немного изменится: вместо вращения всего объекта, мы будем менять спрайты в зависимости от угла обзора камеры. Но векторное движение останется тем же.

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

    3. Построение мира: Y-sorting, TileMap и работа с глубиной

    Построение мира: Y-sorting, TileMap и работа с глубиной

    В предыдущих статьях мы создали сцену с ортогональной камерой и научили персонажа двигаться, используя векторную математику. Теперь перед нами стоит задача создать окружение. В 2D-играх для этого используются тайловые карты (TileMap) и сортировка по оси Y (Y-sorting). Но так как мы работаем в 3D-пространстве Godot (Node3D), правила меняются.

    В этой статье мы разберем, как адаптировать классические 2D-техники для 3D-мира, что такое GridMap и как работает глубина (Depth Buffer) вместо ручной сортировки спрайтов.

    Отличие 2D TileMap от 3D GridMap

    Если вы пришли из 2D-разработки, вы привыкли к узлу TileMap. Он позволяет «рисовать» уровень спрайтами по сетке. В 3D-движке Godot аналогом этого инструмента является GridMap.

    GridMap — это инструмент, который позволяет размещать 3D-сетки (meshes) в клеточной структуре. Вместо набора спрайтов (TileSet) он использует библиотеку мешей (MeshLibrary).

    Почему не TileMap?

    Технически вы можете добавить узел TileMap в 3D-сцену через SubViewport, но это сложно и неэффективно для физики и освещения. Использование нативных 3D-инструментов дает нам:

  • Автоматические тени: Стены и деревья будут отбрасывать реалистичные тени.
  • Физика: Коллизии обрабатываются движком автоматически.
  • Z-буфер: Нам не нужно вручную настраивать слои отрисовки.
  • Создание MeshLibrary

    Чтобы начать строить уровень, нам нужен «набор кистей». В Godot это называется MeshLibrary.

  • Создайте новую сцену (3D Scene).
  • Добавьте корневой узел Node3D.
  • Добавьте дочерние узлы MeshInstance3D для каждого типа блока (пол, стена, угол).
  • Для каждого меша добавьте StaticBody3D и CollisionShape3D, если вы хотите, чтобы игрок с ними сталкивался.
  • Нажмите Scene -> Export As... -> MeshLibrary и сохраните файл с расширением .tres (например, tiles.tres).
  • !Процесс конвертации сцены с моделями в ресурс MeshLibrary.

    Настройка GridMap

    Теперь вернемся в нашу основную сцену World.

  • Добавьте узел GridMap.
  • В инспекторе в поле Mesh Library загрузите созданный ранее tiles.tres.
  • Настройте Cell Size. Если ваши модели имеют размер метра, установите размер ячейки соответствующим образом.
  • Теперь, выбрав узел GridMap, вы увидите сетку в окне редактора и палитру блоков. Вы можете рисовать уровень левой кнопкой мыши, стирать правой и поворачивать блоки клавишами S/A/D/W (в режиме рисования).

    Проблема Y-sorting и её решение в 3D

    В 2D Top-Down играх существует проблема перекрытия. Если персонаж стоит «ниже» дерева на экране, он должен перекрывать ствол. Если «выше» — ствол должен перекрывать персонажа. В 2D это решается сортировкой по оси Y (Y-sort).

    В 3D этой проблемы не существует в привычном виде, потому что у нас есть ось Z (глубина).

    Как работает Z-буфер

    Когда видеокарта рисует кадр, она для каждого пикселя проверяет его расстояние до камеры. Это называется Depth Testing (тест глубины).

    Расстояние от точки в пространстве до плоскости камеры можно выразить упрощенной формулой:

    Где: * — итоговое расстояние (дистанция). * — координаты камеры. * — координаты объекта (пикселя). * — квадратный корень из суммы квадратов разностей координат.

    Движок автоматически рисует поверх то, у чего меньше. Поскольку наша камера наклонена и смещена по оси Z (как мы настроили в первой статье), объекты, которые находятся «ниже» на экране (ближе к нам по оси Z), будут отрисовываться поверх тех, что «выше».

    Таким образом, Z-ось в 3D выполняет роль Y-сортировки из 2D.

    Использование 2D-спрайтов в 3D (Sprite3D)

    Часто в 2.5D играх окружение делают трехмерным (стены, пол), а декорации (кусты, деревья, предметы) — плоскими спрайтами. Это придает игре особый шарм.

    Для этого используется узел Sprite3D.

    Настройка Billboard

    Если вы просто добавите спрайт дерева, он будет лежать плоско или стоять как картонка. При вращении камеры он станет невидимым (станет тонким). Чтобы спрайт всегда «смотрел» в камеру, используется свойство Billboard.

  • Добавьте Sprite3D.
  • Загрузите текстуру.
  • В разделе Flags найдите Billboard и установите Enabled или Y-Billboard.
  • * Enabled: Спрайт поворачивается за камерой по всем осям (хорошо для частиц). * Y-Billboard: Спрайт вращается только вокруг вертикальной оси (идеально для деревьев и персонажей).

    Проблема прозрачности и глубины

    Здесь кроется главный подводный камень. Полупрозрачные объекты в 3D (Transparent) сложно сортировать. Иногда вы можете увидеть, как дерево, стоящее сзади, рисуется поверх дерева спереди, или появляются странные артефакты.

    Чтобы получить четкую картинку в стиле Pixel Art и избежать ошибок сортировки, нужно использовать Alpha Scissor (Альфа-отсечение).

    В свойствах Sprite3D (раздел Flags):

  • Alpha Cut: Измените с Disabled на Discard.
  • Alpha Scissor Threshold: Регулирует порог, при котором пиксель считается прозрачным (обычно 0.5).
  • Это заставляет движок воспринимать спрайт не как «стекло», а как твердый объект сложной формы. Он начинает корректно записываться в Z-буфер и отбрасывать тени.

    !Разница между режимами прозрачности для Sprite3D.

    Практика: Собираем уровень

    Давайте объединим знания и создадим небольшую локацию.

    Шаг 1: Пол и стены

    Используйте GridMap, чтобы нарисовать пол размером клеток. Добавьте стены по периметру. Благодаря GridMap, вы можете быстро менять конфигурацию уровня, не двигая объекты вручную.

    Шаг 2: Декорации

    Добавьте несколько узлов Sprite3D с текстурами деревьев или колонн.
  • Включите Y-Billboard.
  • Включите Alpha Cut: Discard.
  • Разместите их на сцене.
  • Шаг 3: Проверка глубины

    Запустите сцену и побегайте персонажем вокруг спрайтов. Вы увидите, что когда персонаж находится «перед» спрайтом (координата Z персонажа больше координаты Z спрайта), он перекрывает спрайт. Когда он заходит за спрайт — спрайт перекрывает персонажа.

    Математически это работает так:

    Где: * — координата Z игрока. * — координата Z дерева. * — знак логического следствия («следовательно»). * — игрок находится ближе к камере (и перекрывает дерево).

    Итог

    Мы научились строить мир в 2.5D: * Использовали GridMap вместо TileMap для построения геометрии. * Поняли, что Y-сортировка в 3D заменяется естественной работой Z-буфера. * Разобрали настройку Sprite3D с режимом Billboard и Alpha Cut для корректного отображения 2D-объектов в 3D-мире.

    Теперь у нас есть персонаж и мир, по которому он может бегать. Но камера все еще статична. В следующей статье мы создадим систему слежения камеры за игроком, добавим плавность (smoothing) и реализуем механику «взгляда вперед» при движении.

    4. Геймплей: Программирование ИИ врагов и механики боя

    Геймплей: Программирование ИИ врагов и механики боя

    В предыдущих статьях мы создали мир, настроили камеру и научили персонажа передвигаться. Однако игра — это не просто прогулка по красивым декорациям. Игре нужен конфликт. В этой статье мы вдохнем жизнь в противников, создадим искусственный интеллект (ИИ) на основе навигации и реализуем базовую боевую систему с использованием Hitbox и Hurtbox.

    Подготовка сцены врага

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

  • Создайте новую сцену с корневым узлом CharacterBody3D. Назовите его Enemy.
  • Добавьте CollisionShape3D (капсула) и MeshInstance3D (для визуализации, например, красный цилиндр или модель монстра).
  • Важно: Для того чтобы враг мог обходить препятствия, нам понадобится специальный узел навигации. Добавьте к Enemy дочерний узел NavigationAgent3D.
  • NavigationAgent3D — это «мозг» поиска пути. Он не двигает персонажа сам, но рассчитывает, куда нужно сделать следующий шаг, чтобы добраться до цели, избегая стен.

    Настройка навигации в мире

    Прежде чем писать код, нужно объяснить движку, где можно ходить, а где нет. В Godot 4 для этого используется NavigationRegion3D.

  • Вернитесь в сцену World.
  • Создайте узел NavigationRegion3D.
  • Переместите ваш GridMap (или меши пола) внутрь этого узла NavigationRegion3D. Теперь пол является дочерним элементом региона навигации.
  • Выберите NavigationRegion3D и в инспекторе нажмите Bake NavigationMesh (вверху окна просмотра). Godot просканирует геометрию и создаст «карту проходимости».
  • Теперь, если вы добавите препятствия, вам нужно будет снова нажать Bake, чтобы враги узнали о них.

    Логика преследования (Математика и Код)

    Самый простой ИИ для Action-RPG — это преследователь. Враг должен знать, где находится игрок, и двигаться к нему.

    Вектор направления

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

    Где: * — искомый вектор направления. * — вектор позиции цели (игрока). * — вектор текущей позиции врага.

    Однако нам нужно только направление, а не расстояние, поэтому мы нормализуем этот вектор (приводим его длину к 1).

    Скрипт врага

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

    Добавьте игрока в группу "player" (вкладка Node -> Groups в инспекторе игрока).

    Вот код для Enemy.gd:

    gdscript func _physics_process(delta: float) -> void: if not player: return var dist = global_position.distance_to(player.global_position) if dist <= attack_range: # Логика атаки (например, включить анимацию удара) velocity = Vector3.ZERO # Остановиться else: # Логика преследования (код из раздела выше) nav_agent.target_position = player.global_position var next = nav_agent.get_next_path_position() velocity = global_position.direction_to(next) * speed move_and_slide() ``

    Итог

    Мы создали основу геймплея:

  • Навигация: Враги умно обходят стены благодаря NavigationRegion3D и NavigationAgent3D.
  • Бой: Разделили физику и урон, используя Area3D` (Hitbox/Hurtbox).
  • Логика: Враг принимает решения на основе расстояния до игрока.
  • Теперь у нас есть работающий прототип. В следующей, заключительной статье курса, мы создадим пользовательский интерфейс (UI), добавим полоску здоровья и меню, чтобы превратить наш прототип в полноценную игру.

    5. Финальная полировка: UI, звуки и экспорт проекта

    Финальная полировка: UI, звуки и экспорт проекта

    Поздравляю! Если вы следовали всем предыдущим статьям курса, у вас уже есть работающий прототип 2.5D игры: персонаж бегает по изометрическому миру, враги преследуют его, а боевая система позволяет наносить урон. Но пока это больше похоже на техническую демо-версию, чем на готовую игру.

    В этой финальной статье мы превратим прототип в полноценный продукт. Мы создадим пользовательский интерфейс (UI), добавим звуковое сопровождение, реализуем визуальные эффекты и разберем процесс экспорта игры для Windows и Web.

    Пользовательский интерфейс (UI)

    В 3D-играх (и в нашем 2.5D случае) интерфейс — это не просто картинки поверх экрана. Главная проблема — отделить интерфейс от игрового мира так, чтобы камера не влияла на него.

    Слой CanvasLayer

    Если вы просто добавите кнопку или полоску здоровья в сцену World, она будет висеть в пространстве, поворачиваться вместе с камерой и улетать за пределы экрана при движении персонажа. Чтобы интерфейс был «приклеен» к экрану монитора, используется узел CanvasLayer.

    CanvasLayer создает отдельный слой отрисовки, который всегда находится поверх игрового мира и не зависит от движения Camera3D.

    !Разделение слоев рендеринга: игровой мир и интерфейс.

    Создание HUD (Head-Up Display)

  • Создайте новую сцену и выберите корневой узел CanvasLayer. Назовите его HUD.
  • Добавьте дочерний узел Control. В настройках Layout выберите Full Rect, чтобы он занимал весь экран.
  • Добавьте ProgressBar или TextureProgressBar. Разместите его в левом верхнем углу.
  • Математика полоски здоровья

    ProgressBar работает в диапазоне от min_value до max_value. Чтобы корректно отображать здоровье, нам нужно вычислить процент заполнения или просто синхронизировать значения.

    Если мы хотим отобразить здоровье в процентах для текстовой метки, формула будет следующей:

    Где: * — итоговый процент здоровья (от 0 до 100). * — текущее здоровье персонажа. * — максимальное здоровье персонажа. * — умножение для перевода доли в проценты.

    Связь через Сигналы

    Никогда не обновляйте UI из скрипта игрока напрямую (например, get_node("HUD").value = health). Это создает жесткую зависимость. Используйте сигналы.

    В скрипте Player.gd добавьте сигнал:

    В скрипте HUD.gd:

    gdscript func show_damage_number(amount: int, position: Vector3): var label = Label3D.new() label.text = str(amount) label.position = position label.billboard = BaseMaterial3D.BILLBOARD_ENABLED # Чтобы смотрел в камеру get_parent().add_child(label)

    var tween = create_tween() # Анимируем подъем вверх на 1 метр за 0.5 секунды tween.tween_property(label, "position:y", position.y + 1.0, 0.5) # Параллельно делаем текст прозрачным tween.parallel().tween_property(label, "modulate:a", 0.0, 0.5) # Удаляем после завершения tween.tween_callback(label.queue_free) ``

    Этот код создает динамичную обратную связь, которая делает бой приятным.

    Экспорт проекта

    Когда игра готова, её нужно собрать в исполняемый файл (.exe) или HTML5 страницу.

    Шаг 1: Настройки проекта

    Перейдите в Project -> Project Settings.

  • Application -> Run -> Main Scene: Убедитесь, что выбрана ваша главная сцена (например, MainMenu.tscn или World.tscn).
  • Display -> Window: Установите желаемое разрешение (например, 1280x720) и режим растягивания (Stretch Mode: canvas_items или viewport). Для Pixel Art игр лучше использовать viewport.
  • Шаг 2: Загрузка шаблонов

    Godot не включает шаблоны экспорта по умолчанию, чтобы экономить место. Перейдите в Editor -> Manage Export Templates и нажмите Download and Install.

    Шаг 3: Создание пресета

  • Перейдите в Project -> Export.
  • Нажмите Add... и выберите платформу (например, Windows Desktop).
  • В настройках пресета обратите внимание на галочку Embed PCK. Если её включить, ресурсы игры будут «вшиты» в .exe файл. Если выключить — рядом будет лежать отдельный файл .pck`.
  • !Интерфейс меню экспорта проекта в Godot.

    Особенности Web-экспорта

    Для публикации на itch.io выберите пресет Web. * Важно: В Godot 4 Web-экспорт требует поддержки SharedArrayBuffer на сервере хостинга. На itch.io это включается галочкой «SharedArrayBuffer support» в настройках страницы игры. * Рендерер: Если вы используете Forward+, игра может не запуститься на мобильных браузерах. Для максимальной совместимости в Web лучше использовать режим рендеринга Compatibility (OpenGL 3).

    Заключение курса

    Мы прошли долгий путь:

  • Настроили изометрическую камеру и сцену.
  • Реализовали векторное движение персонажа.
  • Построили мир с помощью GridMap и навигации.
  • Создали умных врагов и боевую систему.
  • Добавили интерфейс, звук и собрали проект.
  • Теперь у вас есть фундамент. Вы можете расширять его: добавить инвентарь, диалоги, разные типы оружия или магию. Основы GDScript и архитектуры Godot, которые мы разобрали, универсальны. Удачи в разработке вашей игры мечты!