Contenido del curso
Tu primer juego
Desarrollando el juego
Conclusión
Marcador de goles en Godot con class_name
Resumen
Construir el marcador de Pong en Godot implica algo más que mostrar números en pantalla: necesitas dominar nodos de interfaz, funciones de actualización por frame y una técnica clave llamada class_name para evitar colisiones falsas. Aquí te muestro cómo armar el contador de goles paso a paso, replicando el clásico de Atari con código limpio y reutilizable.
¿Qué nodo se usa para mostrar texto en Godot?
Godot diferencia los nodos por colores y los verdes corresponden a la interfaz de usuario. El nodo Label es el que te permite incorporar texto a la pantalla, y será la base de tu marcador.
Dentro del nodo level agrega un Label llamado MarcadorPlayer. En el inspector vas a configurar tres cosas básicas para que el texto se vea bien posicionado [02:15]:
- Alineación horizontal y vertical centrada para que el texto quede en el centro del rectángulo.
- Tamaño del rect igual al tamaño de la pantalla, así el centrado tiene sentido.
- Margen izquierdo de -200 píxeles para desplazar el marcador del jugador hacia la izquierda.
¿Qué es un nodo Label en Godot? Es un nodo de interfaz que muestra texto en pantalla. Lo usas para marcadores, títulos, instrucciones o cualquier elemento textual de UI.
¿Cómo cargar una tipografía personalizada?
Arrastra tu archivo de fuente a la librería del proyecto. Luego, en el panel Theme Overrides del Label, busca la opción fonts y crea un nuevo DynamicFont. Dentro de esa fuente dinámica vas a encontrar el campo font data, donde arrastras el archivo de tipografía [04:20].
Desde ahí puedes ajustar el tamaño a 32 píxeles en lugar de los 16 por defecto y elegir un color naranja para que el marcador resalte sobre el fondo.
¿Cómo actualizar el marcador con código en GDScript?
El texto inicial es solo un placeholder. Lo que realmente quieres es que el número cambie cada vez que se anote un gol. Para eso vas al script de level y declaras una variable que guarde los goles:
gdscript var player_score = 0
Cada vez que la pelota atraviesa el arco del oponente, antes del reset_game, sumas uno [06:40]:
gdscript player_score += 1
¿Cuál es la diferencia entre process y physics_process?
Godot ofrece dos funciones que se ejecutan en cada frame, pero con propósitos distintos. Aquí está la regla práctica:
- process se usa para actualizar elementos de interfaz como textos, marcadores o cualquier UI.
- physics_process se reserva para mover personajes, calcular colisiones y todo lo relacionado con físicas.
¿Cuándo usar process en Godot? Úsalo siempre que actualices elementos visuales o de interfaz. Para físicas y movimiento de cuerpos, usa physics_process.
Dentro de process actualizas el texto del Label accediendo al nodo y a su propiedad text. Pero hay un detalle: la propiedad text solo acepta cadenas, y player_score es un número entero. Por eso necesitas la función str(), que convierte enteros o floats a string [08:30]:
gdscript func _process(delta): $MarcadorPlayer.text = str(player_score)
Un truco útil: si dejas el mouse sobre el nombre de una propiedad en el inspector, Godot te muestra el nombre real que debes usar en código (siempre en minúsculas, con guiones bajos para palabras compuestas como clip_text).
¿Por qué el marcador inicia en 2 y cómo solucionarlo?
Al ejecutar el juego notarás un bug curioso: ambos marcadores arrancan en 2. Esto sucede porque los arcos están configurados para detectar cualquier colisión con un cuerpo, y al inicio están tocando las paredes superior e inferior del escenario.
La solución elegante pasa por class_name, una palabra clave que te permite nombrar un script como un tipo de nodo reutilizable. En el script de la pelota agregas:
gdscript class_name Ball extends KinematicBody2D
Esto tiene dos ventajas concretas [11:50]:
- Cuando agregas un nodo nuevo desde la interfaz, Ball aparece como opción seleccionable.
- Puedes usar Ball como tipo en condicionales para filtrar colisiones.
¿Cómo filtrar colisiones por tipo de nodo?
En el script de level, dentro de la función que detecta la entrada en el área del arco, agregas una condición que valide el tipo del cuerpo que entra:
gdscript if body is Ball: player_score += 1 reset_game()
Aplicas la misma lógica en ambos arcos. Ahora el marcador solo suma cuando la pelota cruza el área 2D, ignorando las paredes que estaban generando los puntos fantasma.
Reto: ¿cómo crear el marcador del oponente?
La solución replica la lógica del marcador del jugador con tres cambios mínimos:
- Duplica el nodo MarcadorPlayer y renómbralo MarcadorOponente.
- Cambia el margen izquierdo de -200 a 200 para desplazarlo a la derecha.
- Crea una variable opponent_score y actualízala cuando la pelota cruce el arco del jugador.
Dentro de process imprimes el valor con $MarcadorOponente.text = str(opponent_score).
Con el marcador funcionando y las colisiones filtradas correctamente, tu Pong ya cuenta goles como el original. ¿Cómo resolviste el reto del marcador del oponente? Cuéntanos en los comentarios qué variante usaste.