Fall Down
Iremos pulsando sobre los misiles que caen de la parte superior de la pantalla para explotarlos.
Desarrollamos la escena principal
.
└── Scene2D
├── Timer
└── Sprite2D
Mostramos una traza cada cierto tiempo
Esta traza luego será sustituída por la creación de un misil.
extends Node2D
@export var rocket:PackedScene
@onready var timer = $Timer
func _ready():
timer.timeout.connect(put_missile)
func put_missile():
print("misil lanzado)
Instanciamos los misiles
Lo primero será crear el nodo de los misiles:
.
└── RigidBody2D
├── Sprite2D
└── CollisionShape2D
└── Area2D
└── CollisionShape2D
Como puedes ver en el esquema anterior, tanto el RigidBody2D como el Area2D tienen sus propios CollisionShape2D. Estos nodos CollisionShape2D no puedes ser compartidos por RigidBody2D y Area2D, pero lo que sí que podemos hacer es que la forma asociada a CollisionShape2D sea compartida.
Ahora vamos a instanciar los misiles desde la escena.
func put_missile():
var m = rocket.instantiate()
add_child(m)
m.position.x = randf_range(0, get_viewport_rect().size.x)
m.position.y = -60
Destruimos los misiles cuando sobrepasen cierta distancia
func _process(delta: float) -> void:
if(position.y > 1200):
queue_free()
Detectamos la pulsación de un misil
El nodo Area2D del misil emitirá una señal que recibirá el script y la procesará para mostrar una traza cuando hayamos hecho click:
func _on_area_2d_input_event(viewport: Node, event: InputEvent, shape_idx: int) -> void:
if event is InputEventMouseButton and event.pressed:
print("misil pulsado") # Replace with function body.
Vamos a añadir la animación de explosión.
1. Añadimos un nodo AnimatedSprite2D al nodo Rocket.
2. En el panel Inspector del nodo AnimatedSprite2D → Animation → Sprite Frames → New Sprite Frames.
3. En el panel SpriteFrames que se muestra, pulsamos en el botón Add frames from sprite sheet (ctrl + shift + o). Seleccionamos la imagen que contiene la spritesheet y marcamos los frames que compondrán la animación de explosión.

12. Marcamos Autoplay on Load y desmarcamos Animation Looping.

4. En la función que se ejecuta al hacer click en el misil, hacemos visible la animación (que habremos ocultado desde el panel de árbol de nodos) y la ejecutamos.
func _on_area_2d_input_event(viewport: Node, event: InputEvent, shape_idx: int) -> void:
if event is InputEventMouseButton and event.pressed:
$AnimatedSprite2D.visible = true
$AnimatedSprite2D.play()
get_parent().misil_exploted()
5. Asociamos la señal _on_animation_finished al script del rocket para eliminar el misil cuando la animación haya concluído.
extends AnimatedSprite2D
func _on_animation_finished():
queue_free()
Hacer marcador de vidas
Ponemos las vidas en pantalla
Ubicamos 3 nodos sprite2D en la escena. Estas imágenes serán las vidas del jugador.
En el inspector del nodo Sprite2D de las vidas → Animation → Hframes = 2
Llamamos a un método de la escena principal desde el script del misil
/rocket/rocket.gd
func _on_area_2d_input_event(viewport: Node, event: InputEvent, shape_idx: int) -> void:
if event is InputEventMouseButton and event.pressed:
get_parent().one_less_live()
/scenes/main/main.gd
func one_less_live():
print("one_less_live")
Ahora, en lugar de mostrar una traza, lo que queremos es que visualmente desaparezca una vida:
func one_less_live():
live_counter = live_counter -1
if live_counter == 2:
$Sprite2D/Lives/Live3.frame = 1
elif live_counter == 1:
$Sprite2D/Lives/Live2.frame = 1
else:
$Sprite2D/Lives/Live1.frame = 1
Finalmente, añadimos el código necesario para que si nos quedamos sin vidas se cargue la escena de perder.