Introducción a los mapas de tiles en Godot: TileMapLayer, TileSet, colisiones y Codex

Guía para principiantes de Godot 4.x sobre mapas de tiles: TileSet, TileMapLayer, mapas por capas, colisiones de tiles, conexión automática con Terrain y cómo usar Codex para escribir código de interacción con el mapa.

Un mapa de tiles en Godot consiste en tomar una hoja de sprites con pequeñas imágenes como césped, caminos, muros y agua, dividirla en celdas regulares y luego montar el nivel como si estuvieras pintando.

En Godot 4.x, especialmente para proyectos nuevos después de 4.3, conviene usar TileMapLayer. El nodo antiguo TileMap está marcado como obsoleto. Hoy es más recomendable usar un TileMapLayer por cada capa del mapa. Así la jerarquía queda más clara y encaja mejor con la forma de organizar nodos en Godot.

La documentación oficial también indica que TileMapLayer es un nodo para 2D tile-based maps y que usa un TileSet para crear mapas en cuadrícula. Si necesitas varias capas, usa varios TileMapLayer.

Documentación oficial:

https://docs.godotengine.org/en/stable/classes/class_tilemaplayer.html

https://docs.godotengine.org/en/latest/tutorials/2d/using_tilemaps.html

Dos conceptos clave

Lo más importante en un mapa de tiles son dos cosas:

  1. TileSet
  2. TileMapLayer

TileSet es la biblioteca de tiles. Guarda:

  1. Tiles de césped, tierra, muros, agua, caminos y otros elementos.
  2. Formas de colisión para cada tile.
  3. Reglas de conexión automática con Terrain.
  4. Navegación, oclusión y datos personalizados.

TileMapLayer es el lienzo. Usa los tiles del TileSet para dibujar el mapa.

Puedes empezar con una estructura como esta:

1
2
3
4
5
6
World (Node2D)
├─ Ground (TileMapLayer)       # Césped, caminos, suelo
├─ Decoration (TileMapLayer)   # Flores, grietas, sombras
├─ Walls (TileMapLayer)        # Muros y obstáculos
├─ Objects (Node2D)            # Cofres, puertas, NPC, monedas
└─ Player (CharacterBody2D)

Separar por capas tiene varias ventajas:

  1. El suelo no se mezcla con los muros.
  2. El orden de dibujo es más fácil de controlar.
  3. Puedes ocultar una capa concreta.
  4. Solo la capa de muros necesita colisión; la capa de suelo puede seguir siendo simple.
  5. Codex tendrá una estructura de nodos más clara cuando escriba scripts.

Crear el primer mapa de tiles

Primero prepara una imagen de tiles, por ejemplo:

1
tileset.png

Cada celda dentro de la imagen debe tener el mismo tamaño. Los tamaños comunes son:

1
2
3
16 × 16
32 × 32
64 × 64

Si cada tile del recurso mide 32 × 32, el Tile Size del TileSet también debería ser 32 × 32.

Añadir TileMapLayer

Añade esto a la escena:

1
2
Node2D
└─ TileMapLayer

Cambia el nombre de TileMapLayer a:

1
Ground

Selecciona Ground y busca en el Inspector:

1
Tile Set

Haz clic en:

1
2
<empty>
→ New TileSet

Luego abre el recurso TileSet recién creado y configura Tile Size con el tamaño de celda del recurso, por ejemplo:

1
32 × 32

Añadir la imagen de tiles

Después de seleccionar Ground, aparecerá abajo el panel de edición TileMap / TileSet.

Arrastra tileset.png al panel TileSet y elige la creación automática de tiles. Godot dividirá la imagen en tiles según Tile Size.

Después de este paso, el TileSet ya contiene tiles que se pueden dibujar, y el TileMapLayer Ground puede usarlos para pintar el mapa.

Dibujar el mapa

Cambia al panel TileMap inferior:

  1. Elige un tile de césped.
  2. Dibuja con la herramienta de lápiz.
  3. Borra con la goma.
  4. Usa la herramienta de rectángulo para rellenar zonas rápidamente.
  5. Usa la herramienta de relleno para completar áreas conectadas.

No empieces con un mapa enorme. Dibuja primero un mapa pequeño de 20 × 15, solo con césped, muros y un punto de aparición para el jugador.

Añadir colisión a los muros

No añadas colisión a todos los tiles de suelo. Normalmente solo los elementos no transitables necesitan colisión:

  1. Muros.
  2. Rocas.
  3. Vallas.
  4. Bordes de agua.
  5. Acantilados.

Selecciona el recurso TileSet y busca en el Inspector:

1
Physics Layers

Haz clic en:

1
Add Element

