Предисловие
В этом уроке мы продолжим создавать платформер, созданный в предыдущем уроке.
Что такое сигнал в Godot?
Сигналы позволяют обмениваться сообщениями между объектами, при возникновении какого-либо события, например, пересечение объектов, истек таймер и т.д.
Подготовка
Перейдите на сцену world (ваш уровень) и сохраните узел Player, как сцену, нажав «Сохранить ветку как сцену«.
Теперь создадим предмет, который при подборе исчезает. Для этого, создайте узел Area2D, вложите в него Sprite2D и CollisionShape2D.
Далее:
- В качестве спрайта для Sprite2D, используйте icon.svg (либо другой, тут не принципиально).
- Растяните CollisionShape2D под размеры спрайта.
И сохраните Area2D как сцену, чтобы потом можно было продублировать этот предмет по всему уровню.
Теперь, откройте сцену Area2D, нажав на значок указанный на картинке ниже.
Привяжите к Area2D скрипт. Далее, выберите узел Area2D, в правом меню нажмите Узел, и графе Сигналы, выберите body_entered.
Сигнал body_entered срабатывает когда любой body (ChatacterBody, RigidBody, StaticBody), заходит в границы CollisionShape.
Ок, у вас создалась функция _on_body_entered, которая будет вызываться когда Body, зайдет в границы CollisionShape. Перепишите её так:
func _on_body_entered(body):
queue_free()
Функция queue_free(), удаляет объект со сцены, т.к. мы вызываем её из Area2D, то и удаляется объект Area2D.
Готово, теперь запустите. При столкновении с объектом, он исчезает.
Что-бы продублировать объект, нажмите Ctrl+D, выбрав узел.
Добавляем нескроллящийся фон.
Вы, также, можете создать прикрепленный к экрану (нескроллищийся), фон.
Для этого, в сцене world добавьте узел CanvasLayer, и в него вложите узел с фоном, например, ColorRect.
- CanvasLayer — узел, который не меняет своего положения, т.е. не скроллится. Глубина слоя зависит от параметра Layer.
- ColorRect — узел, который рисует прямоугольник залитый одним цветом.
Задайте размер ColorRect так, чтобы он покрывал весь экран, для этого, выберите узел ColorRect
Справа в инспекторе задайте размер по пути Layout->Transform->Size. Теперь, выберите CanvasLayer
В инспекторе, установите глубину слоя (Layer) на -1. Таким образом слой CanvasLayer, и все что в него вложено, переместилось за слой уровня.
Про индексы слоев и маскок.
Впервые мы взаимодействовали со слоями и масками когда создавали TileMap.
Разберем их подробнее:
- Layer — задает, номер слоя на котором находится объект.
- Mask — указывает, номер слоя который видит объект.
Номера слоев (Layer), сидят в оперативной памяти, и не влияют на производительность. В то время как, все слои Mask, проверяются циклом на столкновение, и сильно влияют на производительность.
Слои и маски в TileMap задаются в графе PhysicsLayers внутри тайлсета, в остальных объектах (CharacterBody, Area2D), задаются в графе Collision.
Перемещаемся между уровнями.
Создайте дубликат сцены world, нажав Ctrl+D на файле world.tscn, я его назвал world2
И переделайте, немного, уровень.
На сцене world:
- Создайте узел Area2D
- задайте ему CollisionShape
- Привяжите событие объекта Area2D — body_entered, к скрипту сцены уровня world (если его нет, создайте)
В появившийся функцию, введите следующее:
get_tree().change_scene_to_file("res://world2.tscn")
С помощью get_tree(), мы получили доступ к дереву и, из него, вызвали change_scene_to_file, сменив сцену игры.
change_scene_to_file — функция которая меняет текущую сцену, на сцену из файла, чей путь указан в скобках.
Что-бы получить путь, нажмите по сцене в проводнике Godot ПКМ, и выберите «Копировать путь«
Только что мы создали Area2D, при столкновении с которым, перейдем на следующий уровень.
Ок, код готов, однако, при запуске вы сразу перейдете на 2-ой уровень. Для исправления, вам нужно задать индексы слоя и маски.
Исправляем индексы слоев и масок.
Давайте определимся, на каком индексе будет располагаться каждый объект уровня.
- 1 — уровень, т.е. TileMap
- 2 — игрок
- none — подбираемые предметы не будут находится на каком либо слое. Они будут, лишь, проверять столкновение с игроком.
Ок, со слоями определились. Для удобства, зададим слоям имена, нажав на троеточие и на карандаш.
Теперь, нажав на троеточие, вы сможете указывать индекс слоя/макски по имени.
Теперь, зададим индексы слоя/маски.
Для игрока:
- Layer — 2 (player)
- Mask — 1 (world)
Для подбираемого предмета:
- Layer — нет
- Mask — 2 (player)
Т.к. код столкновения с Body прописан в подбираемом объекте (Area2D), то и проверять на столкновение нужно от-туда же.
Для тайлсета внутри TileMap:
- Collision Layer — 1 (world)
- Collision Mask — нет
Для Area2D, который перемещает на следующий уровень:
- Layer — нет
- Mask — 2 (player)
Ок, теперь запустите. Поздравляю, в вашей игре, теперь, 2 уровня.
Добавляем счетчик собранных предметов.
Для счетчика предметов нам понадобится синглтон (singleton), глобальная сцена/скрипт который сидит в оперативке всю игру.
Сцена нам не нужна, создадим скрипт, для этого, кликните ПКМ по папке res://, в появившемся меню выберите Новый->Скрипт и нажмите Создать. Скрипт переименуйте в global_vals.gd (опять же, для удобства)
Зайдите в Проект->Настройки проекта->Автозагрузка
- Выберите файл скрипта, нажав на значок папки.
- Укажите имя узла, может быть любым, но что-бы никто не терялся, пусть будет GlobalVals.
- Нажмите Добавить
Теперь, перепишите код global_vals.gd на следующее:
extends Node
var items_num = 0
Мы создали переменную items_num, которая будет хранить количество собранных предметов.
Теперь, зайдите в код предмета, и перепишите функцию, столкновения с Body.
func _on_body_entered(body):
GlobalVals.items_num += 1
print(GlobalVals.items_num)
queue_free()
Что-бы получить что-то из объекта в GDScript, используется точка (.)
Т.е:
- из синглтона GlobalVals, получили переменную items_num, и увеличили на 1.
- Вывели значение items_num в консоль Godot
- Удалили объект
Но лучше будет если счетчик будет находится на экране игрока.
Добавляем счетчик на экран.
Откройте сцену world, там создайте узел CanvasLayer, туда вложите Label.
Label — узел, который отображает текст
Выберите узел Label, и введите в инспекторе справа, любой текст. В игре, данный текст будет прикреплен к экрану, благодаря CanvasLayer2.
Наша задача в обновлении текста Label при увеличении items_num, о чем мы погорим в следующей статье.
Заключение.
В этом уроке вы познакомились с:
- сигналами
- индексами слоев и маск
- синглтонами
- Узлами Area2D и CanvasLayer
В следующем уроке, мы отобразим счетчик на экране, и сделаем главное меню.