# AppLifecycle (F5) —— 移动端应用生命周期集中处理。 # # 把 SceneTree 转发来的 MainLoop 通知收成信号,并做默认动作:后台时暂停游戏 # 逻辑 / 降帧 / 停 BGM,恢复时还原;iOS 内存告警时广播让各缓存自清。渲染上下文 # 丢失(Android Vulkan surface)由 Godot 自己重建,我们持有的 GPU 资源都由 # RenderingServer 托管,无需干预。 # # 用法: # var life := preload("res://app_lifecycle.gd").new() # add_child(life) # 越早越好(autoload 亦可) # life.bind(m2client, audio) # 可选:自动接常见消费方 # life.paused.connect(_on_bg); life.resumed.connect(_on_fg) extends Node signal paused # 进入后台(NOTIFICATION_APPLICATION_PAUSED) signal resumed # 回到前台 signal focus_changed(focused: bool) signal memory_warning # iOS 内存压力 signal back_requested # Android 返回键 signal close_requested # 窗口关闭请求(桌面) ## 后台时是否 get_tree().paused = true(默认开;纯观战/录像可关) var pause_tree_on_background := true ## 后台时把 max_fps 压到这个值省电(0 = 不改) var background_max_fps := 8 var _bound_client: Node var _bound_audio: Node var _saved_max_fps := 0 var _bg := false func _ready() -> void: # 通知在暂停树时也要能收到 process_mode = Node.PROCESS_MODE_ALWAYS func bind(m2client: Node = null, audio: Node = null) -> void: _bound_client = m2client _bound_audio = audio func is_backgrounded() -> bool: return _bg func _notification(what: int) -> void: match what: NOTIFICATION_APPLICATION_PAUSED: _enter_background() NOTIFICATION_APPLICATION_RESUMED: _exit_background() NOTIFICATION_APPLICATION_FOCUS_IN, NOTIFICATION_WM_WINDOW_FOCUS_IN: focus_changed.emit(true) NOTIFICATION_APPLICATION_FOCUS_OUT, NOTIFICATION_WM_WINDOW_FOCUS_OUT: focus_changed.emit(false) NOTIFICATION_OS_MEMORY_WARNING: memory_warning.emit() NOTIFICATION_WM_GO_BACK_REQUEST: back_requested.emit() NOTIFICATION_WM_CLOSE_REQUEST: close_requested.emit() func _enter_background() -> void: if _bg: return _bg = true if background_max_fps > 0: _saved_max_fps = Engine.max_fps Engine.max_fps = background_max_fps if _bound_audio and _bound_audio.has_method("stop_bgm"): _bound_audio.stop_bgm() if _bound_client and _bound_client.has_method("suspend"): _bound_client.suspend() if pause_tree_on_background: get_tree().paused = true paused.emit() func _exit_background() -> void: if not _bg: return _bg = false if pause_tree_on_background: get_tree().paused = false if background_max_fps > 0: Engine.max_fps = _saved_max_fps if _bound_client and _bound_client.has_method("resume"): _bound_client.resume() resumed.emit()