Una configuración común es:

1
2
Collision Layer: 1
Collision Mask: 1

Después, en el panel inferior TileSet:

  1. Cambia a las herramientas de colisión o dibujo físico.
  2. Selecciona un tile de muro.
  3. Dibuja una colisión rectangular o poligonal sobre la zona del muro.

Así, distintos tiles dentro del mismo TileSet pueden tener distintas formas de colisión.

Hacer que el jugador choque con los muros

Una escena básica de jugador puede ser:

1
2
3
Player (CharacterBody2D)
├─ Sprite2D
└─ CollisionShape2D

El script de movimiento puede empezar así:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
extends CharacterBody2D

@export var speed: float = 200.0


func _physics_process(_delta: float) -> void:
	var direction := Input.get_vector(
		"move_left",
		"move_right",
		"move_up",
		"move_down"
	)

	velocity = direction * speed
	move_and_slide()

Mientras la capa y máscara de colisión de Player coincidan con la capa física del TileSet, el jugador quedará bloqueado por los tiles de muro.

Al ejecutar el juego, puedes activar:

1
2
Debug
→ Visible Collision Shapes

Esto permite ver directamente las formas de colisión de los muros y del jugador, lo que facilita mucho el diagnóstico.

Dividir el mapa en tres capas

Para empezar, usa tres capas:

1
2
3
4
World
├─ Ground
├─ Walls
└─ Decoration

Cada nodo es un TileMapLayer independiente.

En Ground coloca:

  1. Césped.
  2. Tierra.
  3. Caminos.
  4. Suelos.

Normalmente no tiene colisión.

En Walls coloca:

  1. Muros.
  2. Acantilados.
  3. Bordes de agua.
  4. Rocas no transitables.

Normalmente tiene colisión.

En Decoration coloca:

  1. Flores pequeñas.
  2. Hojas de césped.
  3. Grietas del suelo.
  4. Sombras.

Normalmente no tiene colisión.

Puedes usar z_index para un orden de dibujo básico:

1
2
3
4
Ground: 0
Walls: 1
Decoration: 2
Player: 3

Si hay árboles, tejados o pasos bajo puentes que deben tapar al jugador, puedes resolverlo más adelante con Y Sort o dividiendo los objetos en partes superior e inferior. El primer mapa no necesita un sistema complejo de oclusión.

Usar Terrain para conectar caminos y muros automáticamente

Si quieres que el editor genere bordes y esquinas automáticamente, por ejemplo:

  1. Césped conectado con bordes de tierra.
  2. Caminos con esquinas generadas automáticamente.
  3. Muros que eligen el tile correcto según los vecinos.
  4. Agua con orillas generadas automáticamente.

Necesitas usar Terrain Set de Godot.

El proceso básico es:

  1. Añadir un Terrain Set en el TileSet.
  2. Configurar el modo de coincidencia, por ejemplo por lados y esquinas.
  3. Crear terrains, como Grass, Dirt y Water.
  4. Marcar las posiciones de conexión de terreno en cada tile.
  5. Cambiar el TileMapLayer al modo de dibujo Terrains.
  6. Dibujar el mapa con la herramienta Connect o Path.

Godot elegirá tiles rectos, esquinas y bordes según las celdas cercanas. La documentación oficial también menciona dos modos de dibujo de Terrain: Connect, más fácil para empezar, y Path, más adecuado cuando necesitas más control manual sobre caminos.

No hace falta aprender Terrain de inmediato. Primero dibuja un mapa pequeño a mano y entiende TileSet, TileMapLayer y las colisiones. Después pasa a la conexión automática.

Manipular tiles desde código

Supón esta estructura:

1
2
World
└─ Ground

Puedes referenciar Ground desde el script de World:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
extends Node2D

@onready var ground: TileMapLayer = $Ground

const SOURCE_ID: int = 0
const GRASS_TILE: Vector2i = Vector2i(0, 0)


func place_grass(cell: Vector2i) -> void:
	ground.set_cell(
		cell,
		SOURCE_ID,
		GRASS_TILE
	)

Aquí, cell es la coordenada de celda del mapa. Por ejemplo:

1
place_grass(Vector2i(5, 3))

Esto coloca un tile de césped en la columna 5, fila 3.

Importante: SOURCE_ID y las coordenadas atlas de GRASS_TILE deben coincidir con tu TileSet real. No copies los valores de ejemplo sin comprobarlos.

Convertir entre coordenadas del mundo y coordenadas de celda

La posición del mouse está en coordenadas del mundo, pero el mapa de tiles usa coordenadas de celda. Normalmente primero conviertes a coordenadas locales de la capa y luego a celda del mapa.

