Using TileMaps

簡介

圖塊地圖 (TileMap) 是一組用來建立遊戲畫面的圖塊 (Tile) 網格。使用 TileMap 來設計關卡有許多的好處。首先,通過圖塊地圖便能通過將圖塊「畫」到網格上來繪製畫面,比起通過一個一個將 Sprite 節點放到畫面上來說快多了。再來,通過圖塊地圖也能製作更大的關卡,因為圖塊地圖有為繪製大量網格進行最佳化。最後,也可以給圖塊地圖加上碰撞區域、遮擋、圖塊的導航區域,且可以為 TileMap 新增額外的功能。

../../_images/tileset_draw_atlas.png

設定專案

本處的示範專案使用了來自 Kenney 製作的「Abstract Platform」藝術包中的下列網格。可以在 此處 找到該藝術包中所有的網格,但本處的示範專案只會使用一小部分。

../../_images/tilesheet.png

建立新專案,並將上述圖片放在專案資料夾中。

在使用圖塊集時,進行調整讓相鄰的圖塊對齊很重要。Godot 預設會使用插值「Filter」模式來匯入 2D 圖片,該模式會導致圖塊間的邊框變得很醜。請選擇圖片,然後點擊匯入分頁。關閉 Filter 然後點擊「重新匯入」。詳情請參考 匯入圖片

TileMap 節點

在場景內新增新的 TileMap 。預設情況下,TileMap 會使用正方形的圖塊網格。也可以使用基於透視的「Isometric」模式,或自定客製化的圖塊形狀。

../../_images/tilemap_mode.png

在屬性面板的「Cell」段落中,有許多可以調整並客製化圖塊地圖行為的屬性:

../../_images/tilemap_size.png
  • Cell Size

    定義網格的大小。該選項應符合網格的像素大小。預設值為 (64, 64)

  • YSort

    開啟該屬性會讓圖塊以其 Y 位置順序繪製,而「較低」的圖塊會繪製在「較高」的圖塊上方。

  • Half OffsetTile Origin

    這些屬性會影響圖塊相對於網格的位置。

  • Quadrant

    定義用於批次繪製的區塊大小。該屬性可能會對效能有負面映像。除非你知道正在做什麼,否則請不要更改該屬性。

  • Custom Transform

    用於更改圖塊的形狀。若想使用非正方形的圖塊請更改此屬性。

在本示範專案中,可將所有選項保留為預設值。

建立 TileSet

設定好 TileMap 後,就可以來新增 TileSet 了。TileSet 時一個包含了有關圖塊所有資料的 Resource —— 包含圖塊的紋理貼圖、碰撞區域、形狀與其他屬性。在執行遊戲的時候,TileMap 會將各個圖塊整合成單一物件。

若要建立新 TileSet,請點擊「Tile Set」屬性然後選擇「New TileSet」。

../../_images/tilemap_add_tileset.png

點擊 TileSet 屬性,會在編輯器視窗的下方開啟「TileSet」面板:

../../_images/tilemap_tool.png

首先,我們需要加上用於圖塊的紋理貼圖。點擊「Add Texture(s) to TileSet」按鈕,然後選擇 tilesheet.png 圖片。

接下來,點擊「New Single Tile」,然後將拖移圖片來選擇想要的圖塊。點擊「啟用吸附」按鈕來更輕鬆地選擇整個圖塊。所選圖塊的周圍會顯示黃色的矩形。

../../_images/tilemap_add_tile.png

點擊場景樹中的 TileMap,然後我們會看到新建立的圖塊顯示於右側。點擊檢視區然後放上圖塊。右鍵點擊來移除圖塊。

../../_images/tilemap_draw.png

很容易不小心選擇並移動到 TileMap 節點。要避免不小心點到 TileMap,可以使用節點的鎖定按鈕:

../../_images/tile_lock.png

碰撞形體

若要建立需要碰撞的圖塊地圖 —— 如牆壁、地板或其他障礙物 —— 則需要將碰撞區域加到任何「實心」圖塊上。

