Ganar la Partida (fin)
Para acabar nuestro juego, vamos a implementar una condición de victoria. Para esto, vamos a crear un nuevo nodo que representará el objetivo que el jugador debe alcanzar para ganar la partida.
En primer lugar, vamos a añadir una nueva escena llamada end.tscn que representará el objetivo de la partida. Para crear esta escena, sigue estos pasos:
- Haz clic derecho en el panel de archivos y selecciona "New Scene".
- En la nueva escena, agrega un nodo
Node3Dcomo nodo raíz. - Renombra el nodo raíz a "Finish" o cualquier nombre que prefieras.
- Ahora vamos a añadir 3
StaticBody3Dcomo hijos del nodo raíz. Estos nodos representarán el objetivo que el jugador debe alcanzar para ganar la partida. - Para cada
StaticBody3D, añade un nodo hijo de tipoCollisionShape3Dpara definir la forma de colisión del objetivo. Puedes usar una forma de colisión de tipo caja para representar el objetivo. - También añade un nodo hijo de tipo
MeshInstance3Dpara darle una apariencia visual al objetivo. Puedes usar una forma de malla de tipo caja para representar el objetivo visualmente - Mueve y escala cada uno de los
StaticBody3Dpara crear un objetivo que el jugador pueda alcanzar. Por ejemplo, puedes colocar losStaticBody3Den diferentes posiciones dentro de la escena para que el jugador tenga que moverse por el escenario para alcanzarlos.
Puedes ver una previsualización de cómo se ve el objetivo en la siguiente imagen:

Además la jerarquía de la escena end.tscn debería verse así:
End (Node3D)
├── StaticBody3D
│ ├── CollisionShape3D (BoxShape3D)
│ └── MeshInstance3D (BoxMesh)
├── StaticBody3D
│ ├── CollisionShape3D (BoxShape3D)
│ └── MeshInstance3D (BoxMesh)
└── StaticBody3D
├── CollisionShape3D (BoxShape3D)
└── MeshInstance3D (BoxMesh)
Ahora que tenemos nuestro objetivo creado, vamos a agregarlo a la escena principal. Para esto, simplemente arrastra y suelta el archivo end.tscn desde el panel de archivos al panel de la escena principal. Esto creará una instancia del objetivo en la escena principal.
Para acabar de mostrar el área de finalización, vamos a añadir un nuevo nodo de tipo Area3D como hijo de nuestro nodo Finish. Este nodo se encargará de detectar cuando el jugador entra en el área de finalización para ganar la partida. Para esto, sigue estos pasos:
- Selecciona el nodo
Finishen el panel de la escena y haz clic en "Add Child Node". - En la lista de nodos disponibles, busca
Area3Dy selecciónalo. Esto agregará un nodoArea3Dcomo hijo del nodoFinish. - Añade un nodo hijo de tipo
CollisionShape3Dal nodoArea3Dpara definir la forma de colisión del área de finalización. Puedes usar una forma de colisión de tipo caja para representar el área de finalización. - Ajusta la forma de colisión para que cubra el área alrededor del objetivo. Esto permitirá que el área de finalización detecte cuando el jugador entra en esa área para ganar la partida.
Tras añadir el área la jerarquía del objeto Enden la escena principal debería verse así:
End (Node3D)
└── Area3D
└── CollisionShape3D (BoxShape3D)
Condición de Victoria
Ahora que tenemos nuestro objetivo y el área de finalización configurados, vamos a implementar la lógica para detectar cuando el jugador entra en el área de finalización y ganar la partida. Para esto, vamos a agregar un script al nodo principal de la escena principal.
Vamos a modificar el Script main.gd para agregar la lógica de victoria. Vamos a conectar la señal body_entered del nodo Area3D al método _on_body_entered(), que se encargará de detectar cuándo el jugador entra en el área de finalización. Si el jugador entra en el área de finalización, emitiremos una señal de victoria que detendrá el movimiento del jugador y mostrará un mensaje de "Has Ganado!" al jugador. Para esto, sigue estos pasos:
- Selecciona el nodo
Area3Den la jerarquia de nuestro objeto "finish" y en el panel de señales, conecta la señalbody_enteredal método_on_finish_area_body_entered(). Esto nos permitirá detectar cuándo el jugador entra en el área de finalización. El contenido de la función_on_body_entered()será el siguiente:
func _on_finish_area_body_entered(body):
if body.is_in_group("player"):
game_over.emit()
Probamos el juego y saltamos los obstaculos... Pero nos muestra el mensaje de "Game Over" en lugar de felicitar por haber ganado... Esto se debe a que usamos la misma señal game_over para indicar tanto la derrota como la victoria.
Para solucionar esto, vamos a modificar la señal game_overpara añadir un parámetro que indique si el jugador ha ganado o perdido la partida. Para esto, modificaremos la señal game_over de la siguiente manera:
signal game_over(victory: bool)
Ahora modificaremos el método de game_over() para que reciba el parámetro victory y muestre un mensaje diferente dependiendo de si el jugador ha ganado o perdido la partida. El código para esto sería el siguiente:
func _on_game_over(win:bool) -> void:
$player.started = false
if not win:
$UI/GameOverLabel.text = "Game Over"
else:
$UI/GameOverLabel.text = "Has Ganado"
$UI/GameOverLabel.visible = true
Ahora solo falta que modifiquemos tanto el método _on_body_entered() como el método _on_finish_area_body_entered() para que emitan la señal game_over con el valor correcto dependiendo de si el jugador ha ganado o perdido la partida. El código para esto sería el siguiente:
func _on_body_entered(body: Node3D) -> void:
if body.is_in_group("player"):
game_over.emit(false)
func _on_finish_area_body_entered(body):
if body.is_in_group("player"):
game_over.emit(true)
De esta forma, ya podremos diferenciar entre la derrota y la victoria en nuestro juego, mostrando un mensaje de "Game Over" cuando el jugador pierda la partida y un mensaje de "Has Ganado" cuando el jugador alcance el área de finalización. Esto hace que el juego sea más interactivo y proporciona una mejor experiencia al jugador, ya que ahora tiene una indicación clara de cuándo ha ganado o perdido la partida.

Con esto hemos terminado nuestro juego, por lo que en la próxima sesión, pasaremos a ver como integrar Realidad Virtual (VR) en Godot y como crear un juego para dicha plataforma.