var scoreplayer = -2
var scoreoponente = -2
En las variables score_player y oponente les asigne un -2, no es la mejor solución pero cumple con su objetivo.
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]:
¿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:
¿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]:
¿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:
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.
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.
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]:
¿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.
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.
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
Godot ofrece dos funciones que se ejecutan en cada frame, pero con propósitos distintos. Aquí está la regla práctica:
¿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).
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]:
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.
La solución replica la lógica del marcador del jugador con tres cambios mínimos:
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.
var scoreplayer = -2
var scoreoponente = -2
En las variables score_player y oponente les asigne un -2, no es la mejor solución pero cumple con su objetivo.
Tipografia PoetsenOne
Adicione la siguiente linea para concatenar texto al contador.
$MarcadorPlayer.text = "Player: " + str(PlayerScore)
$OponentePlayer.text = "Oponente: " + str(OponenteScore)

Reto solucionado. Lo que hice fue duplicar el MarcadorPlayer y cambiarlo por MarcadorOpente, luego seguí los mismos pasos que para el MarcadorPlayer pero utilizando el MarcadorOponente.
!Reto
algo mas simple y menos rebuscado de crear otro marcador

Tengo un problema Cuando la pelota choca con la parte de arriba del oponente o player se retrocede
**Reto Cumplido **
Lo que hice fue Duplicar el Label que ya estaba creado y cree otra variable para tomar los goles del oponente.

Aquí esta mi solución siguiendo lo hecho por el profesor.
extends Node2D
var PlayerScore = 0
var OponenteScore = 0
func _process(delta):
$Player2.text = str(PlayerScore)
$Oponente2.text = str(OponenteScore)
func _restart_game():
$Ball.is_moving = false
$Ball.direction =Vector2.ZERO
$Ball.position = Vector2(960, 540)
$Ball.reset_ball()
func _on_ArcoPlayer_body_entered(body):
OponenteScore += 1
_restart_game()
func _on_ArcoOponente_body_entered(body):
PlayerScore += 1
_restart_game()
El reto resuelto. Por cierto, no sé el bug de que inicia el contador en 2, así que lo solucioné colocando el marcador -2. Sé que no es lo mejor, peri bueno, sirve.

Para resolver el Reto Duplicar MarcadorPlayer y en este nuevo nodo, cambiar la posicion, el texto. Agregar otra variable para acumular el score del rival y agregar en el _process la logica para modificar el texto del marcador (nodo duplicado)

El problema del 2 como valor inicial lo resolvi moviendo los arcos 1 pixel fuera del marco

