暂停游戏

暂停?

在大多数游戏中, 最好是在某些时候中断游戏, 做一些其他事情, 比如休息一下或改变选项. 然而, 这并不像它看起来那么简单. 游戏可能被停止, 但可能希望一些菜单和动画继续工作.

对可暂停(以及不可暂停)的内容实现细节控制需要大量工作, 因此Godot提供了一个简单的暂停框架.

如何暂停工作

要设置暂停模式, 必须设置暂停状态. 这是通过为 : 参考:场景树. 暂停 <类_场景树_属性_暂停> 成员变量赋予 "真" 值来完成的:

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

这样做会产生以下行为:

  • 2D 和 3D 物理将被停止.

  • _process_physics_process 将不再会被节点调用.

  • _input_input_event 也不再被调用.

这有效地阻止了整个游戏. 默认情况下, 从脚本调用此函数将导致不可恢复的状态(游戏永久暂停!).

白名单节点

在启用暂停之前, 请确保在暂停期间必须继续工作的节点已列入白名单. 这是通过编辑节点中的 暂停模式 属性来完成的:

../../_images/pausemode.png

你可以在代码中实现同样的结果:

func _ready():
    pause_mode = Node.PAUSE_MODE_PROCESS
public override void _Ready()
{
    PauseMode = Node.PauseModeEnum.Process;
}

默认情况下,所有节点的这个属性都是“Inherit(继承)”状态,也就是说,它们会根据父节点上这个属性的取值来决定处理与否。如果父节点也是“Inherit”,那么就会去检查祖父节点,以此类推。最终,如果祖宗们都没有更改过状态,那么就会使用 SceneTree 的暂停状态。也就是说,在游戏暂停时默认所有节点也都会被暂停下来。

节点的三种可能状态有:

  • Inherit(继承) :处理与否取决于父、祖父等等节点中第一个非 Inherit 状态的节点。

  • Stop(停止) :无条件停止节点(以及 Inherit 模式的子节点)。暂停时该节点不会进行处理。

  • Process(处理) :无条件处理节点(以及 Inherit 模式的子节点)。无论暂停与否,该节点都会进行处理。

示例

一个示例是创建一个带有控件的弹出窗口或面板, 并将其暂停模式设置为 "进程" 然后隐藏它:

../../_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;
}

就是这样, 喵!