[文章翻译] Godot3.0 中的autotile自动拼接(Autotiling in Godot 3.0)

·原文

在这里插入图片描述

Disclaimer 1: I am not the author of the autotiling functionality and I am not experienced enough to understand its source code. To write this tutorial, I basically played around with the functionality until I felt confident enough to explain it to others. There might still be errors in this tutorial. If you find any, please tell me!

Disclaimer 2: I am describing the autotiling functionality of Godot 3.0. It is still a little rough around the edges and I expect the functionality to change in the future.

I will first explain how Godot’s autotiling algorithm decides what tile to put where. Then I will explaing how to plan, set up and draw a new tileset. Last, I will show how to use autotiling in Godot.

The logic behind autotiling
We will consider tilesets with only two types of content: a background and a foreground. In a top-down game these could for example be water (background) and land/island (foreground). In a platformer they could be air/nothing (background) and solid walls (foreground). By clicking in the editor we want to place foreground tiles and by right-clicking we want to remove them and replace them by the background. We will call the foreground tiles “active” and the background tiles “inactive”.

So by clicking in the editor we would end up with a grid of active and inactive cells, such as this one (gray = active, white = inactive):

在这里插入图片描述

In addition to the active/inactive information in each cells, the algorithm also has information on each edge and on each corner. Similar to each cell, an edge and a corner can be active or inactive. However, we cannot directly toggle the edges’ and corners’ state in the editor. Their behavior is defined by the following logic:

· An edge is active, if both of the neighboring cells are active (and inactive otherwise)
· A corner is active, if all four of the neighboring cells are active (and inactive otherwise).

(Note: This logic is specific to the current implementation in Godot. It is also imaginable to have an editor which allows to edit the edges and corners directly.)

For the example grid above, we would get the following edge and corner data (green = active, white = inactive):

在这里插入图片描述

Next, the algorithm determines a so called bitmask for each cell. In Godot, there are currently two types of bitmasks available: 2×2 and 3×3. The 2×2 bitmask consists of the four corners of a cell, and the 3×3 bitmask consists of the four corners, the four edges and the cell itself. In Godot, the bitmasks are represented as small (2×2 or 3×3) grids of red (=active) and transparent (=inactive) squares. The following two images show the two types of bitmasks for our example.

2×2:

在这里插入图片描述

3×3:

在这里插入图片描述

Now, we are almost done. The autotiling module in Godot contains a list of tiles together with a bitmask for each one. To find the correct tile for a cell in the grid, it goes through all of the tiles and tries to find one that has the matching bitmask. If there are multiple tiles with the same matching bitmask, one tile is chosen randomly. If there is no tile with a matching bitmask, a default tile is selected.

Planning and drawing a tileset
Autotiling works best, if we have at least one tile for each possible bitmask. Otherwise, the algorithm might fall back to the default tile in some places and then the tile wouldn’t match perfectly. So, before drawing a tileset, it makes sense to make a list of all possible bitmasks.

In the 2×2-case, this is straight forward: The bitmask consists of 4 bits, so we get a total number of 2^4 = 16 bitmasks. We can nicely set the up in a small grid like this:

在这里插入图片描述

The precise order is not really important. I copied this arrangement from this great website about tiles.

Then, in our favorite image editing software, we can use such an image as a template. Just scale the template to the correct size, put it into the background and draw the tiles on top. Here is an example, how such a tileset could look like:

在这里插入图片描述

In the 3×3-case, everything is a bit more complicated. Having 9 bits, we theoretically get a list of 2^9 = 512 tiles. Fortunately, we do not have to draw all of them, because not all bitmasks are possible if we follow the cell-edge-corner logic explained above. Essentially, we can use the following simplifications:

·The center bit (the cell bit) is always active. Because if it is inactive, the tile will not be drawn.
·A corner can only be active, if the two adjacent edges are active.

Using these two simplifications, the number of relevant tiles reduces to 47. We will add a 48th tile to represent the pure background. We end up with the following collection of bitmasks:

在这里插入图片描述

This arrangement, again, is not my invention, but comes from this website. Check out this website to see an example tileset in this arrangement.

Using autotiling in Godot 3.0 – Step by step

  1. Find or draw a tileset that fits one of the two templates shown above. For testing you may use the 2×2 example from above or the tileset, I linked to.

  2. Create an empty scene. Insert a Node2D as a root node and then add the tileset image as a sprite.
    在这里插入图片描述

These are the properties of the sprite:

在这里插入图片描述

  1. Click Scene, Convert to, TileSet. Save the tileset in a tres file, for example, my_tileset.tres