點擊編輯器視窗下方的「TileSet」按鈕來回到 TileSet 工具。點擊剛才定義的圖塊 (以黃色外框顯示的)。選擇「碰撞」分頁,然後點擊「建立新矩形」按鈕。請確保有開啟網格吸附,然後點擊並拖曳圖塊。正方形的碰撞區域會以淡藍色顯示:

../../_images/tileset_add_collision.png

也可以通過同樣的方法來為圖塊加上遮擋區域與導航區域。

圖塊合集 (Atlas Tile)

比起一個一個新增圖塊,也可以通過合集來一次定義一組圖塊。這樣一來便能通過群組來隨機產生圖塊。

點擊「新增合集」然後拖移並選擇整個圖塊表。

../../_images/tileset_atlas.png

如果還沒將吸附設定中的「Step」改為 (64, 64) 的話,請先修改該屬性,否則圖塊切成小塊的。可以在屬性面板中找到該屬性:

../../_images/tileset_snap.png

定義好合集後,便可以像之前一樣為個別圖塊加上碰撞區域。也可以點擊「圖示」並選擇一個圖塊來代表該合集。

回到 TileMap,可以選擇合集圖塊,然後可以看到該合集內包含的所有圖塊:

../../_images/tileset_draw_atlas.png

除了能在定義圖塊時節省時間,通過合集圖塊也能在需要處理大量圖塊時將類似的圖塊放在同一個群組內。

隨機圖塊優先級

繪製合集圖塊時,若有開啟「Use priority」選項,則會隨機選擇圖塊。預設情況下,在圖塊集中的每個圖塊出現的機率都相同。可以通過調整每個圖塊的優先級 (Priority) 來更改此一機率。舉例來說,優先級 2 的圖塊被選中的機率比優先級 1 的圖塊還要高兩倍,而優先級 3 的圖塊則比優先級 2 的圖塊多出 50% 的機率。

自動圖塊 (Autotile)

使用自動圖塊,可定義一組圖塊,並設定規則來依據周圍的元素控制要繪製哪個圖塊。

點擊「New Autotile」並拖移來選擇要使用的圖塊。可以新增碰撞區域、遮擋、導航形狀、圖塊優先級,並與合集圖塊一樣,可選擇用於圖示的圖塊。

圖塊的選擇是由位元遮罩 (Bitmask) 來控制的。可以通過點擊「Bitmask」來新增位元遮罩,然後點擊圖塊中要新增或移除位元遮罩的部分。左鍵點擊圖塊中的區域來新增位元,右鍵點擊則可移除「關閉 (Off)」,Shift + 左鍵點擊則可設定「忽略 (Ignore)」位元。

當 Godot 使用自動圖塊來更新其中一格圖塊格 (Cell) 時,Godot 會先依據週遭已經設定好的圖塊格來建立圖塊樣式。接著再使用建立好的樣式來以與其位元遮罩相符的單一圖塊來建立自動圖塊。若沒有找到相符的位元遮罩,則會改用「icon」圖塊。若有找到多個相符的位元遮罩,則會依照圖塊優先度隨機選擇一個。

將位元遮罩對應到樣式的規則會依據圖塊集的自動圖塊位元遮罩模式而有所不同。可以在「屬性面板」分頁中的「Selected Tile」底下設定該規則。可設定的值有「2x2」、「3x3 (minimal)」與「3x3」。

位元遮罩中所有的「on」與「off」位元都必須要設定,但「ignore」位元則可忽略。

2x2

在 2x2 模式下,每個位元遮罩都包含了 4 個位元,對應 4 個角落。

對於設為「on」的位元,所有連結到該角落的圖塊格都必須以相同的自動圖塊來填滿以符合位元遮罩。舉例來說,若有設定左上角的位元,則正上方、正作坊、與斜左上方的圖塊格都必須要被填滿。

對於設為「off」的位元,則至少有一個連接到該角落的圖塊格不能使用相同的自動圖塊來設定。

要使用的圖塊都必須要設定至少一個位元。因此,對每個要測試該模式的圖塊排列,都必須要設定總共 15 格圖塊來提供剛好一個的圖塊。

2x2 模式只能對應到 2 乘 2 區塊中的圖塊格 —— 也就是周圍沒有其他圖塊格的圖塊格,且不支援邊長只有 1 的圖塊格。

