D5/Autoload/GameState.gd
2025-05-09 15:36:04 +08:00

109 lines
4.2 KiB
GDScript

# GameState.gd
# Autoload Singleton
# 负责存储和管理核心游戏状态。
# 使用一个中央字典 (_state_data) 来存储所有状态,提高灵活性和可维护性。
# 状态的键名直接来源于初始化数据 (Init.json) 或后续动态添加。
extends Node
# --- 状态信号 ---
# 当游戏状态通过 initialize_for_new_game 初始化完成时发出
signal state_initialized(initial_state: Dictionary)
# 当游戏状态通过 restore_state 从存档恢复完成时发出
signal state_restored(restored_state: Dictionary)
# 当任何状态值通过 set_value 发生改变时发出
signal state_value_changed(key: String, new_value)
# [兼容性信号] 当 "time" 状态值被设置或更新时发出 (保持与旧代码或特定UI的兼容)
signal date_changed(new_date: Dictionary)
# --- 内部状态变量 ---
# 游戏是否暂停(比如正在UI操作界面)
var game_pause: bool = false
var is_on_task: bool = false
# 核心状态字典,存储所有动态游戏数据
var _state_data: Dictionary = {}
# --- 状态初始化与恢复 ---
# 为新游戏初始化状态。
# 直接使用传入的 initial_settings 字典填充状态。
func initialize_for_new_game(initial_settings: Dictionary) -> void:
print("GameState: Initializing state directly from initial settings...")
# 使用深拷贝 (duplicate(true)),确保 GameState 拥有独立的数据副本
_state_data = initial_settings.duplicate(true)
print("GameState: State initialized. Data:", _state_data)
# 发出通用初始化完成信号,传递状态副本
emit_signal("state_initialized", _state_data.duplicate(true))
# [兼容性] 如果存在 "time" 键,则发出 date_changed 信号
if _state_data.has("time") and typeof(_state_data["time"]) == TYPE_DICTIONARY:
emit_signal("date_changed", _state_data["time"].duplicate(true))
# 从加载的数据恢复状态。
# 直接使用 loaded_data 覆盖当前状态。
func restore_state(loaded_data: Dictionary) -> void:
print("GameState: Restoring state from loaded data...")
# 同样建议使用深拷贝,虽然从存档加载的数据理论上已经是独立的
_state_data = loaded_data.duplicate(true)
print("GameState: State restored. Data:", _state_data)
# 发出通用恢复完成信号,传递状态副本
emit_signal("state_restored", _state_data.duplicate(true))
# [兼容性] 如果存在 "time" 键,则发出 date_changed 信号
if _state_data.has("time") and typeof(_state_data["time"]) == TYPE_DICTIONARY:
emit_signal("date_changed", _state_data["time"].duplicate(true))
# 获取需要保存到存档的状态。
# 直接返回核心状态字典的副本。
func get_savable_state() -> Dictionary:
print("GameState: Gathering savable state...")
# 返回深拷贝,确保存档系统拿到的是快照,不会意外修改当前状态
return _state_data.duplicate(true)
# --- 状态访问 (通用 Getter) ---
# 获取指定键 (key) 的状态值。
# 如果键不存在,返回提供的默认值 (default)。
func get_value(key: String, default = null):
# 使用字典的 get 方法,它能优雅地处理键不存在的情况
return _state_data.get(key, default)
# --- 状态修改 (通用 Setter) ---
# 设置指定键 (key) 的状态值。
# 如果值发生变化,会发出 state_value_changed 信号。
# 如果键是 "time",还会额外发出 date_changed 信号。
func set_value(key: String, value) -> void:
var old_value = _state_data.get(key)
# 只有当值确实发生改变时才执行更新和发信号,提高效率
# 注意:对于字典或数组等引用类型,这个比较是浅比较。
# 如果需要深比较来判断内容是否改变,逻辑会更复杂。
# 对于基本类型和简单结构,这个判断通常足够。
if old_value != value:
_state_data[key] = value
#print("GameState: Value changed - ", key, ": ", value)
# 发出通用值变化信号
emit_signal("state_value_changed", key, value)
# [兼容性] 如果更新的是 "time" 键,且值是字典,则发出 date_changed 信号
if key == "time" and typeof(value) == TYPE_DICTIONARY:
emit_signal("date_changed", value.duplicate(true)) # 发送新日期的副本
func pause_game():
game_pause = true
func resume_game():
game_pause = false