Godot 4.4 类型化字典:实现2D世界存档与方块编辑

发布时间:2026/9/4 12:55:18
Godot 4.4 类型化字典:实现2D世界存档与方块编辑 Godot 课程进入 Ep 2.5 之后很多读者会遇到同一个问题方块放下去很好看一旦要实现“世界存档”“重新加载”“右键移除”原来的场景树写法就不够用了。这一集用一个小而完整的 2D 世界编辑器来讲清楚世界存档不是把节点直接保存而是用“坐标到方块记录的映射”来组织数据Godot 4.4 提供的类型化字典可以在编码阶段就减少坐标和类型写错的概率右键移除工具也不是单纯删除一个场景节点而是需要先操作数据字典再同步移除显示层。学完这一篇你会完成一份可以保存为 JSON、可以重新读入、可以右键擦除方块的迷你存档系统。1. 世界存档的模型从“一堆节点”变成“键值映射”很多初学者第一次做“方块世界”时会把每个方块当成一个独立场景节点然后用数组保存节点引用。这个写法在十几二十个方块时还能撑住一旦方块数量增多或者需要在任意位置快速删除、查找、覆盖方块问题就会出现数组里删除一个元素往往要先查找坐标保存时又要遍历节点把位置数据从节点里扒出来。问题的根源是把“显示”和“数据”混在了一起。1.1 场景节点不是世界数据场景节点适合负责显示、动画、碰撞和交互但不适合直接当作存档数据。因为节点里除了坐标还包含材质、子节点、信号连接、脚本状态等大量运行时信息。如果你想保存一个“第 3 行第 5 列有一块草方块”最希望得到的数据是一行简单记录位置Vector2i(5, 3) 类型grass而不是一整棵节点树。真正的世界数据应该独立于场景节点存在随时可以序列化成文件也随时可以从文件还原成一组新的节点。这就是数据层和显示层分离的原因。1.2 使用字典结构表达坐标映射世界存档最典型的数据结构是字典。字典把“位置”当作键 key把“方块信息”当作值 value。在二维格子世界里一个格子可以表示为Vector2i(x, y)所以一张方块表就是world_cells: Dictionary[Vector2i, String] {} world_cells[Vector2i(3, 4)] grass world_cells[Vector2i(3, 5)] stone这里的意思是在 (3, 4) 这个格子放草方块在 (3, 5) 这个格子放石方块。如果需要判断某个坐标有没有方块直接使用world_cells.has(cell)删除不需要遍历数组直接使用world_cells.erase(cell)。1.3 为什么不用数组或普通列表为了弄清楚字典的不可替代性可以对比几种常见方案。数据容器查找某坐标是否占用按坐标删除存档转换成本适合场景Array[Vector2i]需要遍历或has判断语义不直观需要先找到下标再remove_at中等容易混入重复坐标不需要快速索引的小列表每个节点只保存位置互相遍历每帧遍历全部节点随数量增加变慢需要寻找坐标再删节点高保存时要遍历节点树不推荐作为主存档Dictionary[Vector2i, String]O(1) 复杂度直接按键访问直接按键删除低遍历键值即可写出世界范围查找和修改字典最大的优势是键本身携带坐标语义。查找、修改、删除都围绕同一个Vector2i进行不需要关心这组数据在列表里的顺序。这也是类型化字典的价值。GDScript 提供的Dictionary[Vector2i, String]会让编辑器在写代码时报出键类型或值类型不匹配的问题而不是等运行很久之后才因为某个坐标错误而崩溃。注意类型化字典是 Godot 4.4 开始逐步完善的写法。如果你的项目还在 Godot 4.0 到 4.3可以暂时把Dictionary[Vector2i, String]写成普通Dictionary不影响本期逻辑。2. 项目搭建先建立可运行的迷你测试场景这一部分会搭建一个最小项目用来验证“左键放置、右键移除、S 保存、L 加载”的完整流程。场景不需要美术资源直接用ColorRect画方块颜色即可。2.1 场景节点安排新建一个 Node2D 项目后场景树按下面的结构组织World (Node2