D5/System/TimeManager.gd
2025-05-09 15:36:04 +08:00

103 lines
3.4 KiB
GDScript

# TimeManager.gd
# Autoload Singleton
# 负责驱动游戏内时间的流逝。
# 使用 Timer 节点每秒触发一次时间推进逻辑。
# 从 GameState 读取暂停状态和当前时间,并将更新后的时间写回 GameState。
extends Node
# Timer 节点,用于定时触发时间更新
var _day_timer: Timer
# 时间单位常量 (可选,但有助于提高可读性)
const SECONDS_PER_DAY: float = 1.0
const DAYS_PER_WEEK: int = 7
const WEEKS_PER_MONTH: int = 4
const MONTHS_PER_YEAR: int = 12
func _ready() -> void:
print("TimeManager: Initializing...")
# 1. 创建并配置 Timer 节点
_day_timer = Timer.new()
_day_timer.name = "DayTimer" # 给节点一个名字,方便调试
_day_timer.wait_time = SECONDS_PER_DAY
_day_timer.one_shot = false # 需要重复触发
# 2. 连接 timeout 信号到处理函数
# 使用 Callable 进行连接,这是 Godot 4 的推荐方式
var callable_on_timeout = Callable(self, "_on_day_timer_timeout")
if not _day_timer.is_connected("timeout", callable_on_timeout):
_day_timer.connect("timeout", callable_on_timeout)
# 3. 将 Timer 添加为子节点
add_child(_day_timer)
# 4. 启动 Timer (也可以设置 autostart = true)
_day_timer.start()
print("TimeManager: Day timer started (", SECONDS_PER_DAY, "s per day).")
# Timer 超时处理函数,每秒调用一次
func _on_day_timer_timeout() -> void:
# 检查游戏是否暂停
# 直接访问 Autoload GameState
if GameState.game_pause:
# print("TimeManager: Game paused, skipping time update.") # 可以取消注释用于调试
return # 如果暂停,则不执行任何操作
# --- 时间推进逻辑 ---
# 1. 从 GameState 获取当前时间
var current_time: Dictionary = GameState.get_value("time")
# 安全检查:确保获取到的是字典类型
if typeof(current_time) != TYPE_DICTIONARY or current_time.is_empty():
printerr("TimeManager: Error - Could not get valid time data from GameState. Current value: ", current_time)
# 考虑是否停止 Timer 或进行其他错误处理
_day_timer.stop()
printerr("TimeManager: Timer stopped due to invalid time data.")
return
# 2. 复制当前时间字典,避免直接修改 GameState 中的数据
var new_time: Dictionary = current_time.duplicate(true) # 使用深拷贝
# 3. 执行时间进阶计算
new_time["day"] += 1
if new_time["day"] > DAYS_PER_WEEK:
new_time["day"] = 1
new_time["week"] += 1
if new_time["week"] > WEEKS_PER_MONTH:
new_time["week"] = 1
new_time["month"] += 1
if new_time["month"] > MONTHS_PER_YEAR:
new_time["month"] = 1
new_time["year"] += 1
print("TimeManager: Happy New Year! Year:", new_time["year"]) # 新年提示
# 4. 将更新后的时间写回 GameState
# GameState 的 set_value 会处理信号发射 (state_value_changed, date_changed)
GameState.set_value("time", new_time)
# print("TimeManager: Time updated - ", new_time) # 可以取消注释用于调试
# --- 公共接口 (可选) ---
# 如果需要从外部控制 Timer (例如,调试或特定事件)
# func pause_time():
# _day_timer.paused = true
#
# func resume_time():
# _day_timer.paused = false
#
# func set_time_scale(scale: float):
# # 注意:直接修改 wait_time 会在当前周期结束后生效
# # 更复杂的倍速可能需要不同的实现方式 (例如 _process 累积 delta * scale)
# if scale > 0:
# _day_timer.wait_time = SECONDS_PER_DAY / scale
# else:
# printerr("TimeManager: Time scale must be positive.")