Conceptos clave: cuerpos físicos vs áreas
En Godot 2D, la interacción entre objetos se divide en dos grandes familias:
- Colisiones físicas: resuelven empujes, bloqueos y deslizamiento. Se usan con nodos tipo
CharacterBody2D,StaticBody2D,RigidBody2D. Ejemplo: el jugador no atraviesa una pared. - Detección (triggers): detectan solapamientos sin “bloquear” el movimiento. Se usan con
Area2D. Ejemplo: una zona de peligro que reinicia al jugador.
Ambas familias dependen de formas de colisión (shapes) y de la configuración de capas y máscaras para decidir quién interactúa con quién.
Formas de colisión: CollisionShape2D y CollisionPolygon2D
CollisionShape2D (rápido y simple)
CollisionShape2D contiene un recurso Shape2D (por ejemplo RectangleShape2D, CapsuleShape2D, CircleShape2D). Es la opción más común para personajes, plataformas rectas y objetos simples.
- Ventaja: fácil de ajustar y muy eficiente.
- Recomendación: usa pocas formas por objeto; evita “dibujar” siluetas complejas con muchas piezas si no es necesario.
CollisionPolygon2D (para contornos complejos)
CollisionPolygon2D permite definir un polígono (convexo o cóncavo según configuración) para colisiones más ajustadas, útil en suelos irregulares o escenarios con formas orgánicas.
- Ventaja: se adapta mejor a geometrías complejas.
- Precaución: polígonos muy detallados pueden afectar rendimiento y generar comportamientos extraños en bordes finos.
Pautas de alineación y escala
- Coloca el
CollisionShape2D/CollisionPolygon2Dcomo hijo del cuerpo (CharacterBody2D,StaticBody2DoArea2D). - Asegúrate de que el shape esté alineado con el sprite (misma posición relativa). Un error típico es que el sprite se mueva/escale y el shape se quede desfasado.
- Evita escalar el nodo del cuerpo de forma no uniforme; si necesitas cambiar tamaño, ajusta el recurso del shape (por ejemplo, el tamaño del
RectangleShape2D). - En el editor, activa la visualización de colisiones: Debug > Visible Collision Shapes para comprobar el encaje real.
Capas y máscaras de colisión (Collision Layers / Masks)
Godot usa un sistema de bits: un objeto está en una o varias capas (layers) y detecta (o colisiona con) una o varias máscaras (masks).
- Escuche el audio con la pantalla apagada.
- Obtenga un certificado al finalizar.
- ¡Más de 5000 cursos para que explores!
Descargar la aplicación
- Collision Layer: “yo pertenezco a estas capas”.
- Collision Mask: “yo interactúo con estas capas”.
Regla práctica: para que A interactúe con B, la máscara de A debe incluir alguna capa de B (y en algunos casos también al revés, según el tipo de interacción y señales que uses).
Propuesta de capas para este capítulo
| Capa | Nombre (mental) | Ejemplos |
|---|---|---|
| 1 | Player | CharacterBody2D del jugador |
| 2 | World | Plataformas, paredes (StaticBody2D) |
| 3 | Hazard | Zonas de peligro (Area2D) |
Configuración sugerida:
- Jugador: Layer = Player (1). Mask = World (2) + Hazard (3) (para chocar con el mundo y detectar peligros).
- Mundo (plataformas/paredes): Layer = World (2). Mask = Player (1) (opcional para algunos casos; para colisión física con CharacterBody2D suele bastar con que el jugador tenga máscara al mundo).
- Peligro (Area2D): Layer = Hazard (3). Mask = Player (1) (para detectar al jugador).
Práctica 1: plataformas sólidas y paredes con StaticBody2D
Objetivo
Crear un suelo y paredes que bloqueen al jugador usando colisión física.
Paso a paso
Crea una escena de plataforma (reutilizable):
- Nodo raíz:
StaticBody2D - Hijo:
Sprite2D(oColorRectsi estás prototipando) - Hijo:
CollisionShape2DconRectangleShape2D
- Nodo raíz:
Ajusta el shape:
- Selecciona el
CollisionShape2Dy define el tamaño delRectangleShape2Dpara que cubra el área visible de la plataforma. - Activa Debug > Visible Collision Shapes y verifica que el rectángulo coincide con el sprite.
- Selecciona el
Configura capas/máscaras en el
StaticBody2D:- Collision Layer: World (2)
- Collision Mask: Player (1) (opcional)
Duplica para crear paredes:
- Reutiliza la misma escena y rota/escala visualmente el sprite, pero ajusta el shape desde el recurso para mantener coherencia.
Notas de comportamiento
StaticBody2Des ideal para geometría inmóvil: suelos, paredes, plataformas fijas.- Si más adelante necesitas plataformas móviles, suele usarse
AnimatableBody2Do mover unStaticBody2Dcon cuidado (según el caso), pero aquí nos centramos en estáticos.
Práctica 2: zona de peligro con Area2D que reinicia al jugador
Objetivo
Crear un “trigger” que detecte al jugador al entrar y lo devuelva a un punto de reaparición (spawn).
Estructura recomendada
- Nodo raíz:
Area2D - Hijo:
CollisionShape2D(por ejemploRectangleShape2D) - (Opcional) Hijo:
Sprite2DoColorRectsemitransparente para visualizar el área
Paso a paso
Crea el Area2D y ajusta su shape para cubrir la zona peligrosa (por ejemplo, un foso bajo el nivel).
Configura capas/máscaras:
- Area2D Collision Layer: Hazard (3)
- Area2D Collision Mask: Player (1)
Conecta la señal:
- Selecciona el
Area2D> pestaña Node > señales. - Conecta
body_entered(body: Node2D)a un script del propioArea2D(o a un nodo controlador).
- Selecciona el
Implementa el reinicio:
- Define un punto de spawn (por ejemplo un
Marker2Den la escena principal) o guarda una posición inicial. - Cuando el jugador entre, reposiciónalo y reinicia su velocidad.
- Define un punto de spawn (por ejemplo un
Ejemplo de script para el Area2D (Godot 4.x)
extends Area2D
@export var player_path: NodePath
@export var spawn_marker_path: NodePath
@onready var player := get_node(player_path) as CharacterBody2D
@onready var spawn := get_node(spawn_marker_path) as Marker2D
func _ready() -> void:
body_entered.connect(_on_body_entered)
func _on_body_entered(body: Node) -> void:
if body == player:
player.global_position = spawn.global_position
player.velocity = Vector2.ZEROAlternativa: si prefieres no referenciar al jugador por ruta, puedes comprobar por grupo. Por ejemplo, añade al jugador al grupo player y usa:
func _on_body_entered(body: Node) -> void:
if body.is_in_group("player"):
var p := body as CharacterBody2D
p.global_position = spawn.global_position
p.velocity = Vector2.ZEROPor qué Area2D y no un cuerpo físico
- El peligro no necesita bloquear ni empujar: solo detectar solapamiento.
Area2Dofrece señales directas (body_entered,body_exited,area_entered) ideales para lógica de juego.
Comparativa rápida: CharacterBody2D, StaticBody2D y Area2D
| Nodo | ¿Bloquea movimiento? | ¿Detecta solapamientos? | Uso típico |
|---|---|---|---|
| CharacterBody2D | Sí (se mueve y colisiona) | Puede detectar mediante métodos/colisiones y también con áreas auxiliares | Jugador, NPC controlado |
| StaticBody2D | Sí (inmóvil) | No es su objetivo principal | Suelos, paredes, obstáculos fijos |
| Area2D | No | Sí (señales de entrada/salida) | Daño, pickups, checkpoints, zonas de evento |
Diagnóstico: problemas comunes y cómo resolverlos
1) “No colisiona” (el jugador atraviesa el suelo/pared)
- Revisa que exista un shape: el cuerpo debe tener
CollisionShape2DoCollisionPolygon2Dcomo hijo, y el recursoShape2Dno puede estar vacío. - Shape desactivado: en
CollisionShape2D, verifica quedisabledesté enfalse. - Capas/máscaras: confirma que el jugador tenga en su mask la capa World, y que las plataformas estén en layer World.
- Debug visual: activa Debug > Visible Collision Shapes para ver si realmente hay colisionadores donde crees.
2) “Detecta tarde” o “se engancha” en bordes
- Shapes demasiado ajustados: deja un pequeño margen en el colisionador del personaje (por ejemplo, un rectángulo un poco más estrecho que el sprite) para evitar engancharse en esquinas.
- Polígonos muy complejos: simplifica
CollisionPolygon2Dsi hay picos o vértices muy cercanos. - Escala no uniforme: evita escalar el cuerpo; ajusta el tamaño del shape directamente.
3) “El Area2D no dispara body_entered”
- Máscara incorrecta: el
Area2Ddebe tener en su mask la capa del jugador (Player). - El jugador no tiene cuerpo/shape válido: para que
body_enteredfuncione, el jugador debe ser un PhysicsBody2D (comoCharacterBody2D) con colisionador. - Estás usando area_entered en vez de body_entered:
area_enteredsolo detecta otrasArea2D. Para el jugador (cuerpo), usabody_entered. - Monitorización: en el
Area2D, verifica quemonitoringesté activo (por defecto suele estarlo).
4) “Las colisiones se ven desalineadas respecto al sprite”
- Origen/pivote: revisa el offset del
Sprite2Dy la posición delCollisionShape2D. Ambos deben referenciar el mismo origen local. - Transformaciones en nodos padres: si un nodo padre está escalado/rotado, afecta a hijos. Comprueba la jerarquía.
- Usa el modo de edición: selecciona el
CollisionShape2Dy ajusta con herramientas de mover/rotar para encajar.
5) Checklist rápido de verificación
- ¿Ves los colisionadores con Visible Collision Shapes?
- ¿El jugador está en layer Player y su mask incluye World y Hazard?
- ¿Las plataformas/paredes están en layer World?
- ¿El Area2D está en layer Hazard y su mask incluye Player?
- ¿La señal correcta está conectada (
body_entered) y el método se ejecuta?