GDScript 入门笔记(十六):文件读写与数据持久化

游戏需要保存进度、读取配置、加载存档,这些都离不开文件读写。在 Godot 里,处理文件的核心类是 FileAccess,配合 JSON、ConfigFile 等工具可以很方便地实现数据持久化。这篇笔记整理我常用的文件操作和持久化方案,覆盖从简单的文本读写到结构化数据存储。

一、文件读写基础:FileAccess

Godot 4 使用 FileAccess 类来读写文件。它取代了 Godot 3 中的 File 类。基本流程是:打开文件 → 读写内容 → 关闭文件。

1. 写入文本文件

用 FileAccess.open() 打开文件,指定路径和模式。模式有:

  • FileAccess.WRITE:写入模式,会覆盖已有内容
  • FileAccess.READ:读取模式
  • FileAccess.READ_WRITE:读写模式
  • FileAccess.APPEND:追加模式

写入文本:

gdscript 复制代码
var file = FileAccess.open("user://save.txt", FileAccess.WRITE)
if file:
    file.store_string("Hello Godot\n")
    file.store_string("第二行内容")
    file.close()
else:
    print("打开文件失败")

注意:使用 user:// 前缀表示用户数据目录,这是保存游戏存档和配置的推荐位置,不同平台会映射到对应的可写目录(比如 Windows 的 %APPDATA%,Android 的沙盒目录)。

2. 读取文本文件

读取整个文件内容:

gdscript 复制代码
var file = FileAccess.open("user://save.txt", FileAccess.READ)
if file:
    var content = file.get_as_text()
    print(content)
    file.close()
else:
    print("文件不存在或无法读取")

逐行读取:

gdscript 复制代码
var file = FileAccess.open("user://save.txt", FileAccess.READ)
if file:
    while not file.eof_reached():
        var line = file.get_line()
        print(line)
    file.close()

3. 检查文件是否存在

使用 FileAccess.file_exists() 静态方法。

gdscript 复制代码
if FileAccess.file_exists("user://save.txt"):
    print("存档存在")

二、存储路径说明

Godot 中有两种路径前缀:

  • res://:资源目录,指向项目文件夹,只读(在导出后不可写)。用于读取游戏自带资源。
  • user://:用户数据目录,可读写,用于保存存档、配置、截图等。

永远不要把存档写入 res:// ,导出后这会失败或没有权限。保存数据一律用 user://。

三、JSON 持久化

JSON 是最常用的数据交换格式,适合存储结构化数据,比如玩家属性、背包内容、设置选项等。Godot 内置了 JSON 类。

1. 将字典写入 JSON 文件

gdscript 复制代码
var data = {
    "player_name": "Tom",
    "level": 5,
    "health": 100,
    "inventory": ["sword", "potion", "shield"]
}

var file = FileAccess.open("user://save.json", FileAccess.WRITE)
if file:
    file.store_string(JSON.stringify(data, "\t"))
    file.close()

JSON.stringify() 将字典转换成 JSON 字符串,第二个参数是缩进(可选),方便阅读。

2. 从 JSON 文件读取

gdscript 复制代码
var file = FileAccess.open("user://save.json", FileAccess.READ)
if file:
    var content = file.get_as_text()
    var data = JSON.parse_string(content)
    if data != null:
        print(data["player_name"])
        print(data["inventory"])
    file.close()

JSON.parse_string() 返回字典或数组,如果格式错误返回 null。

3. 注意事项

  • JSON 中的数字会被解析为 float,如果需要整数,记得用 int() 转换。
  • JSON 不支持 Vector2、Color 等自定义类型,需要手动转换(存成分量或字符串)。
  • 存档数据较多时,JSON 文件可读性好,但体积和加载速度不如二进制。

四、ConfigFile 配置存储

ConfigFile 是 Godot 提供的一种类似 INI 的格式,适合保存设置和键值对。它自动处理类型,读写方便。

1. 写入配置

gdscript 复制代码
var config = ConfigFile.new()
config.set_value("player", "name", "Tom")
config.set_value("player", "level", 5)
config.set_value("audio", "volume", 0.8)

var err = config.save("user://settings.cfg")
if err == OK:
    print("配置保存成功")

set_value(section, key, value) 将值存入指定分段。

2. 读取配置

gdscript 复制代码
var config = ConfigFile.new()
var err = config.load("user://settings.cfg")
if err == OK:
    var player_name = config.get_value("player", "name", "默认名字")
    var volume = config.get_value("audio", "volume", 1.0)
    print(player_name, volume)
else:
    print("配置文件加载失败")

get_value(section, key, default) 如果键不存在,返回默认值,避免崩溃。

