103 lines
3.4 KiB
GDScript
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.is_game_paused():
|
|
# 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.")
|