Coordenada del mundo a celda:

1
2
var local_position := ground.to_local(get_global_mouse_position())
var cell := ground.local_to_map(local_position)

Coordenada de celda a posición del mapa:

1
var position_in_layer := ground.map_to_local(cell)

Para colocar un tile con clic del mouse:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
extends Node2D

@onready var ground: TileMapLayer = $Ground

const SOURCE_ID: int = 0
const GRASS_TILE: Vector2i = Vector2i(0, 0)


func _unhandled_input(event: InputEvent) -> void:
	if event is InputEventMouseButton:
		if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
			var local_position := ground.to_local(
				get_global_mouse_position()
			)
			var cell := ground.local_to_map(local_position)

			ground.set_cell(
				cell,
				SOURCE_ID,
				GRASS_TILE
			)

Si también quieres borrar tiles con clic derecho, usa:

1
ground.erase_cell(cell)

set_cell(), erase_cell(), local_to_map() y map_to_local() son API comunes de TileMapLayer.

No conviertas cofres, puertas y monedas en tiles planos

Estos objetos normalmente no deberían ser solo tiles de imagen:

  1. Monedas.
  2. Cofres.
  3. Puertas que se pueden abrir.
  4. NPC.
  5. Enemigos.
  6. Puntos de teletransporte.
  7. Mecanismos.
  8. Cajas destructibles.

Tienen scripts, animaciones, colisiones y señales, así que conviene crearlos como escenas independientes.

Por ejemplo, una moneda:

1
2
3
Coin (Area2D)
├─ Sprite2D
└─ CollisionShape2D

Luego colócala en:

1
2
World
└─ Objects

Los tiles normales van bien para mapas estáticos. Los objetos con comportamiento funcionan mejor como Scene independientes. Godot también soporta tiles de tipo Scene Collection, pero para principiantes es más fácil entender y depurar escenas independientes colocadas a mano.

En qué puede ayudar Codex

Codex es útil para:

  1. Escribir scripts de movimiento del jugador.
  2. Leer celdas del mapa.
  3. Generar mapas proceduralmente.
  4. Pintar tiles de suelo de forma aleatoria.
  5. Colocar y borrar tiles con el mouse.
  6. Encontrar puntos de aparición.
  7. Leer datos personalizados de tiles.
  8. Revisar el uso de la API TileMapLayer.
  9. Implementar lógica de monedas, puertas y cofres.

Puedes pedirle algo así:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
Este es un proyecto Godot 4.x.

Estructura de escena:

World: Node2D
├─ Ground: TileMapLayer
├─ Walls: TileMapLayer
├─ Objects: Node2D
└─ Player: CharacterBody2D

Escribe un script para World:

1. Convertir la posición mundial del mouse a coordenadas de celda de Ground;
2. Clic izquierdo coloca un tile de césped;
3. Clic derecho borra un tile;
4. SOURCE_ID y coordenadas atlas deben configurarse con @export;
5. Usar la API TileMapLayer de Godot 4.x;
6. Usar tipos estáticos;
7. No modificar el TileSet ni los nombres de nodos de la escena.

Codex no es tan adecuado para:

  1. Decidir cuántos píxeles debe medir cada tile del recurso.
  2. Dibujar visualmente todo el mapa.
  3. Configurar con precisión las máscaras de Terrain.
  4. Adivinar source_id.
  5. Adivinar coordenadas atlas.
  6. Escribir a mano grandes datos de mapa .tscn.

La división más práctica es: tú creas el TileSet, configuras colisiones y dibujas el mapa en el editor de Godot; Codex escribe la interacción del mapa, la lógica de generación y los scripts de gameplay sobre la estructura real de nodos.

Primer ejercicio

Para el primer ejercicio, crea solo un mapa pequeño de 20 × 15:

  1. Pintar césped en Ground.
  2. Dibujar un borde de muros en Walls.
  3. Configurar colisión para los tiles de muro.
  4. Colocar un Player.
  5. Hacer que el jugador sea bloqueado por los muros.
  6. Añadir después una escena Coin.

Cuando termines este ejercicio, entenderás el flujo básico de mapas de tiles en Godot:

1
2
3
4
5
TileSet guarda el arte y las reglas de los tiles
TileMapLayer dibuja una capa del mapa
La colisión se configura en los tiles dentro del TileSet
Los objetos con comportamiento deben ser escenas independientes
Codex escribe scripts alrededor de la estructura real de nodos

Haz funcionar primero este mapa mínimo. Luego pasa a Terrain, Y Sort, generación procedural y carga de mapas grandes.

记录并分享
Creado con Hugo
Tema Stack diseñado por Jimmy