3. ConfigFile 的优势

  • 自动处理类型(不需要手动转换)
  • 支持分组,结构清晰
  • 读写简单,适合游戏设置

我通常用 ConfigFile 存设置,用 JSON 存复杂存档。

五、二进制文件读写

对于需要高效存储或数据量大的情况(比如地图、关卡数据),可以使用二进制方式。FileAccess 提供了多种方法:

  • store_8(), store_16(), store_32(), store_64()
  • store_float(), store_double()
  • store_buffer() 写入字节数组

读取对应 get_8(), get_16(), get_float() 等。

示例:写入和读取整数数组

gdscript 复制代码
var numbers = [10, 20, 30, 40]

# 写入
var file = FileAccess.open("user://data.bin", FileAccess.WRITE)
if file:
    for n in numbers:
        file.store_32(n)
    file.close()

# 读取
var loaded_numbers = []
var file2 = FileAccess.open("user://data.bin", FileAccess.READ)
if file2:
    while not file2.eof_reached():
        loaded_numbers.append(file2.get_32())
    file2.close()

注意二进制文件不可读,必须按写入时的顺序和类型读取。

六、目录操作

除了文件,有时需要创建或遍历目录。DirAccess 类处理目录。

创建目录

gdscript 复制代码
var dir = DirAccess.open("user://")
if dir:
    dir.make_dir("saves")

遍历目录下的文件

gdscript 复制代码
var dir = DirAccess.open("user://saves")
if dir:
    dir.list_dir_begin()
    var file_name = dir.get_next()
    while file_name != "":
        if not dir.current_is_dir():
            print("文件:", file_name)
        file_name = dir.get_next()
    dir.list_dir_end()

七、实际应用:保存和加载游戏进度

结合前面知识,写一个简单的存档系统:

gdscript 复制代码
extends Node

var save_path = "user://save_game.json"

func save_game(player_data: Dictionary):
    var file = FileAccess.open(save_path, FileAccess.WRITE)
    if file:
        file.store_string(JSON.stringify(player_data, "\t"))
        file.close()
        print("游戏已保存")

func load_game() -> Dictionary:
    if not FileAccess.file_exists(save_path):
        return {}
    var file = FileAccess.open(save_path, FileAccess.READ)
    if file:
        var content = file.get_as_text()
        var data = JSON.parse_string(content)
        file.close()
        if data is Dictionary:
            return data
    return {}

func _ready():
    # 保存示例
    var player = {
        "name": "Tom",
        "level": 3,
        "position": [10.5, 20.0],
        "inventory": ["sword", "potion"]
    }
    save_game(player)

    # 加载示例
    var loaded = load_game()
    if loaded:
        print("加载玩家:", loaded["name"], "等级:", loaded["level"])

八、总结

文件读写和持久化是游戏开发的基本功。在 Godot 中:

  • 用 FileAccess 读写文件,注意使用 user:// 路径
  • 简单文本用 store_string / get_as_text
  • 结构化数据用 JSON,方便读写和调试
  • 设置类数据用 ConfigFile,自动处理类型
  • 大量二进制数据用 store_32 等方法

建议从小项目开始就养成良好的存档习惯,避免后期重构。下一篇我们进入 GDScript 的最后一个基础主题:资源与引用,或者也可以开始实战小项目。

相关推荐
Wang's Blog10 小时前
Java 项目实战: 交友项目:登录链路回顾与今日任务地图
java·开发语言·状态模式·交友
砚底藏山河10 小时前
python量化:行情数据回溯
java·开发语言·python·金融·maven
今年下半年10 小时前
AI智能体项目实战记录(02):初始化 Python 项目
开发语言·人工智能·python·fastapi
Williamtym10 小时前
PickGo Lab实践:用浏览器、Python和MCP串起机器人搬运仿真
开发语言·python·机器人
DongQiShanRen11 小时前
六根硬件映射(四):归属澄清、两处不一致与卷十一总表
开发语言·人工智能·算法·rust·哈希算法·集成学习
CS创新实验室11 小时前
Python 对象“死“了之后去了哪?——引用计数与分代垃圾回收
开发语言·jvm·python
quantdash_cc11 小时前
Pandas 处理分钟级股票行情:从原始数据清洗到 K 线聚合
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
yu_zhidun11 小时前
企业电脑监控软件怎么选:别只看功能清单,先看这 6 个底层能力
开发语言·电脑·php·域智盾系统
无忧.芙桃12 小时前
C++语言原理与实践(十六):多态机制讲解
开发语言·c++·多态
优选资源分享12 小时前
PicGo v3.0.3 新版 | 开源免费图床工具
javascript·笔记·electron