Настоящий саундтрек смуты
Слушаем на всех площадках!
Слушаем на всех площадках!
Для тех кто первый раз читает мой гоблинский блог - расскажу кратко что тут происходит. Я сам являюсь зеленым новичком в разработке игр и в своем блоге описываю этапы изучения столь сложного дела. На данный момент - это работа с движком Godot 4.
Чтобы не мучать вас длинными статьями, я разбиваю этот путь на кучу мелких блоков. Один пост - одна механика движка. Все гоблинские заумные слова расшифровываются на человеческий, так что даже пациент из Кащенко поймет о чем речь. Погнали!
● Создание сцены с персонажем:
В прошлой статье мы создали редактор карт с автоматическим заполнением, кто не читал - почитайте, будет полезно. Теперь нам нужно сделать персонажа, которым мы будем бегать по данной карте. Для этого нам нужен узел типа "CharacterBody2D", на основе которого мы и создаем новую сцену. Сделать это можно выбрав вкладку "Другой узел".
Как выглядит узел "CharacterBody2D"
● Визуальное изображение персонажа:
Узел это конечно хорошо, но мы пока ни черта не видим - нам нужен визуальный образ. Добавляем дочерний узел "Sprite2D". В его настройках находим вкладку текстуры и добавляем иконку Godot. В будущем мы заменим спрайт на анимацию, но пока нам хватит такой затычки.
Узел "Sprite" -> Texture -> Быстро загрузить
● Настройка зоны столкновения:
Чтобы наш персонаж не проваливался в текстуры и реагировал на поверхности мы должны настроить зоны столкновения. В прошлом уроке мы работали со слоем Collision в нашем TileMap. Тут же мы добавляем узел "CollisionShape2D", который представляет из себя выделение зоны столкновения в виде простой геометрической фигуры. Вид этой фигуры мы выбираем во вкладке "Shape".
Узел "CollisionShape2D" -> Shape -> Новый RectangleShape2D
● Начальные данные для физики и управления:
Создаем скрипт для нашей сцены и первым делом зададим константы. Константа - это постоянное значение, которое не будет меняться в ходе работы программы.
Чтобы создать константу мы пишем: const название_константы = значение
Переменные же создаются по другому: var название_переменной = значение
Давайте разберемся за что отвечают указанные нами значения:
speed и acceleration - от этих значений будет зависеть скорость передвижения по оси X (влево-вправо)
jump_velocity - это значение влияющее на высоту прыжка. Ось Y в Godot перевернута с ног на голову и отрицательное значение означает вверх.
friction - значение влияющее на скорость остановки при прекращении передвижения.
Так выглядят наши константы в коде
Так же мы добавляем значение гравитации, однако оно выставляется из внутренних настроек проекта.
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
● Общая функция для управления персонажем:
Задав исходные данные мы можем приступать к настройкам функций нашего персонажа. Для этого мы пишем стандартную функцию Godot:
func _physics_process(delta):
Для тех кто не знает - эта функция вызывается перед каждым физическим кадром, который привязан к физическому fps, он по умолчанию равен 60 раз в секунду.
var input_axis = Input.get_axis("ui_left","ui_right")
Get_axis - это функция которая присваивает переменной одно из двух значений при нажатии одной из двух кнопок. Первое значение равно -1 и задается при нажатии клавиши "влево". Второе же равно 1 и задается при нажатии клавиши "вправо". Если на момент кадра не нажата ни одна из этих кнопок, значение равно 0. Это позволяет нам определить нужное направление для изменения координат персонажа.
Влево = -1 | Вправо = 1 | Стоим на месте = 0
● Движение по оси X (влево-вправо), создаем новую функцию:
handle_acceleration (input_axis, delta)
В нее мы добавляем условие, что должна быть нажата одна из клавиш - влево или вправо.
if input_axis !=0:
Если данное условие выполнено, то мы совершаем перемещение в заданном направлении. Для этого используется функция move_toward.
velocity.x = move_toward(velocity.x, speed * input_axis, acceleration * delta)
velocity.x - это переменная отвечающая за перемещение по оси X.
В move_toward мы задаем три параметра через запятую. Изначальная точка, точка в которую мы должны прийти, шаг в сторону нужной точки за один кадр.
Каждый кадр мы двигаемся в выбранную сторону, начальная точка меняется и это создает замкнутый круг движения. А чтобы его запустить, мы добавляем нашу функцию под physics_process и в конце пишем move_and_slide().
move_toward ( начальная точка, точка прибытия, расстояние шага за один кадр )
▸ А где тормоза то !?
● Как сделать остановку?
Мы начали двигаться и если не нажмем кнопку в противоположную сторону - улетим за край карты. Чтобы разорвать наш круг постоянного движения мы должны сделать функцию тормоза.
Копируем нашу прошлую функцию и переименовываем ее:
handle_friction (input_axis, delta):
Так же меняем заданное условие, input_axis должен быть равен нулю. Главное помнить, что знак равенства при сравнении выглядит вот так "==".
if input_axis == 0:
В функции move_toward заменяем значения. Первое остается прежним, на втором ставим ноль, а на третьем стираем acceleration и пишем friction. Все это в сумме обеспечит нам быструю остановку.
Функции обратные друг другу
● Движение по оси Y (прыжок, гравитация), создаем новую функцию:
aplay_gravity(delta):
Если мы не на земле, то бишь в воздухе - нас должно тянуть вниз.
if not is_on_floor():
velocity.y += gravity * delta
Ставим именно "+=", так как это сделает плавное падение с нарастающим ускорением. Не забудьте умножить на delta, иначе все произойдет за долю секонды.
● Следующая функция для прыжка:
handle_jump(delta):
Для нас важны два условия - нахождение на земле в момент прыжка и нажатие нужной клавиши.
if is_on_floor() and Input.is_action_just_pressed("ui_accept"):
Если данное условие соблюдено мы приравниваем параметр оси Y к значению высоты прыжка.
velocity.y = jump_velocity
Добавляем эти функции под physics_process, а после переходим на сцену "world". Туда из общего списка ресурсов перетаскиваем сцену "player".
.tscn - это формат сцены в Godot
Как выглядит наш блок с функциями
● Что у нас получилось в итоге?
✓ Если вы нажимаем клавишу влево или вправо - персонаж двигается в выбранном направлении.
✓ Если ни одна из клавиш направления не нажата - мы останавливаемся.
✓ Если мы находимся в воздухе - нас тянет вниз с каждой секундой все сильнее.
✓ Если находясь на земле, мы жмем прыжок - нас подкинет вверх.
▸ Оно живое!
Вот так при помощи четырех простых функций мы создали основу физики и управление персонажем. Надеюсь разобрал каждый шаг максимально подробно и понятно.
✓ Зеленые новички - крепитесь и подписывайтесь, скоро новая статья. На очереди две темы - "анимация персонажа" или "двойные прыжки и прыжки от стены".
✓ Опытные шаманы - запасайтесь успокоительным, ибо дальше будет еще куча попыток освоить gamedev.
✓ Ну и все кто имеет свое мнение, поддержку или усмешку - пишите комменты!
Для тех кто первый раз читает мой гоблинский блог - расскажу кратко что тут происходит. Я сам являюсь зеленым новичком в разработке игр и в своем блоге описываю этапы изучения столь сложного дела. На данный момент - это работа с движком Godot 4.
Чтобы не мучать вас длинными статьями, я разбиваю этот путь на кучу мелких блоков. Один пост - одна механика движка. Все гоблинские заумные слова расшифровываются на человеческий, так что даже пациент из Кащенко поймет о чем речь. Погнали!
● Узлы, сцены и прочие слова не связанные с BDSM - это интерфейс Godot 4:
▸Наглядно показываю что и где
Основа движка Godot - это узлы и их древо. Блоки могут быть самого разного назначения, от визуального изображения, до настроек звука. Сцена - это отдельная группа узлов. Она нужна чтобы структурировать элементы и не путаться. Например, можно создать отдельную сцену с узлами нашего персонажа, а после добавлять эту сцену как узел в другую.
Создадим сцену нашей карты и назовем ее World. Для этого выбираем "2D сцена" как на скрине выше. Теперь можем добавить к сцене дочерний узел, нажав на плюсик. В поиске ищем TileMap - это узел для работы с тайл-сетами будущей карты.
● Что такое TileMap:
TileMap - это крайне полезный инструмент, который позволяет создать автоматическое заполнение карты. В разделе TileSet выбираем новый, внизу выбираем "Набор тайлов" и в открывшемся окне загружаем заранее подготовленный файл.
▸Шаблон для создания тайл-сета
Тайл-сет - это набор элементов из которых будет состоять будущая карта. Его можно нарисовать или поступить как истинный гоблин и взять ассеты в интернете. Чтобы не перетаскивать каждый кусок этого набора в нашу сцену, мы настроим автоматическое заполнение.
● Настройка рисования карты в TileMap:
В правом блоке узла TileMap вы найдете вкладку "Terrain Sets" (набор местности). В ней мы нажимаем "Добавить элемент" и в открывшемся блоке снова жмем "Добавить элемент". Теперь в центральном блоке выбираем вкладку "Рисовать" -> "Свойства рисования" - > Terrains.
▸Настройка местности
В обоих выделенных вкладках выбираем созданный нами элемент Terrain. С его помощью мы настраиваем области тайл-сета. Именно по ним Godot определяет какой кусок ставить следующим.
▸Настроенный TileMap
● Зоны столкновения для TileMap:
Помимо визуального изображения, нам нужно добавить для карты физический слой. Выбираем Physics Layer и добавляем новый элемент. Далее в разделе рисования выбираем "Физика" и наш слой. Так как наша карта состоит из блоков - выделаем каждый квадратом.
Теперь другие объекты будут видеть нашу карту и воспринимать ее как физическое препятствие.
● Как работает настроенный TileMap:
▸Рисуем что хотим
Теперь мы можем буквально рисовать карту, создавая любые формы. Алгоритм определяет какую часть нашего тайл-сета ставить в зависимости от соседних элементов. Просто води курсором с зажатой ЛКМ, а Godot сделает все остальное.
▸А вот это уже что-то похожее на элемент игры
Создание основы для уровня теперь занимает всего пару минут. Но помимо карты нам нужен наш персонаж, опасности и условия для завершения уровня. Этим мы займемся в следующем уроке.
Надеюсь гоблин смог пояснить за механику тайлов и вы смогли дочитать эту графоманию до конца.
✓ Зеленые новички - крепитесь и подписывайтесь, скоро новая статья.
✓ Опытные шаманы - запасайтесь успокоительным, ибо дальше будет еще куча попыток освоить gamedev.
✓ Ну и все кто имеет свое мнение, поддержку или усмешку - пишите комменты!