Пауза в играх

Пауза?

In most games it is desirable to, at some point, interrupt the game to do something else, such as taking a break or changing options. However, this is not as simple as it seems. The game might be stopped, but it might be desirable that some menus and animations continue working.

Внедрение филигранного контроля на то что может быть приостановлено (а что не может) это куча работы, так что в 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
public override void _Ready()
{
    PauseMode = Node.PauseModeEnum.Process;
}

By default, all nodes have this property in the "Inherit" state. This means, that they will only process (or not) depending on what this same property is set on the parent node. If the parent is set to "Inherit" , then the grandparent will be checked and so on. Ultimately, if a state can't be found in any of the grandparents, the pause state in SceneTree is used. This means that, by default, when the game is paused every node will be paused.

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

  • 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;
}

Вот и всё!