## 全局时间系统(Autoload 单例)。 ## 负责游戏时间的推进与播报,仅在世界场景中运行。 ## 历法:12 月 × 30 日 = 360 日/年。 extends Node ## 每当推进一日后发出。 ## @param year: 当前年份 ## @param month: 当前月份(1-12) ## @param day: 当前日(1-30) signal day_passed(year: int, month: int, day: int) ## 每当进入新月份时发出(同一天内 day_passed 之后)。 ## @param year: 当前年份 ## @param month: 当前月份(1-12) signal month_passed(year: int, month: int) ## 每当进入新年份时发出(同一天内 month_passed 之后)。 ## @param year: 当前年份 signal year_passed(year: int) ## 时间流速档位变化时发出。 ## @param speed_index: 新档位在 SPEEDS 中的索引 signal speed_changed(speed_index: int) ## 暂停状态变化时发出。 ## @param paused: 是否已暂停 signal pause_changed(paused: bool) ## 可选的时间流速倍率档位。 const SPEEDS := [1.0, 5.0, 20.0] ## 每月的天数。 const DAYS_PER_MONTH := 30 ## 每年的月数。 const MONTHS_PER_YEAR := 12 ## 现实世界每 1 天对应的时长(秒)。 const DAY_LENGTH := 0.5 ## 当前流速档位在 SPEEDS 中的索引。 var speed_index := 0 ## 当前流速倍率(与 SPEEDS[speed_index] 保持一致)。 var speed := 1.0 ## 是否暂停时间推进。 var paused := false ## 已累积的现实时间(秒),未满 1 天。 var _elapsed := 0.0 func _process(delta: float) -> void: if paused or not _is_in_game(): return _elapsed += delta * speed if _elapsed >= DAY_LENGTH: _elapsed -= DAY_LENGTH _advance() ## 判断当前场景是否为游戏世界场景(主菜单/存档界面不推进时间)。 func _is_in_game() -> bool: var scene := get_tree().current_scene return scene != null and scene.name == "MainGame" ## 推进一日并广播对应信号,跨月/跨年时补发 month_passed / year_passed。 func _advance() -> void: var new_month := false var new_year := false GameState.day += 1 if GameState.day > DAYS_PER_MONTH: GameState.day = 1 GameState.month += 1 new_month = true if GameState.month > MONTHS_PER_YEAR: GameState.month = 1 GameState.year += 1 new_year = true day_passed.emit(GameState.year, GameState.month, GameState.day) if new_month: month_passed.emit(GameState.year, GameState.month) if new_year: year_passed.emit(GameState.year) ## 循环切换下一档流速,返回新倍率。 func cycle_speed() -> float: speed_index = (speed_index + 1) % SPEEDS.size() speed = SPEEDS[speed_index] speed_changed.emit(speed_index) return speed ## 直接设置流速档位(越界自动钳制)。 ## @param index: 目标档位索引 func set_speed_index(index: int) -> void: speed_index = clampi(index, 0, SPEEDS.size() - 1) speed = SPEEDS[speed_index] speed_changed.emit(speed_index) ## 切换暂停状态,返回切换后的暂停状态。 func toggle_pause() -> bool: paused = not paused pause_changed.emit(paused) return paused ## 显式设置暂停状态(幂等,状态未变化时不发信号)。 ## @param value: 目标暂停状态 func set_paused(value: bool) -> void: if paused == value: return paused = value pause_changed.emit(paused) ## 当前流速的显示文本,如 "x5"。 func get_speed_label() -> String: return "x%d" % int(speed) ## 当前日期数组 [年, 月, 日]。 func get_current_date() -> Array: return [GameState.year, GameState.month, GameState.day] ## 当前日期文本,如 "3年 5月 12日"。 func get_date_text() -> String: return "%d年 %d月 %d日" % [GameState.year, GameState.month, GameState.day] ## 直接设置日期(供读档/测试使用)。 ## @param y: 年 ## @param m: 月(1-12) ## @param d: 日(1-30) func set_date(y: int, m: int, d: int) -> void: GameState.year = y GameState.month = m GameState.day = d