Godot 的瓦片地圖,可以理解成把一張包含草地、道路、牆壁、水面等小圖片的素材表,切成規則格子,再像畫畫一樣拼出關卡。
在 Godot 4.x,尤其是 4.3 之後的新專案中,建議使用 TileMapLayer。舊的 TileMap 節點已經被標記為棄用;現在更推薦一個地圖層對應一個 TileMapLayer 節點。這樣層級更清楚,也更符合 Godot 的節點組織方式。
官方文件也明確說明:TileMapLayer 是用於 2D tile-based maps 的節點,它使用 TileSet 建立網格地圖;如果需要多層效果,可以使用多個 TileMapLayer。
官方文件:
https://docs.godotengine.org/en/stable/classes/class_tilemaplayer.html
https://docs.godotengine.org/en/latest/tutorials/2d/using_tilemaps.html
先理解兩個核心概念
瓦片地圖最重要的是兩個東西:
TileSetTileMapLayer
TileSet 相當於瓦片素材庫,裡面保存:
- 草地、土地、牆壁、水面、道路等瓦片。
- 每個瓦片的碰撞形狀。
- Terrain 自動連接規則。
- 導航、遮擋和自訂資料。
TileMapLayer 相當於畫布。它使用 TileSet 裡的瓦片來繪製地圖。
推薦從這種節點結構開始:
|
|
分層的好處很明顯:
- 地面不會和牆壁混在一起。
- 可以單獨設定顯示順序。
- 可以單獨隱藏某一層。
- 只給牆壁層添加碰撞,地面層保持簡單。
- 後續讓 Codex 寫腳本時,節點職責更清楚。
建立第一張瓦片地圖
先準備一張瓦片圖片,例如:
|
|
圖片內部每個格子大小要一致,常見尺寸有:
|
|
假設素材每個瓦片是 32 × 32,那麼 TileSet 的 Tile Size 也應該設定成 32 × 32。
添加 TileMapLayer
在場景裡添加:
|
|
把 TileMapLayer 改名為:
|
|
選中 Ground,在 Inspector 中找到:
|
|
點擊:
|
|
然後點擊剛建立的 TileSet 資源,把 Tile Size 設定為素材格子大小,例如:
|
|
加入瓦片素材
選中 Ground 後,底部會出現 TileMap / TileSet 編輯面板。
把 tileset.png 拖到 TileSet 面板中,選擇自動建立瓦片。Godot 會按照 Tile Size 把圖片切成一塊塊小瓦片。
這一步完成後,TileSet 就擁有了可繪製的瓦片,Ground 這個 TileMapLayer 就可以使用它來畫地圖。
繪製地圖
切換到底部的 TileMap 面板:
- 選擇一個草地瓦片。
- 使用鉛筆工具繪製。
- 用橡皮擦刪除。
- 用矩形工具快速鋪一片區域。
- 用填充工具快速鋪滿連續區域。
剛開始不要急著做大地圖。先畫一個 20 × 15 的小地圖,只要有草地、牆壁和玩家出生點就夠了。
給牆壁添加碰撞
不要給所有地面瓦片都加碰撞。通常只給這些不可通行內容添加碰撞:
- 牆壁。
- 石頭。
- 柵欄。
- 水域邊界。
- 懸崖。
選中 TileSet 資源,在 Inspector 中找到:
|
|
點擊:
|
|
常見配置是:
|
|
然後在底部 TileSet 面板中:
- 切換到碰撞或物理繪製相關工具。
- 選擇牆壁瓦片。
- 給牆壁區域繪製矩形或多邊形碰撞。
這樣,同一個 TileSet 中的不同瓦片就可以擁有不同碰撞形狀。
玩家如何被瓦片牆擋住
玩家場景可以這樣搭:
|
|
玩家移動腳本可以從最小版本開始:
|
|
只要 Player 的碰撞層、遮罩與 TileSet 的物理層匹配,玩家移動時就會被牆壁瓦片擋住。
執行遊戲時可以打開:
|
|
這樣能直接看到牆壁和玩家的碰撞形狀,排錯會輕鬆很多。
地圖建議分成三層
初學階段,推薦使用三層:
|
|
每個節點都是獨立的 TileMapLayer。
Ground 放:
- 草地。
- 泥土。
- 道路。
- 地板。
通常沒有碰撞。
Walls 放:
- 牆壁。
- 懸崖。
- 水域邊界。
- 不可穿越的石頭。
通常有碰撞。
Decoration 放:
- 小花。
- 草葉。
- 地面裂紋。
- 陰影。
通常沒有碰撞。
可以使用 z_index 控制基本顯示順序:
|
|
如果有樹木、屋頂、橋洞這類需要遮擋玩家的物件,後面再考慮 Y Sort,或者把物件拆成上下兩部分。第一張地圖不必一開始就把遮擋系統做複雜。
使用 Terrain 自動連接道路和牆壁
如果你希望畫地圖時自動生成邊緣和轉角,例如:
- 草地自動連接泥土邊緣。
- 道路自動生成轉角。
- 牆壁自動判斷上下左右。
- 水面自動生成岸邊。
就需要使用 Godot 的 Terrain Set。
基本流程是:
- 在
TileSet中添加Terrain Set。 - 設定匹配模式,例如按邊和角匹配。
- 建立 Terrain,例如
Grass、Dirt、Water。 - 給各個瓦片標註對應的地形連接位置。
- 在
TileMapLayer中切換到Terrains繪製模式。 - 使用
Connect或Path工具畫地圖。
Godot 會根據周圍格子自動選擇直線、轉角、邊緣瓦片。官方文件中也提到,Terrain 連接模式包括 Connect 和 Path:Connect 更容易上手,Path 更適合需要更多人工控制的道路或路徑。
剛開始不必立刻學習 Terrain。先手動畫一張小地圖,理解 TileSet、TileMapLayer 和碰撞之後,再做自動連接。
在程式碼中操作瓦片
假設場景結構是:
|
|
可以在 World 腳本中引用 Ground:
|
|
這裡的 cell 是地圖格子座標。例如:
|
|
表示在第 5 列、第 3 行放置一個草地瓦片。
注意:SOURCE_ID 和 GRASS_TILE 的 atlas 座標必須以你實際的 TileSet 為準,不能直接照搬範例。
世界座標和格子座標互轉
滑鼠點擊的位置是世界座標,而瓦片地圖使用格子座標。通常需要先轉成本層的局部座標,再轉成地圖格子。
世界座標轉格子座標:
|
|
格子座標轉回地圖位置:
|
|
如果要做滑鼠點擊放置瓦片,可以這樣寫:
|
|
如果還想支援右鍵刪除瓦片,可以使用:
|
|
set_cell()、erase_cell()、local_to_map() 和 map_to_local() 都是 TileMapLayer 常用 API。
寶箱、門和金幣不要都畫成普通瓦片
這些物件通常不適合只畫成普通瓦片:
- 金幣。
- 寶箱。
- 可以打開的門。
- NPC。
- 敵人。
- 傳送點。
- 機關。
- 可以破壞的箱子。
它們有腳本、動畫、碰撞和信號,更適合做成獨立場景。
例如金幣:
|
|
然後放進:
|
|
普通瓦片適合靜態地圖;有行為的物件適合獨立 Scene。Godot 也支援 Scene Collection 類型的瓦片,但初學階段手動放置獨立場景更容易理解,也更容易排錯。
Codex 最適合幫你做什麼
Codex 很適合輔助這些工作:
- 寫玩家移動腳本。
- 讀取地圖格子。
- 程式化生成地圖。
- 隨機鋪地面。
- 滑鼠放置和刪除瓦片。
- 尋找出生點。
- 讀取自訂瓦片資料。
- 檢查
TileMapLayerAPI 用法。 - 實現金幣、門、寶箱邏輯。
可以這樣給 Codex 提示:
|
|
Codex 不太適合這些工作:
- 判斷素材應該切成多少像素。
- 視覺化繪製整張地圖。
- 精細配置 Terrain 位掩碼。
- 憑空猜
source_id。 - 憑空猜 atlas 座標。
- 大規模手寫
.tscn地圖資料。
更合理的分工是:你在 Godot 編輯器中建立 TileSet、配置碰撞並繪製地圖;Codex 負責編寫地圖互動、生成邏輯和 gameplay 腳本。
第一個練習怎麼做
建議第一個練習只做一張 20 × 15 的小地圖:
Ground鋪草地。Walls畫一圈牆。- 給牆壁瓦片配置碰撞。
- 放一個
Player。 - 讓玩家移動時被牆擋住。
- 再加入一個
Coin場景。
這個練習做完,你就會真正理解 Godot 瓦片地圖的基本工作流:
|
|
先把這個最小地圖跑通,再去研究 Terrain、Y Sort、程式化生成和大地圖載入,會穩很多。