Giới thiệu
Godot 4 đã viết lại hoàn toàn hệ thống TileMap. Nếu bạn từng dùng TileMap trong Godot 3, thì gần như mọi thứ đã thay đổi — trình chỉnh sửa TileSet, cách định nghĩa tile, auto-tiling, layer và GDScript API. Hướng dẫn này trình bày kiến trúc mới từ đầu.
Người dùng Godot 3: Các autotile, set_cellv() và cell_size cũ đều đã bị loại bỏ. Xem phần Chuyển đổi từ Godot 3 ở cuối trang.
Kiến trúc TileMap mới
Hệ thống TileMap của Godot 4 gồm hai thành phần chính:
- Node TileMap — Node bạn thêm vào scene. Nó chứa một hoặc nhiều layer và tham chiếu đến một tài nguyên TileSet.
- Tài nguyên TileSet — Định nghĩa chính các tile. Chứa nguồn (atlas, bộ sưu tập scene, v.v.), layer vật lý, layer điều hướng, layer dữ liệu tùy chỉnh và terrain set.
Thay đổi quan trọng: Trong Godot 3, kích thước tile được đặt trên node TileMap. Trong Godot 4, kích thước tile được định nghĩa trong tài nguyên TileSet, còn TileMap chỉ tham chiếu đến nó.
Nguồn TileSet
Một TileSet có thể có nhiều nguồn, mỗi nguồn được xác định bằng một source_id (số nguyên). Các loại nguồn bao gồm:
- TileSetAtlasSource — Loại phổ biến nhất. Một ảnh texture đơn chứa nhiều tile được sắp xếp theo lưới.
- TileSetScenesCollectionSource — Mỗi tile là một packed scene, hữu ích cho các tile có hoạt ảnh hoặc tương tác.
Thiết lập một TileSet
Bước 1: Tạo tài nguyên TileSet
- Thêm một node TileMap vào scene của bạn.
- Trong Inspector, nhấp vào thuộc tính Tile Set và chọn New TileSet.
- Đặt Tile Size (ví dụ: 16x16 hoặc 32x32).
Bước 2: Thêm một nguồn atlas
- Nhấp vào TileSet để mở trình chỉnh sửa TileSet ở panel phía dưới.
- Nhấp vào nút + và chọn Atlas.
- Kéo ảnh tileset của bạn vào thuộc tính Texture.
- Trình chỉnh sửa tự động chia ảnh thành các tile dựa trên kích thước tile của bạn. Bạn có thể điều chỉnh vùng texture và lề (margin).
Bước 3: Cấu hình thuộc tính tile
Trong trình chỉnh sửa TileSet, bạn có thể thêm nhiều loại layer áp dụng cho tất cả các tile:
- Physics Layers — Hình dạng va chạm cho tile
- Navigation Layers — Đa giác có thể đi lại cho việc tìm đường
- Custom Data Layers — Dữ liệu có kiểu tùy ý (bool, int, float, String, v.v.)
- Terrain Sets — Dùng cho auto-tiling (phần thay thế cho autotile của Godot 3)
Layer TileMap
Một node TileMap đơn có thể chứa nhiều layer. Đây là một cải tiến lớn so với Godot 3, nơi bạn cần các node TileMap riêng biệt cho nền và tiền cảnh. Mỗi layer có thể có cài đặt z-index, y-sort và modulate riêng.
Cấu hình layer thông thường:
- Layer 0 — Nền (mặt đất, sàn) — z-index: -1
- Layer 1 — Địa hình (tường, chướng ngại vật) — z-index: 0
- Layer 2 — Tiền cảnh (vật trang trí phía trên người chơi) — z-index: 1
GDScript API cho layer
# Set a cell on layer 0
tilemap.set_cell(0, Vector2i(5, 3), source_id, atlas_coords)
# Get cell info
var source = tilemap.get_cell_source_id(0, Vector2i(5, 3))
var coords = tilemap.get_cell_atlas_coords(0, Vector2i(5, 3))
# Erase a cell
tilemap.erase_cell(0, Vector2i(5, 3))
# Check if a cell is occupied
if tilemap.get_cell_source_id(0, Vector2i(5, 3)) != -1:
print("Cell has a tile")
Lưu ý API: Tham số đầu tiên trong set_cell() luôn là chỉ số layer (0, 1, 2...). Tham số thứ hai là vị trí cell dạng Vector2i. Tham số thứ ba là source_id, và tham số thứ tư là atlas_coords dạng Vector2i.
Hệ thống terrain (Auto-Tiling)
Hệ thống terrain thay thế autotile của Godot 3. Nó tự động chọn biến thể tile đúng dựa trên các tile lân cận.
Thiết lập terrain
- Trong TileSet, thêm một Terrain Set (Inspector → Terrain Sets → Add Element).
- Chọn chế độ terrain: Match Corners and Sides (47 tile), Match Corners (16 tile) hoặc Match Sides (16 tile).
- Thêm các loại terrain trong set (ví dụ: "Grass", "Dirt", "Water").
- Trong trình chỉnh sửa TileSet, chuyển sang chế độ Select, chọn một tile và vẽ các bit peering terrain lên từng tile.
Vẽ terrain
Sau khi terrain đã được cấu hình, chuyển sang trình chỉnh sửa TileMap và chọn tab Terrains. Chọn loại terrain của bạn và vẽ trực tiếp lên bản đồ. Godot sẽ tự động chọn biến thể tile đúng.
# Set terrain programmatically
tilemap.set_cells_terrain_connect(0, [Vector2i(5, 3)], 0, 0)
# Parameters: layer, cells array, terrain_set, terrain index
Vật lý trên tile
Để thêm va chạm cho tile:
- Thêm một Physics Layer trong Inspector của TileSet.
- Cấu hình collision layer và mask nào mà layer vật lý này sử dụng.
- Trong trình chỉnh sửa TileSet, chuyển sang tab Physics và vẽ các đa giác va chạm lên từng tile.
Mẹo: Bạn có thể có nhiều layer vật lý cho các loại tile khác nhau. Ví dụ, một layer cho tường (chặn di chuyển) và một layer khác cho vật nguy hiểm (gây sát thương thông qua sự chồng lấn Area2D).
Dữ liệu tùy chỉnh trên tile
Các layer dữ liệu tùy chỉnh cho phép bạn đính kèm metadata có kiểu vào bất kỳ tile nào. Điều này cực kỳ hữu ích cho logic gameplay.
Thiết lập dữ liệu tùy chỉnh
- Trong Inspector của TileSet, thêm một Custom Data Layer.
-
Đặt tên cho nó (ví dụ: "is_destructible") và đặt kiểu (ví dụ:
bool). - Trong trình chỉnh sửa TileSet, chuyển sang tab Custom Data và đặt giá trị cho từng tile.
Đọc dữ liệu tùy chỉnh trong code
var tile_data = tilemap.get_cell_tile_data(0, Vector2i(5, 3))
if tile_data:
var is_destructible = tile_data.get_custom_data("is_destructible")
var damage = tile_data.get_custom_data("damage")
if is_destructible:
destroy_tile(Vector2i(5, 3))
Các ví dụ dữ liệu tùy chỉnh thường gặp:
is_destructible: booldamage: intmovement_cost: floattile_type: String(ví dụ: "water", "lava", "ice")spawn_chance: float
Đặt tile theo thủ tục
Việc đặt tile bằng lập trình rất đơn giản với API mới:
# Fill a rectangular area
for x in range(20):
for y in range(10):
tilemap.set_cell(0, Vector2i(x, y), 0, Vector2i(0, 0))
# Random tile placement
for x in range(50):
for y in range(50):
if randf() > 0.7:
tilemap.set_cell(0, Vector2i(x, y), 0, Vector2i(1, 0))
else:
tilemap.set_cell(0, Vector2i(x, y), 0, Vector2i(0, 0))
# Get all used cells on a layer
var used_cells: Array[Vector2i] = tilemap.get_used_cells(0)
print("Layer 0 has ", used_cells.size(), " tiles")
# Clear all tiles on a layer
tilemap.clear_layer(0)
# Clear everything
tilemap.clear()
Chuyển đổi tọa độ world sang map
# Convert world position to map coordinates
var map_pos: Vector2i = tilemap.local_to_map(world_position)
# Convert map coordinates to world position (center of tile)
var world_pos: Vector2 = tilemap.map_to_local(Vector2i(5, 3))
# Example: check what tile the player is standing on
var player_tile = tilemap.local_to_map(tilemap.to_local(player.global_position))
var tile_data = tilemap.get_cell_tile_data(0, player_tile)
if tile_data:
var tile_type = tile_data.get_custom_data("tile_type")
print("Player is on: ", tile_type)
Chuyển đổi từ Godot 3
| Godot 3 | Godot 4 |
|---|---|
TileMap.cell_size |
TileSet.tile_size |
set_cellv(pos, tile_id) |
set_cell(layer, pos, source_id, atlas_coords) |
get_cellv(pos) |
get_cell_source_id(layer, pos) |
autotile |
Hệ thống terrain (Terrain Sets) |
| Một layer mỗi node TileMap | Nhiều layer trong một TileMap |
TileMap.tile_set = preload(...) |
Tài nguyên TileSet được gán trong Inspector hoặc qua code |
world_to_map() |
local_to_map() |
map_to_world() |
map_to_local() |
Các lỗi thường gặp
-
Quên tạo TileSet trước. Node TileMap sẽ không hiển thị trình chỉnh sửa tile cho đến khi bạn gán một tài nguyên TileSet. Hãy tạo một cái trong Inspector.
-
Sai source_id. Nếu bạn chỉ có một nguồn atlas, thì
source_idcủa nó là0. Thêm nguồn thứ hai sẽ cho nósource_id = 1. Kiểm tra panel phía dưới của trình chỉnh sửa TileSet — mỗi tab nguồn hiển thị ID của nó. -
Nhầm lẫn atlas_coords với tile ID. Trong Godot 4, không có tile ID đơn giản. Thay vào đó, bạn tham chiếu tile theo vị trí của chúng trong lưới atlas dưới dạng
Vector2i(column, row). -
Không chỉ định tham số layer. Mọi thao tác trên cell đều yêu cầu chỉ số layer làm đối số đầu tiên. Quên nó sẽ gây lỗi đối số.
-
Dùng
set_cellv(). Phương thức này không còn tồn tại. Hãy dùngset_cell()với chữ ký mới.