Пауза в играх

Пауза?

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

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

Как работает пауза

Чтобы установить режим паузы, нужно установить состояние паузы. Это можно сделать присвоив true свойству SceneTree.paused:

get_tree().paused = true
GetTree().Paused = true;

Это приведёт к тому что:

  • 2D и 3D физика остановятся.
  • _process and _physics_process will not be called anymore in nodes.
  • _input и``_input_event`` также не будут вызываться.

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

Белый список нодов

Прежде чем делать паузу, убедитесь что ноды которые должны работать во время паузы занесены в белый список. Это выполняется через редактирование свойства «Pause Mode» в ноде:

../../_images/pausemode.png

You can achieve the same result in code:

func _ready():
    pause_mode = Node.PAUSE_MODE_PROCESS

По умолчанию во всех нодах это свойство установлено в состояние «Inherit». Это означает, что они будут обрабатываться (или нет) в зависимости от установки данного свойства в родительской ноде. Если в родителе установлено «Inherit», то родитель данного родителя будет проверяться и так далее. В конечном итоге, если состояние не было найдено не в одном из родителей, будет использовано состояние SceneTree/ Это означает, что по умолчанию, когда игра ставится на паузу каждая нода будет остановлена.

Существует три возможных состояния для ноды:

  • Inherit: Процесс зависит от состояния родителя, родителя-родителя, итд. Т.е первый родитель который будет иметь не-Inherit состояние.
  • Stop: Останавливает ноду в любом случае (и потомков в состоянии Inherit). Когда пауза происходит эта нода не будет обрабатываться.
  • Process: Обрабатывать эту ноду в любом случае (и потомков в состоянии Inherit). Вне зависимости от паузы эта нода будет обрабатываться.

Пример

Например создадим поп-ап или панель с элементами управления внутри, установим режим паузы в «Process» а затем скроем её:

../../_images/pause_popup.png

Просто установив корень всплывающего окна в «Process», все потомки и потомки потомков будут наследовать это состояние. Таким образом, эта часть дерева сцены продолжит работу во время паузы.

Наконец, сделайте так чтобы нажатая кнопка паузы (любая кнопка подойдёт), включала паузу и показывала экран паузы.

func _on_pause_button_pressed():
    get_tree().paused = true
    $pause_popup.show()
public void _on_pause_button_pressed()
{
    GetTree().Paused = true;
    GetNode<Control>("pause_popup").Show();
}

Для отключения паузы, сделайте обратное когда экран паузы закрывается:

func _on_pause_popup_close_pressed():
    $pause_popup.hide()
    get_tree().paused = false
public void _on_pause_popup_close_pressed()
{
    GetNode<Control>("pause_popup").Hide();
    GetTree().Paused = false;
}

Вот и всё!