Pausando jogos

Pausa?

Na maioria dos jogos, é desejável, em algum ponto, interromper o jogo para fazer outra coisa, como fazer uma pausa ou alterar opções. No entanto, isso não é tão simples quanto parece. O jogo pode ser interrompido, mas pode ser desejável que alguns menus e animações continuem funcionando.

Implementar um controle refinado para o que pode ser pausado (e o que não pode) é muito trabalhoso, portanto, uma estrutura simples para pausa é fornecida no Godot.

Como a pausa funciona

Para definir o modo de pausa, o estado de pausa deve ser definido. isso é feito atribuindo true à propriedade SceneTree.paused:

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

Fazer isso terá o seguinte comportamento:

  • As físicas 2D e 3D serão interrompidas.

  • _process e _physics_process não serão mais chamados nos nós.

  • _input e _input_event também não serão mais chamados.

Isso efetivamente interrompe todo o jogo. Chamar esta função a partir de um script, por padrão, resultará em um estado irrecuperável (nada funcionará mais!).

Adicionando nós à lista branca

Antes de habilitar a pausa, certifique-se de que os nós que devem continuar trabalhando durante a pausa estejam na lista branca. Isso é feito editando a propriedade "Modo de Pausa" em um nó:

../../_images/pausemode.png

Você pode alcançar o mesmo resultado em código:

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.

Assim, os três estados possíveis para um nó são:

  • Herdar: Processa dependendo do estado do pai, avô, etc. O primeiro pai que tem um estado não Inherit.

  • Stop: Para o nó não importa o que aconteça (e filhos no modo Inherit). Quando pausado, este nó não será processado.

  • Process: Processa o nó independentemente do que aconteça (e os filhos no modo Inherit). Pausado ou não, este nó será processado.

Exemplo

Um exemplo disso é criar um pop-up ou painel com controles internos e definir seu modo de pausa para "Process" e ocultá-lo:

../../_images/pause_popup.png

Apenas definindo a raiz do pop-up de pausa como "Process", todos os filhos e netos herdarão esse estado. Dessa forma, este ramo da árvore da cena continuará funcionando quando estiver em pausa.

Finalmente, faça isso quando um botão de pausa for pressionado (qualquer botão serve), habilite a pausa e mostre a tela de pausa.

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();
}

Para remover a pausa, faça o oposto quando a tela de pausa for fechada:

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

E é isso!