重构时间系统为回合制并新增主游戏场景

- TimeSystem 由实时天数推进改为按月回合制(advance_month),
  新增 turn_started/season_changed 信号,移除 GameState.day
- 新增 MainGame 场景及 HUD(时间显示、下一回合、返回主菜单)
- 新增 SaveSystem 存档组框架并注册为 Autoload
- 存档面板打开时隐藏新建槽按钮
- 窗口改为无边框,主场景切换为 MainGame
This commit is contained in:
2026-08-11 23:47:34 +08:00
parent 8399ee5664
commit 843f0cd53d
17 changed files with 408 additions and 130 deletions
+57
View File
@@ -0,0 +1,57 @@
## 存档系统(Autoload 单例)。
## 两级存档:存档组 SaveGroup(一个角色/一次轮回)→ 存档槽 SaveSlot(该组下任意多个进度快照)。
## 每个新游戏创建一个组;每次存档在该组下新建一个槽;组与槽数量无上限。
## 文件:user://saves/profile_{组id}/{auto|slot_{时间戳}}.json
extends Node
## 存档根目录。
const SAVE_ROOT := "user://saves"
## 存档组列表文件。
const PROFILES_PATH := "user://saves/profiles.json"
## 自动槽文件名(固定)。
const AUTO_SLOT := "auto"
## 存档格式版本(兼容迁移预留)。
const VERSION := 1
## 新建存档组(主菜单"新游戏"调用),返回组 id(名"存档N")。
func create_profile() -> int:
var profiles := _load_profiles()
var id := 1
for p in profiles:
id = maxi(id, int(p["id"]) + 1)
profiles.append({
"id": id,
"name": "存档%d" % id,
"created": Time.get_date_string_from_system(),
"last_date": "",
})
_save_profiles(profiles)
return id
## 读取存档组列表。
func _load_profiles() -> Array[Dictionary]:
if not FileAccess.file_exists(PROFILES_PATH):
return []
var f := FileAccess.open(PROFILES_PATH, FileAccess.READ)
if f == null:
return []
var parsed: Variant = JSON.parse_string(f.get_as_text())
if parsed is not Dictionary or not parsed.has("profiles"):
return []
var result: Array[Dictionary] = []
for p in parsed["profiles"]:
result.append(p)
return result
## 写入存档组列表。
## @param profiles: 存档组列表
func _save_profiles(profiles: Array[Dictionary]) -> void:
var da := DirAccess.open("user://")
if da != null:
da.make_dir_recursive("saves")
var f := FileAccess.open(PROFILES_PATH, FileAccess.WRITE)
if f == null:
return
f.store_string(JSON.stringify({"profiles": profiles}, "\t"))