在这里插入图片描述

You can now delete this scene. We will only use the created TileSet resource.

  1. Create a new scene. This will be the main scene. Add a Node2D as root and a tilemap.

在这里插入图片描述

Click on the tilemap. In its properties, go to the “Tile Set” Property and load the my_tileset.tres (or alternatively, drag it from the filesystem on the left and drop it onto the property)

在这里插入图片描述

  1. Click onto the tile set in the tilemap’s property to edit it. Activate the option “Is Autotile”.

在这里插入图片描述

  1. Open the Autotiles tab on the bottom.

在这里插入图片描述

  1. First select the bitmask mode (2×2 or 3×3) and enter the tile size (my tileset is a 2×2 tileset with a tile size of 100 x 100 and zero spacing).

在这里插入图片描述

  1. In the tab “icon” select one tile that is representative for the tileset. It will appear in the top left on the “palette” of tiles. The selected tile will also define the “default” tile. That is the one that is selected, if no matching bitmask is found.

在这里插入图片描述

  1. In the tab “bitmask” define the bitmasks as discussed above (“paint” everything red that is solid).

在这里插入图片描述

  1. Switch back to the tilemap (by clicking on it in the scene tree). One last thing, we need to adjust is the tile size in the tilemap:

在这里插入图片描述

  1. Thats it. You can start drawing now.

在这里插入图片描述

If you followed my steps and used the 2×2-tileset, you will notice that the tile will only be correct, if you place at least four tiles in a square. That is because of the tile selection logic, that I explained earlier. Overall, I suggest you use the 3×3-bitmask system. It will work better overall (with the downside that you have to draw many more tiles).

Conclusion
Thanks for reading. I hope you found the tutorial helpful. If you have any questions or suggestions please leave a comment.

In this tutorial, I have not covered, how to set up collision, occlusion and navigation with the autotiling module. I haven’t tried it myself, but I believe it is pretty much straight forward.

·翻译

在这里插入图片描述

声明1: 我不是autotiling功能的作者,也没有足够的经验来理解其源代码。在编写本教程时,我基本上是在学习这些功能,直到我有足够的信心向其他人解释它为止。本教程中可能仍然存在错误。如果你找到了,请告诉我!

声明 2:我正在描述 Godot 3.0 的autotiling功能。它在边缘处理上仍不完善,我希望将来功能会发生变化。

首先我将解释 Godot 的 autotiling 算法如何决定将哪个 tile 放置在何处。然后我将解释如何计划、设置和绘制一个新的tileset。最后,我将展示如何在 Godot 中使用autotiling。

autotiling 背后的逻辑
我们将考虑只有两种内容类型的图块集:背景(background) 和前景 (foreground)。例如,在自上而下的游戏中,这些可以是水(背景)和陆地/岛屿(前景)。在平台游戏中,它们可以是空气/无(背景)和实心墙(前景)。按照我们的想法在编辑器中通过单击放置图块,通过右键单击我们想要移除的图块并用背景替换它们。我们将前景图块称为“活动的”,将背景图块称为“非活动的”。

因此,通过在编辑器中单击,我们最终会得到一个由活动和非活动单元格组成的网格,例如这个(灰色 = 活动的,白色 = 非活动的):

在这里插入图片描述

除了每个单元格中的活动/非活动信息外,该算法还有关于每个边和每个角的信息。与每个单元格类似,边和角可以是活动的或非活动的。但是,我们不能在编辑器中直接切换边和角的状态。它们的行为由以下逻辑定义:

· 如果两个相邻单元都处于活动状态,则边缘处于活动状态(否则为非活动状态)。
· 如果所有四个相邻单元格都处于活动状态,则角点处于活动状态(否则为非活动状态)。.

(注意:此逻辑特定于 Godot 中的当前实现。允许直接编辑边角的编辑器也是可能存在的。)

对于上面的示例网格,我们将获得以下边和角数据(绿色 = 活动,白色 = 非活动):

在这里插入图片描述

接下来,算法为每个单元确定所谓的位掩码。在 Godot 中,目前有两种类型的位掩码可用:2×2 和 3×3。2×2 位掩码由单元格的四个角组成,3×3 位掩码由四个角、四个边和单元格本身组成。在 Godot 中,位掩码表示为红色(=活动)和透明(=非活动)方块的小(2×2 或 3×3)网格。以下两个图像显示了我们示例的两种类型的位掩码。

2×2:

在这里插入图片描述

3×3:

