从零开始的 Godot 之旅 — EP12:瓦片地图碰撞
在上一节中,我们掌握了如何创建和绘制瓦片地图(TileMap)。本节我们将进一步完善地图细节,重点学习如何为瓦片添加 碰撞检测 功能,让角色能够与环境产生真实的交互,并以此构建一个基础的游戏场景。
绘制一个简单的场景
为了让游戏世界更加生动,今天我们需要在之前创建的草地上添加一些道路、灌木、树木、花朵和石头等元素。
首先,选中之前的 TileMapLayer 节点,在草地上绘制一条笔直的泥土路。
接着,我们需要在道路两侧添加一些灌木丛和树木,让环境看起来更自然。
注意:我们需要新建一个 Layer(图层)来绘制这些装饰物。如果我们直接在现有的 TileMapLayer 上绘制,新绘制的图块会直接覆盖掉底层的草地或道路,导致视觉效果不正确(例如树木周围应该是草地,而不是透明或背景色)。
由于新的 Layer 将使用与之前相同的瓦片集(TileSet),为了方便复用,我们需要先将原 TileMapLayer 中的 TileSet 资源保存为独立文件。
点击 TileSet 属性旁边的下拉图标,选择 另存为 (Save As)。
将 .tres 文件存储到 maps/tres 目录下。
接下来,添加一个新的 TileMapLayer 节点,将其命名为 Tree,并将刚刚保存的 .tres 资源加载到该节点的 Tile Set 属性中。
选中新创建的 Tree 节点后,你会发现编辑器中其他的 Layer 都变暗了。这是一种视觉提示,表示我们当前只能编辑选中的 Layer,避免误操作。
现在我们可以将灌木和树木添加到场景中了。但在开始绘制之前,我们需要先调整一下图块的大小。
默认情况下,Godot 会将纹理自动切割成 16x16 的小图块。然而,我们的灌木、树木等素材尺寸往往大于 16x16。如果不进行调整,绘制时这些物体会被切割成多个碎片,不仅拼接麻烦,效果也容易出错。
调整 TileSet 图块大小
打开上节创建的 TileSet 面板。可以看到,Godot 之前自动在所有不透明区域生成了图块,但它们都被统一处理成了 16x16 的网格。
以灌木丛为例,它显然不是一个标准的 16x16 图块:
我们希望将整个灌木丛作为一个完整的图块来使用,而不是被切割成四块。因此,我们需要手动重新定义这些图块。
-
删除旧图块:在 TileSet 编辑器中,右键点击那些被错误切割的图块,将其删除。
删除后,原本图块的位置会显示为暗色遮罩,表示该区域目前没有定义图块。
-
创建大图块:按住
Shift键,使用鼠标左键框选整个灌木丛的区域。
这样,我们就成功创建了一个包含完整灌木丛的大型图块。
请使用同样的方法,将树木、石头、雕像等其他大型素材也重新创建一遍。
完成场景绘制
回到场景编辑器,继续丰富我们的地图。在 Tree 层上绘制灌木、树木、石头、花朵、雕像等元素。
细心的同学可能已经发现了问题:场景中某些图块的层叠关系看起来很别扭。例如,树木本应该在雕像的后方(视觉上被遮挡),或者角色站在树前时应该遮挡树干,站在树后时应该被树冠遮挡。但目前它们的遮挡关系是固定的,导致视觉效果不真实。
为了解决这个问题,我们需要启用 Y Sort(Y 轴排序) 功能。
选中需要参与排序的节点(如 TileMapLayer 节点),在右侧检查器中找到 Ordering -> Y Sort Enabled,勾选它。
勾选后,Godot 会根据节点(或图块)的 Y 轴坐标自动调整渲染顺序:Y 坐标较大的物体(位于屏幕下方,即“更近”)会覆盖 Y 坐标较小的物体(位于屏幕上方,即“更远”)。
设置碰撞
场景看起来已经相当不错了,但试玩一下你会发现,角色竟然可以“穿墙”——直接穿过树木、石头甚至房屋。这显然不符合物理规律。
接下来,我们将为角色和场景中的障碍物添加碰撞检测。
1. 给角色添加碰撞体
相信大家早就注意到了角色节点旁边的黄色警告图标。它在提示我们:该节点缺少描述物理形状的子节点,因此无法进行碰撞检测。
进入角色场景, 为角色添加一个 CollisionPolygon2D 节点。
小知识:CollisionPolygon2D vs CollisionShape2D
- CollisionShape2D: 只能使用预定义的基本形状(如矩形、圆形、胶囊形)。
- CollisionPolygon2D: 允许自定义任意多边形形状,更加灵活。
- 对于角色这种不规则形状,或者需要精确贴合脚底的碰撞区域,
CollisionPolygon2D往往更合适;而对于简单的箱子或墙壁,CollisionShape2D性能稍好且易于配置。
选中 CollisionPolygon2D,使用工具栏中的 添加点 工具,在角色脚底绘制一个菱形的碰撞区域(通常碰撞判定区只在脚底,以模拟伪 3D 的透视关系)。
2. 设置瓦片地图的碰撞
瓦片地图的碰撞需要在 TileSet 资源中统一设置。
-
添加物理层:选中
TileMapLayer节点,在右侧检查器的Tile Set属性中,找到 Physics Layers,点击 Add Element 添加一个物理层。添加后,Collision Layer(所在层)和 Collision Mask(监听层)暂时保持默认的 1 即可。
-
绘制碰撞区域:打开底部的 TileSet 编辑器,切换到 Select 模式(或直接在 Paint 模式下),找到 Physics Layer 0 属性。
选中灌木丛图块,按下
F键(或使用多边形工具),为它绘制碰撞区域。提示:同样地,碰撞区域通常只需要覆盖物体的“根部”,这样角色就可以在树冠后面行走,产生遮挡效果,而不是被树冠挡住去路。
按照同样的方法,为树木、石头等所有需要阻挡角色的图块添加碰撞区域。
测试效果
运行游戏,看看效果如何。
现在,角色已经被灌木丛稳稳地挡住了!
总结
本节我们学习了如何通过 Y Sort 解决层叠遮挡问题,并利用 Physics Layer 为瓦片地图添加了碰撞检测,成功让游戏世界具备了基本的物理规则。
在下一节中,我们将引入 摄像机(Camera2D) 及其跟随功能,让镜头随着角色的移动而移动,探索更广阔的地图。