Язык программирования godot engine
Язык программирования godot engine
The game engine you waited for.
Godot provides a huge set of common tools, so you can just focus on making your game without reinventing the wheel.
Godot is completely free and open-source under the very permissive MIT license. No strings attached, no royalties, nothing. Your game is yours, down to the last line of engine code.
Godot 3.3 has arrived, with a focus on optimization and reliability
All Godot contributors are delighted to release our latest milestone today, Godot 3.3, after more than 7 months of development! This release was initially planned as a 3.2.4 update to the 3.2 branch.
A different way to make games
Innovative design
Big or small ideas adapt seamlessly to Godot’s node-based architecture, making your life easier.
Gorgeous 3D
Innovative 3D renderer design, which makes your art look great with minimal effort.
Beautiful 2D
Dedicated 2D engine that works in pixel coordinates, with plenty of built-in tools.
Easy to program
Object-oriented API with language options such as GDScript, C#, C++ and visual scripting.
Team-friendly
From architecture and tools to VCS integration, Godot is designed for everyone in your team.
Open Source
Truly open development: anyone who contributes to Godot benefits equally from others’ contributions.
Get involved
Join the community and help create a game engine that belongs to everybody.
If you know how to code, and enjoy fun and challenging problems, you can help by fixing bugs or creating cool new features.
Document
Documentation quality is essential in a game engine; help make it better by updating the API reference, writing new guides or submitting corrections.
Report
Found a problem with the engine? Don’t forget to report it so that developers can track it down.
Donate
You don’t need to be an engine developer to help Godot. Consider donating to speed up development and make Godot Engine even more awesome!
Godot, 1000 мелочей
Недавно открыл для себя Godot engine, опенсурсный игровой движок. Делюсь некоторыми приёмами и заметками, в основном из области 3д, кода или общих моментов.
У Godot в целом репутация скорее 2д движка, которое проработано довольно хорошо, но и не так давно появившиеся 3д возможности позволяют делать трёхмерные игры. Особенно если вы в состоянии оптимизировать какие-то вещи самостоятельно, не делаете слишком уж тяжёлую и комплексную игру, а также вас устраивают текущие варианты рендера. Ну или можете ждать будущих оптимизаций и появления vulkan.
«Из коробки» в движке есть некоторая физика, в том числе джоинты и колёсный транспорт. Нет встроенного редактора terrain, но можно воспользоваться плагином, импортировать из специализированных программ или просто как меш из 3д пакета. В последнем случае ради производительности придётся самостоятельно резать ландшафт на фрагменты-чанки, и скорее всего делать им отдельные меши под коллизии. Что касается мешей под форму коллизии ландшафта — чтобы не было визуальных нестыковок, нужно триангулировать модель во время экспорта из 3д пакета. Например, один из простейших способов это сделать в Blender — экспортировать меш в формате collada (.dae), там по дефолту стоит галочка triangulate.
Иногда модель из Blender придётся переворачивать на 180 градусов внутри Godot, поэтому не удивляйтесь если вашего terrain’a не видно — скорее всего он повёрнут нормалями не в ту сторону.
Godot практикует подход «всё есть сцена» и заточен под древовидную структуру элементов. На практике это означает, что новые объекты на уровень добавляются как ветки к уже существующим на нём узлам, их можно сворачивать в префабы и открывать отдельно, как будто это их отдельный маленький локальный мирок. Таким образом очень удобно редактировать всевозможные сохранённые составные объекты, единственный момент — если на вашем уровне был выставлен свет, то, допустим, зайдя внутрь персонажа, в его локальную сцену, вы этого освещения не увидите и настраивая его материалы не будете понимать как они смотрятся на свету. Эту проблему можно решать по разному, например, переключаясь в окно уровня и оценивая происходящие изменения с персонажем, после сохранения его сцены, там. Или просто временно бросить источник света внутрь префаба с персонажем.
Сцена с объектом theEnergy, который будет помещён на уровень для сбора игроком. В качестве основы используется узел Area, к которому прикреплена форма коллизии, а также сферический примитив, внутрь которого вложен ещё один.
Что касается языков, то если не рассматривать низкоуровневый способ, наиболее ходовые варианты — это скриптовые языки GDScript и C#, а также визуальный скриптинг для чего-то простого. GDScript лучше интегрирован в движок, имеет больше примеров, не требует запуска внешней среды, а в плане общей структуры тут будет происходить всё то же, что в варианте C# — объявление переменных, вызов функции инициализации, цикл процессов, цикл физических процессов и так далее. Так что выбор GDScript в качестве основного скриптового языка разработки имеет смысл. Пересаживаясь на местный C# получим разве что большую аккуратность и подробность записи, теряя в лаконичности, но усиливая разборчивость и контроль над ситуацией — фигурные скобочки вместо использования табуляции, отметки конца строки, более формальную типизацию.
Код, прикреплённый на вышеупомянутый объект (на языке GDScript). Заводится переменная идентификатор, значение которой можно будет выставить в редакторе, Далее одноразовая функция инициализации, в которой ничего особенного не происходит (и можно было её стереть). Далее описан метод-обработчик сигнала, который должен будет удалять объект.
Сигналы
Для обмена данными между узлами в Godot можно также воспользоваться иерархией, ведь объекты крепятся друг к другу, как ветки к дереву. Правда у этого подхода свои подводные камни, ведь в нашей игре иерархия может быть динамически изменяемой. К тому же обращение к иерархии в пределах одной сцены — это одно, а вот когда у тебя сцена внутри сцены внутри сцены, то с этим возникают некоторые сложности, хотя бы даже чисто в понимании происходящего.
Один из способов со всем этим управляться и не слишком привязываться именно к конкретной текущей иерархии — это сигналы. Какое-то количество общих сигналов уже предустановлено — можно заглянуть в панель сигналов объекта, чтобы прикрепить строку с обработкой получения одного из них в скрипт того же объекта или другого объекта со скриптом, в пределах сцены. Если же нужно сделать свой собственный сигнал, то делается это так:
Заводим сигнал
Излучаем его в том же скрипте при нажатии кнопки или других условиях
Всё с этим отлично, пока вам не потребовалось передавать сигналы из одной сцены в другую. Например, потому, что вы кодом собираете уровень из сцен и вам надо знать, когда нужно текущий уровень разрушить и, допустим, собрать следующий.
В этом случае можно прямо в момент конструирования уровня кодом прицепить обработчик сигнала на тот объект, который будет посылать сигнал в корневую сцену. Тем самым, мы, так сказать, заводим агента-шпиона в этой сгенерированной ветке и будем слушать, что он нам сообщит.
В момент сборки уровня находим на нём космический кораблик и цепляем к нему слушателя сигнала, указывая метод, в котором будем сообщения этого сигнала обрабатывать.
В сигнал можно также прикрепить какие-то переменные, что может быть довольно полезно. Например, вместо того чтобы заводить разные сигналы на объекте, мы можем обойтись одним, но будем отправлять его с разными параметрами и дополнительно обрабатывать при получении.
А вот и описание самого метода, который мы заводили выше. Получая сигнал он обрабатывает посланную с ним переменную.
Происходит событие и мы смотрим, есть ли у вошедшего в зону объекта нужный метод.
Метод есть, и он активируется, отправляя сигнал. Сам обладатель метода, кстати, не обязан иметь возможность вызывать эту свою функцию самостоятельно.
CSG-объекты
Один из полезных 3д инструментов в Godot — примитивы constructive solid geometry. Проще говоря это объекты, поддерживающие булевы операции — пересечение, исключение, объединение. Кроме набора примитивов есть универсальный CSG Mesh, в качестве формы для которого можно установить уже произвольный меш.
Пустышка CSG Combiner потребуется для использования в иерархии, чтобы управлять приоритетом применения операций, если в этом есть необходимость при сборе какой-то сложной конструкции.
Пара сфер, из которых вырезаны дочерние сферы.
Основное применение CSG — удобство и простота прототипирования статики уровня и каких-то его элементов. По факту можно сделать меш в 3д пакете, и повторить в нём те же самые результирующие формы, разве что этим надо будет заниматься вне игрового редактора.
Следующее применение статических CSG — имитация разрушаемости и повреждений. для этого требуется расставить CSG примитивы в режиме исключения, как дыры, «огрызки» и вмятины, а затем временно скрыть, включая видимость в нужный момент. Ограничение тут в том, что «повреждать» мы можем только поверхность CSG объекта, к тому же «повреждение» должно быть изначально прикреплено к нему как дочернее либо крепиться через код, как потомок. Зато такой вариант по гибкости настройки уже значительно выигрывает по сравнению с заготовленным в 3д-пакете разрушаемым объектом.
В мост встроены 3 цилиндра в режиме исключения. Пока они скрыты мост целый.
Если их включить, то вырезается исключаемая ими область.
Далее у нас идут CSG движущиеся. Через код, либо записанную анимацию. В целом через этот способ можно реализовывать какие-то эффекты, но очень желательно чтобы подобные анимации не крутились на сцене в цикле. Несколько анимированных CSG могут заметно посадить производительность, к тому же в Godot оптимизирует не все вещи, и если вы не вырубите анимированные CSG самостоятельно, то они будут продолжать расходовать производительность вне видимости камеры.
Тем не менее эффекты анимированных CSG уже сложно заменить решениями 3д пакета, поэтому вы можете быть заинтересованы именно в их использовании (по крайней мере, если не собираетесь рисовать продвинутое 3д через код). Главное найти им правильное применение, лучше всего их использовать точечно, в определённых местах, включая анимацию по триггеру. Как эффект открытия прохода или прочий разовый спецэффект. Естественно, чем проще форма CSG объектов — тем лучше. А основную вычислительную нагрузку они оказывают именно в процессе соприкосновения в движении, притом нет особой разницы, какой именно объект двигать относительно другого.
На видео есть момент где машинка падает сквозь дыру в мосту, когда анимированная CSG-капсула проходит через CSG Mesh с моделькой моста.
Мультимеш
Если нужно растиражировать какой-то меш в огромных количествах, например, разбросав камни или деревья по уровню, то здесь пригодится узел MultimeshInstance.
После добавления на сцену мультимешу нужно указать, по какому объекту рассыпать копии и что брать в качестве образца для клонов. Попутно можно выбрать размер клонов и их количество. Когда мультимеш «запечён», то он представляет собой множество клонов, а цели, которые он использовал для своей генерации, можно и удалить, если в них больше нет надобности.
Кнопка для выбора целей мультимеша появляется в окне редактора справа вверху, когда он выбран. Если её нажать, то выпадет это окошко с установками для генерации.
Здесь мы имеем два объекта добавленные в сцену как узлы MeshInstance. Далее левый объект мы расклонируем по правому.
Получаем мультимеш. В данной ситуации в настройках было выставлено 10000 клонов. Кстати, если бы их было 3-4 тысячи, то визуально результат не сильно бы отличался.
Устанавливаем Visible Instance в 500 и плотность заполнения резко снижается.
Разное
Управление в Годо можно настроить открыв пункт Проект в верхней панели редактора. Далее Настройки проекта, вкладка Список действий.
Можно посмотреть как называются дефолтные кнопки, чтобы знать по каким именам к ним обратиться через код. А также добавить свои собственные.
Например, для кнопки PgUP по дефолту установлено название «ui_page_up», и обработать её нажатие в коде можно написав следующую строчку в GDScript — if Input.is_action_pressed(«ui_page_up»):
Если требуется действие для однократного нажатия, то is_action_pressed нужно заменить на is_action_Just_pressed. Окончание нажатия — pressed меняется на released.
Если вам нужно анимировать мерцание материала то можно сделать это через самописный шейдер. Для этого в качестве материала объекта выбираем Новый ShaderMaterial
Далее в пустом поле выбираем VisualShader
Щелкаем на него, ниже редактора открывается визуальный редактор
Добавляем пару узлов, сначала Input — All — Time, затем Scalar — Common — ScalarFunc, выставив в её выпадающем списке, допустим, Sin. В принципе уже такая конструкция даст нечто вроде мерцания между чёрным и белым, но чтобы было получше, добавим ещё один узел Scalar — Common — ScalarFunc и выберем там Abs. Соединяем узлы между собой (обратите внимание, что нажимая на закрытый глаз у каждого узла можно открыть его и посмотреть как изменяется картинка на каждом этапе) и, подключаем к каналу Alpha, Emission или Albedo. Всё, наш объект теперь мерцает.
Естественно, это далеко не единственный способ, но один из очень простых вариантов. А если вы хотите чтобы мерцание было цветным, то вам нужно будет сделать пару узлов с цветом, смешать их в специальном узле (выходящем на Albedo) и прикрепить к нему же выход той цепочки узлов, что мы собирали выше. Таким образом эта цепочка будет выступать в качестве фактора смешивания этих цветов.
Чтобы превратить выбранный узел в отдельную сцену нужно щёлкнуть на нём правой кнопкой мыши и выбрать пункт «Сохранить ветку, как сцену». После чего задать имя этой сцене. После этого рядом с названием узла появится значок «Открыть в редакторе», откуда можно перейти к редактированию получившейся сцены в новом окне.
Чтобы произвести обратную манипуляцию, если нам, допустим, нужно достать объекты сохранённой ветки на текущую сцену, чтобы их как-то пересобрать или модифицировать — жмём на таком узле, скрывающем в себе сцену, правой кнопкой и выбираем пункт «Сделать локальным». Сохранённая сцена, которую он собой представлял, при этом не уничтожается.
Чтобы пользоваться глобальными переменными, нужно создать скрипт и забросить его в автозагрузку: Проект — Настройки проекта — Автозагрузка. Галочка «синглтон» должна быть отмечена.
Содержимое скрипта SaveTheWorld, переменные которого мы хотим использовать как глобальные. В данный момент здесь объявлен некий показатель здоровья и массив состояний врагов, заполняющийся на шаге инициализации.
Чтобы обратиться к этим глобальным переменным из кода нужно сначала получить ссылку на синглтон, после чего пользоваться его переменными:
Находим наш SaveTheWorld, после чего проверяем, является ли состояние этого конкретного врага нулевым. Если да, то враг удаляется.
UPD. Можно обратиться к переменным синглтона сразу через его имя, то есть в примере выше нам не пришлось бы брать ссылку, и вместо main.enemy_arr[myID] обращались бы к SaveTheWorld.enemy_arr[myID]. Но вы должны быть уверены, что у этого узла в автозагрузке отмечена галочка в графе «синглтон».
Для записи и проигрывания анимаций на сцену добавляется узел AnimationPlayer. Он может находится в произвольном месте в иерархии. Для того, чтобы дать ему возможность записать анимацию нужно нажать на кнопку «Анимация», выше открывшегося таймлайна и создать новую анимацию.
После этого на каждом выбираемом узле в текущей сцене, справа в инспекторе появятся значки ключа. Если нажать на ключ, то аниматор предложит добавить новую дорожку анимации.
Далее передвигаем ползунок таймлайна в нужные точки, и в каждой меняем в инспекторе объекта то анимируемое значение, снова нажимая ключ, чтобы эта точка появилась на таймлайне. Расширить доступный таймлан можно в поле с часиками, справа, по умолчанию там выставлена 1 секунда. Правее часиков кнопка зацикливания анимации. Ниже, первой в строке идёт одна из часто-используемых опций, устанавливающая дёрганный дискретный или непрерывный плавный характер анимации.
Правее центральной панельки с названием анимации находится кнопка автозапуска, если её нажать то выбранная анимация будет проигрываться при запуске приложения. Если вам нужно несколько анимированных объектов, проигрываемых в цикле постоянно, то можно сделать их дорожки в одном AnimationPlayer, создав им одну общую анимацию. Если нужно переключать анимации у какого-то конкретного объекта, то ему можно завести отдельный AnimationPlayer и там создать ему несколько анимаций для разных состояний, при этом только одна из них может быть отмечена как запускаемая автоматически.
Для различных узлов, например MeshInstance или CollisionShape, в поле Mesh (Shape) можно выбирать из заготовленного списка примитивов (в том числе загрузить свою кастомную модель, в случае с MeshInstance).
Для MeshInstance одними из наиболее затратных примитивов будут сфера и капсула, так как в них скорее всего будет много полигонов. Поэтому для 3д частиц лучше выбирать что вроде полигона, куба или призмы. Для коллизий, наоборот, форма сферы будет наиболее быстро считаемой, так как из параметров у неё один лишь радиус. Собственно, вышесказанное касается не только Годо, но и прочих игровых движков.
Также Godot может сделать форму коллизии для MeshInstance автоматически, для этого нужно нажать на кнопку «Массив», которая появляется вверху справа в редакторе, когда выбран MeshInstance. Далее выбираете из предложенных вариантов, но как правило, для того же terrain, это будет первый пункт — «Создать вогнутое статическое тело» (после чего к объекту прикрепится узел StaticBody с вложенной в него точной коллизией). Во всех прочих случаях, когда особо точные коллизии не требуются можно обходиться самостоятельно выставленными примитивами CollisionShape, либо собирать оптимальные меши для коллизий в 3д пакете, после чего добавлять их через MeshInstance и также создавать по их форме коллизию через кнопку «Массив».
Если в каком-то из числовых полей в инспекторе требуется, например, прибавить к параметру определённое число, умножить значение, и так далее, то можно так и выбивать: «315-180», «20+40», «64*5»… редактор сам посчитает и подставит итоговый результат операции в поле.
Когда есть некий объект, параметры которого нужно перенести на другой (положение в пространстве, вращение, масштаб), то, чтобы, не переносить каждое конкретно поле можно скопировать всё сразу, нажав на значок инструментов слева, в Инспекторе. Там в списке есть опция «Копировать параметры». Потом выбирается другой объект и через такую же иконку свойств выбирается опция «Вставить параметры».
Для удаления объекта через код обычно ему делают вызов queue_free(). Ещё быстрее можно удалить с помощью free(), но это менее безопасный вариант. Удаление слишком тяжёлых объектов вызывает заметную просадку fps, но лёгкие и оптимальные устраняются без просадок. В целом это некий индикатор — если объект удаляется слишком долго, то желательно оптимизировать его. Вызов remove_child(object) тоже похож на удаление, но по факту такой объект всё ещё хранится в памяти, чтобы его можно было снова к чему-то прикрепить, а если прикреплять заново не потребовалось, то эффект близок к вызову hide(), то есть к обычному сокрытию из видимости.
Твоя первая игра на Godot Engine
1. Предисловие
Здравствуй, в данной статье я хочу в максимально сжатой форме познакомить тебя с основами создания простых 2d платформеров на движке Godot. Иногда мы будем останавливаться на некоторых важных моментах, а иногда пропускать ненужную тебе на начальном уровне информацию.
2.Стартуем!
Думаю установить сам движок не составит труда. После установки открываем его и нажимаем на кнопку «новый проект».
Создание проекта.
В выплывшем окошке введи название проекта и выбери его расположение в файловой системе. В пункте «отрисовщик» выбираем «OpenGL ES 3.0», у нас нет нужды использовать более старую версию opengl, т.к ее обычно применяют при создании браузерных игр.
3.Знакомство с интерфейсом
Итак, мы создали твой первый проект! Отличное начало, на сегодня хватит. Ладно, а если серьезно, то изучать интерфейс программы, особенно на первых парах, очень важно. Перед тобой открылась интересная картина с пустой 3d сценой, но она нам сегодня не понадобится, поэтому переходим во вкладку 2d. Кнопка находится сверху посередине. Стало немного проще, не правда ли? Ну, а теперь перейдем к самому интерфейсу программы (его кстати можно настроить под себя, перетащив какие-то элементы левой кнопкой мыши, но пока лучше оставить все как есть).
4.Работа с файлами через Godot
Не очень удобно каждый раз лазить в проводник, чтобы достать какие-то файлы, согласен? Для этого в Godot существует отдельное окошко, оно находится в левом нижнем углу редактора.
Проводник в Godot Engine.
Пока что там пусто, но это потому, что мы еще ничего не добавили. Так давай сделаем это! Ссылку на архив я прикрепил в конце поста, скачивай его и наслаждайся халявными спрайтами для игры (сразу говорю, они не мои). Если конечно у тебя заготовлена своя графика, то милости прошу.Итак, выделяем все нужные нам файлы и переносим их в окошечко. Вжух и они скопировались в движок! Но на этом магия не заканчивается! Здесь можно делать все то, что ты делаешь в обычном проводнике! Одним словом, полная свобода действий.
Но давай пока оставим эту часть экрана в покое и перейдем к более серьезным вещам.
5.Работа со сценами
Посмотри в верхний левый угол редактора. Здесь есть вкладка, которая называется «Сцена». Давай добавим твою первую сцену! Делается это просто, тебе нужно либо нажать на плюсик, либо ввести сочетание клавиш «ctrl + A». Перед тобой выплыло меню, в поиске которого нужно ввести заветное слово «Node». Мы давай это будет наша основная сцена, назовем ее «World», но название в принципе неважно. Чтобы переименовать сцену нужно лишь дважды щелкнуть на нее левой кнопкой мыши. Теперь давай добавим на сцену игрока!
Многие просто добавляют объект «Sprite», но это большая ошибка! Так делать нельзя! Запомни это раз и навсегда! Мы с тобой, как продвинутые пользователи добавим не «Sprite», а «KinematicBody2D».
Теперь древо твоего проекта выглядит так:
Добавляем игрока.
Как ты наверное успел заметить, напротив нашего «KinematicBode2D» висит какой-то желты значок. Что он тут забыл? Дело в том, что наш объект пока что не имеет форму, вот Godot и ругается. Но прежде чем добавить форму нашему игроку, давай добавим его спрайт( И не забудь заменить название «KinrmaticBode2D» на «Player» ). Для этого нажми один раз правой кнопкой мыши на нашего «Player» и сочетанием клавиш «ctrl + A» добавь объект «Sprite». Потом опять нажми на Игрока и добавь объект «CollisionShape2D». У тебя должна быть примерно такая картина:
Добавляем в спрайт и границы игрока.
Если все так, едем дальше. Теперь зададим картинку спрайта нашего персонажа. Выбираем объект «Sprite», а потом перетаскиваем из моего архива картинку «Player.png»( или твою картинку) в раздел «Texture». Если картинка импортировалась с сжатым качеством, просто нажми на нее, и в Godot в верхнем левом углу перейди в вкладку «Импорт», там в разделе «Flags» убери галочку с пункта «Filter» и нажми «Переимпортировать». Если не помогло, то просто перезапусти Godot.
Итак, мы добавили спрайт игрока, но выглядит это немного странно.
Добавляем текстуру спрайта игрока.
Что же делать? Без паники, все поправимо в пару кликов. В левой части панели «Инспектор» выбираем параметр «Hframes», и подгоняем его по размерам ( у меня это 25). Ну что, поменялась картинка?
Устанавливаем границы спрайта.
Супер, едем дальше! Ты еще не забыл про CollisionShape2D? Выделяй его и в пункте «Shape» выбирай «Новый RectangleShape2D». Теперь изменяй его под размер персонажа. У меня получилось так:
CollisionShape2d.
6.Отдельные сцены в Godot
Это все конечно классно,но хорошим тоном в Godot является создание отдельных сцен для объектов. Поэтому нам нужно сделать так, чтобы объект «Player» был отдельной сценой. Но не создавать же нам все заново? Нет, для этого в движке предусмотрена отдельная функция.Нажмите на «Player» правой кнопкой мыши и выберете «Сохранить ветку,как ветку».
Создание сцены из ветки.
Теперь «Player» это отдельная сцена, отлично!Чтобы перейти на сцену игрока достаточно нажать на иконку:
Перейдем на сцену игрока и приступим к очень интересному занятию — программированию.
7. Скрипт игрока, GDscript
Для того чтобы добавить скрипт какому-либо объекту нужно просто выбрать этот объект и нажать на иконку свитка:
Создать скрипт.
После этого выплывет такая табличка:
Скрипт для игрока.
Нажимаем «Создать» и у нас открывается встроенный редактор кода в Godot.Теперь начинается более сложная часть туториала, поэтому слушай внимательнее.Пока что наш персонаж просто стоит на сцене и ничего не делает, это слишком скучно. Ну так давай сделаем управление персонажем!Что нам для этого понадобится? Нам нужен скрипт, который будет обрабатывать нажатия клавиш с клавиатуры, двигать персонажа, проигрывать анимацию. Но давай пойдем по порядку и начнем с самого простого — управления.
Простое управление.
Как ты заметил, мы прибавляем к координате игрока произведение направления по координате на ускорение и на какую-то delta. Вопрос, что такое delta? Delta показывает сколько времени (в секундах, тип float) прошло с момента отрисовки прошлого кадра.Зачем это сделано? Если мы не будем привязывать передвижение игрока ко времени, то оно автоматически привязывается к частоте процессора. На крутых компьютерах или телефонах разница незаметна, но запустив приложение на старом пк или телефоне, ты все поймешь. Поэтому всегда привязывай передвижение к delta!
Потом в строке 13 мы используем какой-то clamp. Опять неразбериха! Все просто, clamp, как можно догадаться из названия, «сжимает» значение переменной. Сделано это для оптимизации и плавности движения.Ну и в последней строке мы просто запускаем передвижение нашего игрока. Не так уж все и сложно!
8. Первый запуск.
Вот сделали мы все это с тобой, а где результат? Ну так давай поскорее запустим с тобой первую демку! Все очень просто, нажми клавишу F5, после этого выплывет окно, которое скажет тебе, что основания сцена не выбрана. В нашем случае основная сцена — World.tscn. Выбираем ее и снова жмем F5. Должно появиться что-то такое:
Окно демки.
В верхнем левом углу можно заметить маленькую часть нашего персонажа. Давай приведем все в порядок. Для этого сначала закрое окошко демки и перейдем в настройки проекта. Чтобы это сделать, в левой верхней части нажми на «Проект», а в выплывшем окне нажми «Настройки проекта». Здесь переходим в вкладку «Window» и ставим разрешение на 320×180. Почему такое маленькое? Все просто, мы с тобой задали разрешение экрана в самой сцене, для платформера такие размеры идеальны. А для экрана самой демки нужно задать нормальное разрешение. Это можно сделать в пунктах «Test Width» и «Test Height». Я задам его в формате 1280×720. Спустимся пониже и в пункте «Mode» ставим «2d», а в «Aspect» ставим «keep». Для красоты предлагаю обратно перейти на сцену и передвинуть персонажа в середину экрана. Делается это легко, просто зажми персонажа левой кнопкой мыши и начни перетаскивать. Теперь все приготовления закончены,можно запускать демку.
Красота, правда? Попробуй передвигать персонажа стрелками на клавиатуре. Получилось? Да, но персонаж будто скользит по экрану и не может остановиться. Не волнуйся, скоро мы это исправим. Однако сейчас наш персонаж как бы висит в воздухе, это не есть хорошо. Давай сделаем землю для нашего игрока!
9.Tilemaps
Что такое «Tilemap»? Тайлы — это плитки, вместе образующие сетку тайлов. Чаще всего они принимают форму квадратов. Как же их добавить в наш платформер? Очень просто, для начала выбери объект «World»(нашу основную сцену), нажми клавиши «ctrl + A» и выбери «TileMap».
Теперь в этом окошке выбири «Tile Set» и нажми «Новый TileSet».Снова нажми на «TileSet», должно получиться ка-то так:
Добавляем анимацию.
Давай добавим спрайт для нашего tilemap, для этого нажми на плюс снизу и выбери «tile.png».
Следующий шаг будет довольно сложным, поэтому слушай внимательно. Итак, во вкладке «Регион» полостью выделяем нашу картинку, в вкладке «snap options» ставим step по x и y на 16. Такие же действия повторяем во вкладках столкновение, перекрытие, навигация, битовая маска. А последней мы остановимся поподробней.
В ней мы нажимаем на квадратик и выделяем весь тайл. Тоже самое проделываем и в других вкладках. Вот как в итоге должно получиться.
Задаем границы тайла.
Отлично, сохраняем все и переходим обратно на сцену. Еще раз кликаем на Tilemap и в раздеел «Cell» меняем size на 16×16.Теперь можно делать уровень!
Создаем простой уровень.
Вот как у меня получилось. Супер, но на нашего игрока до сих пор не действует гравитация, давай это исправим. Для этого перейдем в скрипт player и введем там такой код.
Константы для прыжка и гравитации.
Здесь к существующим переменным мы добавляем friction, gravity, jumpforce, airresistance. Названия говорят сами за себя, поэтому объяснять за что они отвечают я не буду.
Реализация прыжка и гравитации.
Следом идет сама сила гравитации. Мы прибавляем к motion.y силу тяжести, умноженную на delta. Это действие заставляет нашего игрока падать вниз, если под ним ничего нет. После этого скрипт обрабатывает нажатия на кнопки, характерные для прыжка (стрелочка вверх). И заставляет игрока падать вниз, когда он уже прыгнул.
Вот собственно и все, давай запустим демку!Все работает. Но нет никаких анимаций,и передвижение из-за этого выглядит очень топорно.
Как выглядит при запуске.
10.Анимации
Простые анимации в Godot сделать очень легко. Для этого перейдем на сцену player и добавим туда «AnimationPlayer». Жмем на кнопку «анимация», далее жмем «новый» и вводим название анимации. Сделаю анимацию для бега и назову ее «Run».Чтобы добавить новый кадр для анимации нужно перейти в «sprite».
Добавляем кадры в анимацию.
Напротив пункта «frame» есть ключик,если нажать на него, то кадр из спрайта добавиться в анимацию. Постепенно увеличиваем frame от 0 до 8 и ключиком добавляем кадр в анимацию. Вот как в итоге это должно выглядеть:
Создаем анимацию из кадров.
Тоже самое повторяем для других анимаций, просто меняя номер кадра. В итоге у тебя будет несколько анимаций — для прыжка, ходьбы, и анимация idle. Теперь все это нужно добавить в код.Переходим в код player и вносим некоторые изменения:
Добавляем переменные для анимации.
Добавляем две переменные sprite и player. Но ты заметил, они какие-то странные. Почему в начале стоит слово onready, что за странное значение этой переменной? Сейчас все объясню. Переменные типа onready нужны для взаимодействий с другими объектами на сцене. В данном случае мы подключаем их для воспроизведения анимации и получения спрайта игрока.
Анимация при ходьбе.
На 16-ой строчке мы проигрываем анимацию ходьбы. Однако здесь еще появилась какая-то странная 22 строчка, что она делает? Она зеркально отражает анимацию игрока в зависимости от того, куда он идет. А на 24 строке мы говорим, что если игрок стоит, то проигрывать нужно анимацию idle.
Анимация прыжка.
На 35 строчке мы проигрываем анимацию прыжка, если игрок не на земле. Вот собственно и все изменения в коде.
Заключение
Если ты все правильно делал, то у тебя должен получиться простой платформер. Что делать дальше? Да все что угодно! Улучшай свои навыки в использовании движка, создавай свои собственные игры изучай новые фишки. На этом я вынужден с тобой проститься, надеюсь ты хорошо провел время и научился чему-то новому.