樣板 - 通用:

本樣板可用於側面或完整由上而下的視角。本樣板是為大小為 64x64 的 TileMap 圖塊格所設計的。

索引鍵:

  • 紅色:「on」

  • 白色:「off」

../../_images/autotile_template_2x2.png

3x3 (minimal)

3x3 (minimal) 模式中,每個位元遮罩都包含了 9 個位元 (4 個角落、4 個邊緣、1 個中央)。4 個角落的位元的運作方式與 2x2 模式相同。

When an edge bit is "on", the cell which shares that edge must be filled. When an edge bit is "off", the cell which shares that edge must be empty.

The center bit should be "on" for any tile you wish to use. Note that in this mode, it makes no sense for a corner bit to be "on" when either edge bit adjacent to it is not "on".

A total of 47 tiles would be needed to provide exactly one bitmask for each arrangement that this mode can test for.

備註

Right-click an image and choose Save image as… to save it.

樣板 - 通用:

This template can be used for sideways or fully top-down perspectives. All templates below are designed for a TileMap cell size of 64x64, but you may have to use different subtile sizes for top-down templates as described below.

索引鍵:

  • 紅色:「on」

  • 白色:「off」

../../_images/autotile_template_3x3_minimal.png

Template - Generic 16 tiles:

This template can be used for tilesets that only have 16 tiles - for simpler art styles the missing tiles will not be noticeable.

索引鍵:

  • 紅色:「on」

  • 白色:「off」

  • Blue-checkered: "ignore"

../../_images/autotile_template_3x3_minimal_16.png

Template - Top-down floor in 3/4 perspective:

Key (applies to the four templates below):

  • Green: floor

  • Cyan: wall

  • Yellow: top of wall

  • Grey: hidden due to overlap

  • Transparent: air

../../_images/autotile_template_3x3_minimal_topdown_floor.png

Template - Top-down wall in 3/4 perspective:

../../_images/autotile_template_3x3_minimal_topdown_walls.png

Template - Top-down wall in 3/4 perspective (thick walls):

When using this template, set the TileSet subtile size to Vector2(64, 88).

../../_images/autotile_template_3x3_minimal_topdown_walls_thick.png

Template - Top-down wall in 3/4 perspective (tall walls):

When using this template, set the "Snap Options" Step to Vector2(64, 184) and the "Selected Tile" Texture offset to height minus the cell size. This means the texture offset should be Vector2(0, -120):

../../_images/autotile_template_3x3_minimal_topdown_walls_tall.png

3x3

In 3x3 mode, each bitmask contains 9 bits (4 corners, 4 edges, 1 center)

Each bit checks a single adjacent cell. Corner bits only check diagonally adjacent cells. The center bit should be "on" for any tile you wish to use.

A total of 256 tiles would be needed to provide exactly one bitmask for each arrangement that this mode can test for.

Disabling autotile

When using an autotile, it is possible to turn off the autotile behaviour and select tiles manually, by clicking "Disable Autotile" at the top of the tile selection window.

Autotile binding

By default, autotile only checks for adjacent cells filled using the same autotile. This behaviour can be overridden in order to have autotiles bind to each other, or even bind to empty cells. At present, this can only be done through scripting. You will need to add a script to your tileset, and define a function named "_is_tile_bound(drawn_id, neighbor_id)". This function will be called for each adjacent cell that does not contain the same autotile, and should return true if you want the drawn cell to "bind" to the neighbor cell. You can find the id of an autotile using "find_tile_by_name(name)", empty cells are given an id of -1.

Note that to use this in the editor, the script should start with a "tool" declaration, and you may need to close and reload the scene for these changes to take effect.

Tips and tricks

  • If you're using a Camera2D to scroll your level, you may notice lines appearing between your tiles. To fix this, open Project Settings and enable Use Gpu Pixel Snap in the Rendering > 2d > Snapping section.

  • You can flip and rotate tiles using the icons at the top right of the editor.

  • To draw straight lines, hold Shift while clicking and dragging a tile.

  • Tools such as copy, paste, and bucket fill, can be found in the "TileMap" menu in the upper-right.

../../_images/tilemap_menu.png