Parte: 0 — Fundamentos y prerrequisitos · Fuente: Eric Lengyel, Mathematics for 3D Game Programming and Computer Graphics ⏱️ Duración estimada: 90 min · Nivel: Fundamentos
Un objeto en un juego no tiene "una" posición: tiene varias según el espacio en el que lo mires. Su posición local (relativa a su padre), su posición en el mundo, su posición vista desde la cámara y su posición final en pantalla (píxeles). Confundir estos espacios es una de las causas más frecuentes de bugs de colocación e input.
En esta clase entenderás la jerarquía de transformaciones padre/hijo, la diferencia entre espacio local y mundo, el espacio de cámara/vista y el espacio de pantalla. En 2D verás por qué el eje Y crece hacia abajo y cómo convertir la posición del ratón a coordenadas de mundo. Lo comprobarás en Godot moviendo un padre y observando a sus hijos, y colocando un marcador donde clicas.
Al finalizar, el alumno podrá:
position) de posición de mundo (global_position).| # | Tema | Por qué importa |
|---|---|---|
| 1 | Espacio local | Coordenadas relativas al nodo padre. |
| 2 | Espacio de mundo | Coordenadas globales absolutas de la escena. |
| 3 | Jerarquía padre/hijo | Mover el padre transforma a todos los hijos. |
| 4 | Espacio de cámara/vista | Todo se expresa relativo a la cámara. |
| 5 | Espacio de pantalla | Píxeles del viewport; origen arriba-izquierda. |
| 6 | Eje Y en 2D | Y hacia abajo; afecta el sentido del movimiento. |
| 7 | Ratón → mundo | Traducir clics a posiciones jugables. |
| 8 | to_local/to_global |
Convertir entre espacios de forma segura. |
position.global_position, resultado de acumular las transformaciones de los padres.y mueve el objeto hacia abajo.get_global_mouse_position(): función de Godot que da la posición del ratón ya convertida a mundo. Clave: evita conversiones manuales de píxeles a mundo.Usarás Godot 4 (https://godotengine.org/) con GDScript. Trabajarás con nodos Node2D, Sprite2D y Camera2D. La referencia teórica es Mathematics for 3D Game Programming and Computer Graphics de Eric Lengyel (https://foundationsofgameenginedev.com/). Consulta también la documentación de Godot sobre Node2D y transformaciones 2D (https://docs.godotengine.org/en/stable/tutorials/2d/2d_transforms.html) y sobre el sistema de coordenadas (https://docs.godotengine.org/en/stable/tutorials/2d/2d_movement.html). No necesitas assets externos: basta el icon.svg que trae cada proyecto.
Crea un proyecto 2D. Estructura la escena así: un Node2D llamado Padre, y como hijo suyo un Sprite2D llamado Hijo con el icon.svg como textura. En el editor, coloca Hijo con position = (100, 0) respecto al padre. Añade a Padre un script con este contenido:
extends Node2D
func _ready() -> void:
var hijo := $Hijo
print("Hijo position (local): ", hijo.position)
print("Hijo global_position: ", hijo.global_position)
Coloca el Padre en (300, 200) desde el inspector y ejecuta. La consola mostrará que position del hijo sigue siendo (100, 0) (relativa al padre) mientras que global_position es (400, 200): la suma de la posición del padre más la local del hijo. Mover el padre cambia el global_position del hijo pero no su position local.
Añade movimiento al padre para verlo en vivo:
func _process(delta: float) -> void:
# Sumar a y mueve el nodo HACIA ABAJO en pantalla
position.y += 50.0 * delta
Ejecuta: el conjunto padre-hijo desciende. Sumar a y baja el objeto porque en 2D el eje Y crece hacia abajo, al contrario que en las gráficas matemáticas clásicas.
Agrega un Camera2D como hijo de la raíz (para tener un espacio de cámara claro) y un Sprite2D llamado Marcador. En el script de la raíz, coloca el marcador donde se hace clic:
extends Node2D
@onready var marcador: Sprite2D = $Marcador
func _unhandled_input(event: InputEvent) -> void:
if event is InputEventMouseButton and event.pressed:
# get_global_mouse_position() ya devuelve coordenadas de MUNDO
var mundo := get_global_mouse_position()
marcador.global_position = mundo
print("Clic en pantalla: ", event.position, " -> mundo: ", mundo)
Ejecuta y haz clic: el Marcador salta exactamente bajo el cursor. La consola muestra la posición en pantalla (event.position, en píxeles) y la posición en mundo ya convertida. Si mueves la cámara, verás que un mismo píxel de pantalla corresponde a distintas coordenadas de mundo.
Padre 45° y observa cómo cambia el global_position del hijo sin que cambie su position.to_local() sobre el padre para convertir un punto de mundo a local e imprímelo.Camera2D y verifica que el mismo clic en pantalla da una posición de mundo distinta.Label, la posición del ratón en mundo actualizada cada frame.event.position y get_global_mouse_position().Construye una escena con una Camera2D desplazable (por ejemplo, con las flechas) y un marcador que siga al ratón en coordenadas de mundo. Al hacer clic, deja una "huella" (instancia o marca) en esa posición de mundo, de modo que si mueves la cámara las huellas permanezcan ancladas al mundo, no a la pantalla. Criterio de aceptación: las huellas colocadas no se desplazan respecto al mundo cuando mueves la cámara, y el marcador coincide siempre con el cursor.
| Síntoma / mensaje | Causa y cómo arreglar |
|---|---|
| El marcador aparece desfasado del cursor | Usaste event.position (pantalla) como mundo; usa get_global_mouse_position(). |
| Mover el padre no mueve al hijo | El nodo no es realmente hijo en el árbol; revisa la jerarquía de la escena. |
El objeto "sube" al sumar a y |
Suposición de eje Y hacia arriba; en 2D sumar a y baja el objeto. |
global_position no cambia |
Modificaste position de un nodo sin padre transformado; ambos coinciden si el padre está en el origen. |
| Las huellas se mueven con la cámara | Fijaste su posición en espacio de pantalla; asigna global_position en mundo. |
❓ ¿Cuándo uso position y cuándo global_position? Usa position para ubicar respecto al padre y global_position cuando necesitas la posición absoluta en la escena, por ejemplo para colisiones o distancias entre objetos de distintas ramas.
❓ ¿Por qué el eje Y apunta hacia abajo en 2D? Hereda la convención de las pantallas y los sistemas de imagen, cuyo origen (0,0) está en la esquina superior izquierda y crece hacia abajo.
❓ ¿get_global_mouse_position() tiene en cuenta la cámara? Sí. Devuelve la posición del ratón ya transformada al espacio de mundo, considerando el desplazamiento y zoom de la Camera2D activa.
❓ ¿Qué hacen to_local() y to_global()? Convierten un punto entre el espacio de mundo y el espacio local de un nodo, útil cuando necesitas expresar una coordenada relativa a un objeto concreto.
Clase 017 - Gráficos por computadora: cómo se dibuja un frame