在这里插入图片描述

现在,我们差不多完成了。Godot 中的自动拼贴模块包含一个拼贴列表以及每个图块的位掩码。要为网格中的单元格找到正确的图块,它会遍历所有图块并尝试找到具有匹配位掩码的图块。如果有多个瓦片具有相同的匹配位掩码,则随机选择一个瓦片。如果没有具有匹配位掩码的图块,则选择默认图块。

规划和绘制图块集(tileset)
如果我们为每个可能的位掩码对应一个图块,则自动拼接的效果最好。 否则,算法可能会在某些地方回退到默认图块,然后图块将无法完美匹配。因此,在绘制图块集之前,有必要列出所有可能的位掩码。

在 2×2 的情况下,这是直接的:位掩码由 4 位组成,因此我们总共得到 2^4 = 16 个位掩码。
我们可以在一个小网格中很好地设置,如下所示:
在这里插入图片描述

确切的顺序并不重要。我从一个关于tiles的网站复制了这个设置。

然后,在我们最喜欢的图像编辑软件中,我们可以使用这样的图像作为模板。只需将模板缩放到正确的大小,将其放入背景中并在上面绘制瓷砖。这是一个例子,这样的图块集看起来像:

在这里插入图片描述

在 3×3 的情况下,一切都有些复杂。有 9 位,理论上我们得到 2^9 = 512 个瓦片的列表。幸运的是,我们不必绘制所有这些,因为如果我们遵循上面解释的单元格边缘角逻辑,则并非所有位掩码都是可能的。从本质出发,我们可以使用以下简化:

·中心位(单元位)始终处于活动状态。因为如果它处于非活动状态,则不会绘制图块。
·如果两个相邻边处于活动状态,则角只能处于活动状态

使用这两个简化,相关图块的数量减少到 47 个。我们将添加第 48 个图块来表示纯背景。我们最终得到以下位掩码集合:

在这里插入图片描述

同样,这种安排不是我的发明,而是来自 这个网站。查看此网站以查看此排列中的示例图块集。

一步一步地在 Godot 3.0 中使用自动拼接

  1. 找到或绘制一个适合上面显示的两个模板之一的图块集。为了进行测试,您可以使用上面的 2×2 示例或图块集。链接

2)创建一个空场景。插入 Node2D 作为根节点,然后添加图块集图像作为sprite。
在这里插入图片描述

这些是sprite的属性:

在这里插入图片描述

  1. 单击场景、转换为、图块集。将tileset保存在tres文件中,例如my_tileset.tres

在这里插入图片描述

你现在可以删除此场景。我们将只使用创建的 TileSet 资源。

  1. 创建一个新场景。这将是主要场景。添加一个 Node2D 作为根节点和一个 tilemap。

在这里插入图片描述

单击tilemap。在其属性中,转到“TileSet”属性并加载 my_tileset.tres(或者,将其从左侧的文件系统拖放到属性上)

在这里插入图片描述

  1. 单击在tilemap 属性中设置的tile以对其进行编辑。激活选项“is Autotile”。
    在这里插入图片描述

  2. 打开底部的 Autotiles 选项卡。

在这里插入图片描述

  1. 首先选择位掩码模式(2×2或3×3),输入tile size(我的tileset是2×2的tileset,tile size为100 x 100,零间距)。

在这里插入图片描述

  1. 在“icon”选项卡中选择一个代表图块集的图块。它将出现在瓷砖“palette”的左上角。选定的瓷砖也将定义“default默认”瓷砖。如果没有找到匹配的位掩码,那就是被选中的那个。

在这里插入图片描述

9)在“位掩码Bitmask”选项卡中,如图所述定义位掩码(将所有实体“涂成”红色)。

在这里插入图片描述
10) 切换回tilemap (通过在场景树中点击它)。最后一件事,我们需要调整瓦片地图中的瓦片大小:

在这里插入图片描述

  1. 就是这样。现在就可以开始画了。

在这里插入图片描述

如果你按照我的步骤操作并使用 2×2-tileset,你会注意到,只有在平面中放置至少四个图块时,图块才会正确。那是因为我之前解释过的磁贴选择逻辑。总的来说,我建议你使用 3×3-bitmask 系统。整体效果会更好(缺点是你必须绘制更多图块)。

总结
谢谢阅读。希望本教程对您有所帮助。如果你有任何问题或建议,请发表评论。

在本教程中,我没有介绍如何使用 autotiling 模块设置碰撞、遮挡和导航。我自己还没有尝试过,但我相信它非常简单。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值