使用 TileMap
前言
图块地图是用于创建游戏布局的图块网格. 使用 TileMap 节点设计关卡有很多好处. 首先, 它们可以通过将图块 “绘制” 到网格上来绘制布局, 这比逐个放置单个 Sprite 节点快得多;其次, 它们允许更大的关卡, 因为它们针对绘制大量图块进行了优化. 最后, 您可以为图块添加碰撞, 遮挡和导航形状, 从而为图块地图添加其他功能.
项目设置
这个演示将使用来自Kenney的 “抽象平台游戏” 艺术包的素材。在 这里 可以找到完整的包,但对于当前演示只使用部分素材。
创建一个新项目并将上面的图像放置在项目文件夹中.
使用图块集时, 相邻的图块匹配很重要. Godot的默认设置是使用插值的 “滤镜(Filter)” 模式导入2D图像, 这将导致图块之间的边界很丑. 选择图像, 然后单击 “导入(Import)” 选项卡. 关闭 Filter
, 然后单击 “重新导入”. 有关详细信息, 请参见 导入图像 .
TileMap节点
在场景中添加一个新的 TileMap 节点. 默认情况下,TileMap使用正方形的图块网格. 您还可以使用基于透视图的 “Isometric” 模式或定义自己的自定义图块形状.
在属性面板的 “Cell” 部分下, 有许多属性可以调整, 自定义图块贴图的行为:
Cell Size
这定义了网格的大小。这应与您的图块的像素大小匹配。默认为
(64,64)
。YSort
这将导致以
Y
(竖直方向)位置的顺序绘制图块, 这样的话 “较低” 图块的绘制覆盖在 “较高” 图块的上面.Half Offset
和Tile Origin
这些属性影响图块相对于网格的位置.
Quadrant
定义用于批处理绘图的块大小. 这可能会对性能产生负面影响. 除非你知道你在做什么, 否则不要改变它.
Custom Transform
用来改变图块的形状. 如果您有非正方形的图块, 请使用此选项.
在这个演示中, 所有这些选项都可以保持默认值.
创建 TileSet
一旦你配置好你的TileMap, 是时候添加一个 TileSet 了.TileSet是一个 Resource , 它包含了图块的所有数据——纹理, 碰撞形状(Collision Shape)和其他属性. 当游戏运行时,TileMap 将独立的图块合并成一个对象.
若要添加新TileSet, 请单击”Tile Set”属性并选择” 新建 TileSet(New TileSet)”.
单击TileSet属性,”TileSet” 面板将在编辑器窗口底部打开:
首先, 您需要添加用于砖块的纹理. 点击”Add Texture(s) to TileSet(添加纹理到磁贴集)”按钮, 选择 tilesheet.png
的图片.
接下来, 点击”New Single Tile(新建图块)”, 在图像中拖动来选择你想要的图块. 单击”Enable Snap(启用吸附)”按钮可以更容易地选择整个砖块. 一个黄色矩形会出现在选定的图块区域周围.
单击场景树中的TileMap, 你会看到新创建的图块现在出现在右侧. 单击视窗, 你就可以放置图块. 右键单击以删除它们.
很容易发生意外地选择和移动TileMap节点的情况. 为了避免这种情况, 使用节点的锁定按钮:
碰撞形状
如果你在制作需要碰撞体积的地图——墙壁, 地板, 或其他障碍——你需要添加collision shape到任何你想被认为是 “实心的” 图块上.
点击编辑器窗口底部的 “TileSet”, 返回到图块集工具. 点击你之前定义的图块(黄色勾勒). 选择 “碰撞” 选项卡, 点击 “创建一个新的矩形” 按钮. 确保你仍然启用了网格吸附, 然后点击并拖入图块. 一个正方形的碰撞形状将出现在浅蓝色当中:
你也可以以相同的方式向图块添加occlusion shapes(光线遮挡形状)和navigation shapes(导航形状).
图集图块
除了逐个添加单独图块之外,你还可以通过图集(Atlas)来一次定义一组图块。这样你就可以从这一组图块中随机生成图块了。
点击“新建图集”然后把整张图块表(Tile Sheet)拖进去。
如果你还没有设置, 请确保将Snap Options中的 “Step” 更改为 (64, 64) 或者别的适合你图块的大小. 你可以在属性面板中找到它:
定义好图集之后,你就可以和之前一样单独为每一个图块添加碰撞形状。你还可以点击“图标”,挑选用来代表这个图集的图块。
回到 TileMap,选中图集图块后就可以看到它所包含的所有图块:
除了节省定义图块的时间外,这还可以帮你在处理大量图块时将类似的图块分组在一起。
随机图块优先级
使用图集图块进行绘制时,启用“使用优先级”选项会导致随机选择图块。默认情况下,图块集中所有图块出现的可能性都相等。你可以通过为每个图块设置不同的优先级来调整可能性的大小。例如,优先级为 2 的图块被选择的可能性是优先级为 1 的图块的两倍,优先级为 3 的图块被选择的可能性比优先级为 2 的图块多 50%。
自动图块
自动图块允许你定义一组图块,然后添加规则以根据相邻单元格的内容来控制使用哪个图块进行绘制。
点击“新建自动图块”然后框选你想要的图块。你可以使用和图集图块一样的方法来设置碰撞、遮罩、导航形状、图块优先级、以及设置图块图标。
图块的选择由位掩码(Bitmask)控制。点击“位掩码”,然后在图块上点击不同的位置就可以添加或者删除掩码(Mask)的位(Bit),从而设置位掩码。在图块上的对应区域单击左键可以添加位,单击右键则是删除“off”,按住 Shift 单击左键可以设置“ignore(忽略)”位。
Godot 使用自动图块更新某个单元格时,会首先根据周围单元格的填充情况创建模式,并在这个自动图块中查找位掩码与该模式相符的图块。如果没有找到相符的位掩码,就会用作为“图标”的那个图块。如果相符的图块不止一个,就会根据图块优先级进行随机选择。
位掩码与模式的匹配规则取决于图块集的自动图块位掩码模式(Autotile Bitmask Mode),可以在“检查器”面板的“Selected Tile(所选图块)”下设置。可设定的值有“2x2”“3x3 (minimal)”以及“3x3”。
位掩码中设为“on”和“off”的位必须一致才能匹配成功,而“ignore”的位会被忽略。
2x2
在 2x2 模式下,每个位掩码包含 4 个位,对应 4 个角。
对于设为“on”的位元,所有连接到该角落的图块格都必须以相同的自动图块来填满,才能与匹配该位掩码。举例来说,若设定了左上角的位元,则正上方、正左方、斜左上方的图块格都必须要被填满。
对于设为“off”的位元,则至少有一个连接到该角落的图块格不能使用相同的自动图块来设定。
要使用的图块都必须要设定至少一个位元。因此,对每个要测试该模式的图块排列,都必须要设定总共 15 格图块来提供刚好一个的图块。
2x2 模式只能对应到 2 乘 2 区块中的图块格——也就是周围没有其他图块格的图块格,且不支持边长只有 1 的图块格。
模板——通用:
此模板可用于侧视角或完全的俯视角。每一个 TileMap 图块格的尺寸是 64x64。
图例:
红色:“on”
白色:“off”
3x3 (minimal)
3x3 (minimal) 模式中,每个位掩码都包含了 9 个位元(4 个角落、4 个边缘、1 个中央)。4 个角落的位元的运作方式与 2x2 模式相同。
当边缘位为“on”时,必须填充共享该边缘的单元。当边沿位为“off”时,共享该边沿的单元格必须为空。
对于任何你想要使用的图块,中心位应该是“on”。注意,在这种模式下,当相邻的任何一个边位都不是“on”时,让一个角位“on”是没有意义的。
总共需要 47 个图块,才能为该模式可以测试的每种设置提供一个精确的位掩码。
注解
右键单击图像并选择 图片另存为… 来保存它。
模板——通用:
该模板可用于侧视角或俯视角。下面的所有模板都是专为 64x64 的 TileMap 单元格尺寸设计的,但对于俯视角的模板,您可能需要使用不同的子图块尺寸。
图例:
红色:“on”
白色:“off”
模板——16 图块通用:
该模板可用于仅包含 16 个图块的图块集——在更简单的艺术风格下,缺失的图块并不明显。
图例:
红色:“on”
白色:“off”
蓝白格:“忽略”
模板——3/4 俯视角地面:
图例(以下四个模板均适用):
绿色:地面
青色:墙面
黄色:墙顶
灰色:由于重叠而隐藏
透明:空气
模板——3/4 俯视角墙面:
模板——3/4 俯视角墙面(厚墙):
使用此模板时,请将图块集子图块大小设置为 Vector2(64, 88)
。
模板——3/4 俯视角墙面(高墙):
使用该模板时,请将“Snap Options(吸附选项)”中的 Step(步长)设置为 Vector2(64, 184)
,“Selected Tile(选定图块)”纹理偏移为高度减去单元格大小。这意味着纹理偏移应该是 Vector2(0, -120)
:
3x3
在 3x3 模式下,每个位掩码包含 9 个位元(4 个角、4 个边、1 个中心)
每个位都会检查一个相邻的单元格。角位只检查对角线相邻的单元格。对于您想使用的任何图块,中心位应该是“on”。
总共需要 256 个图块,才能为该模式可以测试的每种排列提供准确的一个位掩码。
禁用自动图块
使用自动图块时,可以通过单击图块选择窗口顶部的“禁用自动图块”来关闭自动图块行为,并手动选择图块。
自动图块绑定
默认情况下,自动图块只检查使用相同自动图块填充的相邻单元格。这种行为可以被覆盖,以便让自动图块相互绑定,甚至绑定到空单元格。目前,这只能通过脚本来实现。你需要添加一个脚本到你的图块集,并定义一个名为“_is_tile_bound(drawing_id, neighbor_id)”的函数。此函数将适用于每个不包含相同自动图块的相邻单元格,如果你想让绘制的单元格“绑定”到相邻的单元格,那么这个函数应该返回 true。你可以使用“find_tile_by_name(name)”查找自动图块的 ID,空单元格的 ID 为 -1。
注意,要在编辑器中使用的脚本应该以“tool”声明开始,并且您可能需要关闭并重新加载场景,以便这些更改生效。
提示和技巧
如果你使用 Camera2D 来滚动显示关卡,你可能会注意到图块之间出现了线条。要解决这个问题,请打开项目设置,并在 Rendering > 2d > Snapping(渲染 > 2d > 吸附)中启用 Use Gpu Pixel Snap(启用 GPU 像素吸附)。
您可以使用编辑器右上方的图标来翻转和旋转图块。
要绘制直线,请在点击并拖动图块时按住 Shift。
可以在右上角的“TileMap”菜单中找到复制、粘贴、油漆桶填充等工具。