Galería de tiro 1

Galería de tiro

Galería de tiro 2

Galería de tiro

En esta lección, aprenderemos a desarrollar un juego de galería de tiro en 2D utilizando Godot. Crearemos una escena en la que los jugadores puedan disparar a objetivos en movimiento y acumular puntos según su precisión. Aprenderemos a manejar nodos 2D, detectar colisiones y gestionar la lógica del juego con GDScript.

Descargar imágenes

Pasos en la resolución

Paso 1: Creación de la Escena Principal con un timer

.
└── Node2D
├── Sprite2D
└── Timer (habrá que marcar la check de autostart)
extends Node

func _ready():
	$Timer.timeout.connect(put_enemy)

func put_enemy():
	print("aaaa")

Paso 2. Creación de uno de los enemigos

.
└── Node2D
└── AnimatedSprite2D
extends Node2D

var speed:int = 100

func _process(delta):
	position.x += speed * delta

Actualizamos el código de la función que ponía al enemigo en pantalla:

func put_enemy():
	var m = load("res://characters/caterpillar/caterpillar.tscn").instantiate()
	add_child(m)
	m.position.x = -60
	m.position.y = 200

Volvemos a actualizar la función put_enemy para que los enemigos siempre aparezcan en posiciones verticales aleatorias dentro de los límites de la pantalla:

var sprite_height = m.get_node("AnimatedSprite2D").sprite_frames.get_frame_texture("default", 0).get_size().y
m.position.y =  randf_range(sprite_height/2, get_viewport().get_visible_rect().size.y-sprite_height/2)

Actualizamos nuevamente la función put_enemy para que los enemigos puedan aparecer inicialmente en dos posiciones diferentes en función de un valor aleatorio:

var side = randi() % 2  # 0 o 1 aleatoriamente

if side == 0:
	m.position.x = 0
else:
	m.position.x = 400

Si el enemigo fue instanciado en la parte derecha de la pantalla, se moverá horizontalmente hacia la izquierda:

else:
	m.position.x = 400
	m.change_direction()
extends Node2D

var speed:int = 100
var direction:int = 1

func _process(delta):
	position.x += direction * speed * delta

func change_direction():
	direction = -1

Ahora, la posición x del enemigo cuando parte de la parte derecha de la pantalla ya no será 400, sino que será algo más del límite horizontal de la pantalla:

var sprite_width = m.get_node("AnimatedSprite2D").sprite_frames.get_frame_texture("default", 0).get_size().x
m.position.x = get_viewport().get_visible_rect().size.x + sprite_width 

Paso 3. Eliminando a los enemigos

Primero vamos a añadir un nodo Area2D para poder detectar la pulsación sobre el enemigo:

.
└── Node2D
├── AnimatedSprite2D
└── Area2D
└── CollisionShape2D

Recuperaremos la señal de hacer click del area2D en el script que ya teníamos:

func _on_area_2d_input_event(viewport: Node, event: InputEvent, shape_idx: int) -> void:
	if event is InputEventMouseButton and event.pressed:
		print("Clicked Enemy")

Ahora detonamos la animación de explosión cuando pulsemos sobre el enemigo:

$Explosion.visible = true
$AnimatedSprite2D.visible = false
$Explosion.play()

Finalmente, eliminamos la instancia cuando la animación termine, recibiendo la señal emitida por el nodo de la animación de explosión:

func _on_explosion_animation_finished() -> void:
	queue_free()