HOME / 第 6 部分 · 数据与进阶开发 / 第 62 课
MODULE 6 · 数据与进阶开发

第 62 课 · 存档系统(Save/Load)

⏱ 预计时长 40 分钟📊 难度 进阶📚 模块 第 6 部分 · 数据与进阶开发

🎯 本课学习目标

让游戏进度「留下来」。本课实现完整的存档系统。

📖 详细教学步骤

存档设计设计

先想清楚要存什么:

  • 玩家:位置、生命值、金币
  • 游戏进度:已解锁关卡、最佳分数
  • 设置:音量、画质

把这些组织成一个字典结构最方便。

用 JSON 保存存档代码

JSON 是文本格式,人类可读、跨平台:

GDSCRIPTextends Node

func save_game(data: Dictionary, slot: int = 0):
    var path = "user://save_%d.json" % slot
    var file = FileAccess.open(path, FileAccess.WRITE)
    file.store_string(JSON.stringify(data))
    file.close()
    print("存档成功:", path)

func load_game(slot: int = 0) -> Dictionary:
    var path = "user://save_%d.json" % slot
    if not FileAccess.file_exists(path):
        return {}
    var file = FileAccess.open(path, FileAccess.READ)
    var text = file.get_as_text()
    file.close()
    var parsed = JSON.parse_string(text)
    return parsed if parsed is Dictionary else {}

构造存档数据代码

把游戏状态打包:

GDSCRIPTfunc build_save_data() -> Dictionary:
    return {
        "player": {
            "position": [player.global_position.x,
                         player.global_position.y],
            "hp": player.hp,
            "score": player.score,
        },
        "unlocked_level": game.unlocked_level,
        "time": Time.get_datetime_string_from_system(),
    }

读取存档恢复状态代码

读取并应用:

GDSCRIPTfunc apply_save_data(data: Dictionary):
    var p = data.get("player", {})
    if p:
        player.hp = p.get("hp", 3)
        player.score = p.get("score", 0)
        var pos = p.get("position", [0, 0])
        player.global_position = Vector2(pos[0], pos[1])
    game.unlocked_level = data.get("unlocked_level", 1)
    hud.update_hp(player.hp)
    hud.update_score(player.score)

接入快捷键与 UI集成

  • 创建存档/读取动作(F5 存、F9 读)
  • 主菜单加「继续游戏」「新游戏」按钮
  • 「继续游戏」→ 读取存档恢复;「新游戏」→ 清空存档

多存档位与自动存档进阶

扩展:

  • 多槽位:slot 参数(0-2)分别存不同档
  • 自动存档:到达检查点 / 通关时自动 save_game
  • 加密:Godot 4.3+ 可用 FileAccess 加密 API(进阶)
⚠️
JSON.parse_string 返回 null?

说明文件格式损坏或为空。保存前先 JSON.stringify,读取前判断 file_exists。

⚠️
存档位置找不到?

user:// 映射到系统用户目录。可在代码里 print(OS.get_user_data_dir()) 查看。

🧪 动手试一试

🏋️ 课后练习

实现「自动存档」:玩家吃到金币时自动保存,重新运行时恢复金币数与位置。

金币拾取 → save_game(build_save_data());启动 _ready 里 load_game + apply。

💡

JSON.stringify 带缩进参数(JSON.stringify(data, "\t"))便于人类查看调试。

💡

存档数据里别存节点引用,只存数值/数组,否则无法序列化。

🎓 本课小结

存档 = 字典结构 + JSON 序列化 + user:// 文件;save_game 打包状态、load_game 解析恢复;支持多槽位与自动存档。