Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

Графический интерфейс

Заключительный этап нашей игры нуждается в Пользовательском интерфейсе (UI), чтобы отображать такие вещи, как очки, сообщение "игра окончена" и кнопку перезапуска.

Создайте новую, сцену нажмите на "Другой узел" и добавьте узел CanvasLayer с именем HUD. "HUD" означает "heads-up display", дисплей, отображающийся поверх игры.

Узел CanvasLayer позволяет нам прорисовывать элементы нашего UI на слое поверх всей остальной игры, поэтому отображаемая информация не перекрывается никакими игровыми элементами, такими как игрок или мобы.

HUD должен отображать следующую информацию:

  • Счет, измененный ScoreTimer.

  • Сообщение, например "Game Over" или "Get Ready!"

  • Кнопку "Start" для начинания игры.

Основной узел для элементов UI — это Control. Чтобы создать наш UI, мы будем использовать два типа узлов Control:, Label и Button.

Создайте следующие узлы, как дочерние узла HUD:

  • Label с именем ScoreLabel.

  • Label с именем Message.

  • Button с именем StartButton.

  • Timer с именем MessageTimer.

Нажмите на ScoreLabel и введите число в поле Text в Инспекторе. Стандартный шрифт для узлов Control мал и плохо масштабируется. В ресурсы игры включен файл шрифта под названием "Xolonium-Regular.ttf". Чтобы использовать этот шрифт, сделайте следующее:

В "Theme Overrides > Fonts" выберите "Загрузить" и выберите файл "Xolonium-Regular.ttf".

../../_images/custom_font_load_font.webp

Размер шрифта все еще слишком мал, увеличьте его до 64 в разделе «Theme Overrides > Font Sizes». Сделав это для ScoreLabel, повторите изменения для узлов Message и StartButton.

../../_images/custom_font_size.webp

Примечание

Якоря: Узлы Control имеют не только положение и размер, но также якоря. Якоря определяют начало координат - опорную точку для краев узла.

Расположите узлы, как показано ниже. Вы можете перетаскивать узлы, чтобы разместить их вручную, или для более точного размещения используйте "Предустановки значений для якорей и отступов узла Control".

../../_images/ui_anchor.webp

ScoreLabеl

  1. Установите текст на 0.

  2. В Инспекторе, установите "Horizontal Alignment" и "Vertical Alignment" на Center.

  3. Установите "Предустановки значений для якорей и отступов узла Control" на Вверху по центру.

Message

  1. Установите текст на Увернись от Крипов!.

  2. В Инспекторе, установите "Horizontal Alignment" и "Vertical Alignment" на Center.

  3. Установите "Autowrap Mode" на Word, в противном случае надпись останется на одной строке.

  4. В разделе "Control - Layout/Transform" установите для параметра «Size X» значение на``480``, чтобы использовать всю ширину экрана.

  5. Установите "Предустановки значений для якорей и отступов узла Control" на По центру.

StartButtоn

  1. Установите текст на Старт.

  2. В разделе "Control - Layout/Transform" установите для параметра «Size X» значение 200, а для параметра "Size Y" значение 100, чтобы добавить немного больше отступа между границей экрана и текстом.

  3. Установите "Предустановки значений для якорей и отступов узла Control" на Внизу по центру.

  4. В разделе "Control - Layout/Transform" установите для параметра "Position Y" значение 580.

В MessageTimer установите параметр Wait Time на 2, а параметр One Shot на значение "Вкл".

Теперь добавьте этот скрипт в HUD:

extends CanvasLayer

# Notifies `Main` node that the button has been pressed
signal start_game

Теперь мы хотим временно отобразить сообщение, например "Get Ready" (Приготовьтесь), поэтому мы добавляем следующий код

func show_message(text):
    $Message.text = text
    $Message.show()
    $MessageTimer.start()

Также нам нужна функция, которая будет вызываться, когда игрок проигрывает. Она покажет надпись "Game Over" на 2 секунды, затем произойдет возврат к основному экрану, и после короткой паузы появится кнопка "Старт".

func show_game_over():
    show_message("Game Over")
    # Wait until the MessageTimer has counted down.
    await $MessageTimer.timeout

    $Message.text = "Dodge the Creeps!"
    $Message.show()
    # Make a one-shot timer and wait for it to finish.
    await get_tree().create_timer(1.0).timeout
    $StartButton.show()

Примечание

Если вам нужно сделать паузу на короткое время, то альтернативой использованию узла Timer является использование функции SceneTree create_timer(). Может быть очень полезно добавлять задержки наподобие таких, как в вышеприведенном коде, где нам хотелось бы подождать немного времени, прежде чем показывать кнопку "Start".

Добавьте приведенный ниже код в HUD, чтобы обновлять счет

func update_score(score):
    $ScoreLabel.text = str(score)

Присоедините сигнал timeout() из MessageTimer и сигнал pressed() из StartButton к узлу HUD и добавьте следующий код к новым функциям:

func _on_start_button_pressed():
    $StartButton.hide()
    start_game.emit()

func _on_message_timer_timeout():
    $Message.hide()

Подключение HUD к Main

Теперь, когда мы закончили создание сцены HUD, вернитесь к Main. Инстанцируйте сцену HUD в Main подобно тому, как вы это делали со сценой Player. Дерево сцены должно выглядеть так, поэтому убедитесь, что вы ничего не упустили:

../../_images/completed_main_scene.webp

Теперь нам нужно подключить функционал HUD в наш Main-скрипт. Для этого потребуются некоторые дополнения к сцене Main:

In the Signals tab, connect the HUD's start_game signal to the new_game() function of the Main node by clicking the "Pick" button in the "Connect a Signal" window and selecting the new_game() method or type "new_game" below "Receiver Method" in the window. Verify that the green connection icon now appears next to func new_game() in the script.

В new_game() обновим отображение счёта и выведем сообщение "Get Ready":

$HUD.update_score(score)
$HUD.show_message("Get Ready")

В game_over() нам нужно вызвать соответствующую функцию HUD:

$HUD.show_game_over()

Наконец добавьте этот код в _on_score_timer_timeout(), чтобы синхронизировать отображение с изменением количества очков:

$HUD.update_score(score)

Предупреждение

Когда вы убедитесь, что всё работает, удалите вызов new_game() из _ready(), иначе ваша игра запустится автоматически.

Теперь вы готовы играть! Нажмите кнопку "Play the Project".

Удаляем старых крипов

Если вы играете до "Game Over", а затем сразу начинаете новую игру, то крипы из предыдущей игры могут все еще оставаться на экране. Было бы лучше, если бы все они исчезали в начале новой игры. Нам просто нужен способ сказать всем мобам, чтобы они удалились. Мы можем сделать это с помощью функции "group" ("группа").

В сцене Mob выберите корневой узел и щелкните вкладку Groups рядом с вкладкой Signals, а затем кнопку "+", чтобы открыть диалоговое окно "Create New Group" ("Создать новую группу").

../../_images/group_tab.webp

Назовите группу mobs и нажмите «ok», чтобы добавить новую группу сцены.

../../_images/add_group_dialog.webp

Теперь все мобы будут в группе «mobs».

../../_images/scene_group_mobs.webp

Затем мы можем добавить следующую строку в функцию new_game() в Main:

get_tree().call_group("mobs", "queue_free")

Функция call_group() вызывает каждую именованную функцию на каждом узле в группе - в этом случае мы говорим каждому мобу удалять себя.

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