Godot Game: disparando ráfagas
Disparar proyectiles individuales requiere una serie de pasos más o menos sencillos de cumplir. Disparar ráfagas no es mucho más complicado, pero necesita añadir una serie de pasos extra.
¿Qué se necesita para disparar?
Se necesita un evento que desencadene el mecanismo del disparo, que puede ser presionar un botón si queremos que dispare el jugador o, la detección del jugador, si queremos que dispare el enemigo, o simplemente el paso del tiempo.
Una vez producido el evento necesitamos añadir el proyectil al juego. Ese proyectil debe tener una dirección, una velocidad, un sprite y una forma de colisión, por lo menos. A parte, se pueden definir métodos que le den propiedades interesantes, como capacidad de hacer daño, o destruirse cuando impacta o desaparece de la pantalla.
Normalmente, se suele añadir un mecanismo de tiempo muerto o cool down, en el que no se puede disparar para evitar saturar la pantalla de proyectiles o añadir un poco de dificultad. Esto se puede reolver fácilmente con un Timer
Proyectil
Normalmente, el nodo raíz que utilizo es un Node2D, que tiene como hijos:
- Sprite
- HitBox
- VisibleOnScreenNotifier2D
El HitBox es estándar y ya hable de él en otro artículo. Lo que si es más nuevo es el VisibleOnScreenNotifier2D. Se trata de un nodo que tiene señales interesantes, como screen_entered o screen_exited. En mi caso utilizo la señal screen_exited para llamar al método self_destroy() cuando el proyectil desaparece de la pantalla.
Disparador
La escena que dispara, jugador o enemigo, tiene que instanciar al proyectil. Normalmente exporto una variable de tipo PackedScene en la que defino el proyectil que va a ser disparado. Luego, en el método shoot(), creo un nuevo proyectil, le asigno su posición y lo añado a la escena principal, de esa forma, si el nodo padre desaparece, por ejemplo, porque muere el enemigo, no desaparecen todas las balas instanciadas por él.
A parte de los nodos propios de la escena, puede incluir un timer para gestionar el tiempo de cool down.
Evento desencadenante
Es lo más variable y dependerá de quién dispare habrá que colocarlo en un nodo u otro.
Disparando ráfaga
En el caso de disparar en ráfagas, es necesario, además, definir el número de balas que se van a disparar en cada ráfaga y el tiempo que va a pasar entre cada una de ellas. Por lo que será necesario tener un timer para el tiempo mínimo entre cada ráfaga cool down y otro para el tiempo entre cada bala, o pausa entre balas.
El proceso sería algo así:
Si cool_down no está activo:
repetir n veces:
si pausa_entre_balas está activa:
esperar a que acabe la pausa
disparar
comenzar pausa_entre_balas
comenzar cool_down
Que habría que traducir a GDScript
func rafaga() -> void:
for i in range(balas_en_rafaga):
if !pausa_entre_balas.is_stopped():
await pausa_entre_balas.timeout
shoot()
pausa_entre_balas.start()
cool_down.start()
Lo único que es necesario ahora es definir cuando se van a disparar las ráfagas y eso puede hacerse detectando la presencia del jugador o activándola en cuanto el enemigo entre en pantalla, etc.
Espero que le pueda servir a alguien. Un saludo.