Disparar una nave espacial en Godot Engine


En el artículo de hoy quiero enseñar a realizar disparos en juegos de naves espaciales, juegos muy desarrollados cuando se inicia en un motor de vídeojuegos.

El proyecto que he realizado y que pueden usar para hacer las pruebas se encuentra aquí: Descargar

Ahora voy a explicar lo que tienen que hacer:

Crear los nodos

Vamos a necesitar una escena para el jugador y otra diferente para la bala. Cada una se puede considerar como un nodo kinematic con su respectivo collision_shape. Además es importante resaltar que necesitamos un nodo que se encargue de destruir las balas cuando ya salgan de la pantalla y no sean útiles, ya que se quedan ocupando memoria y eso hace que el juego sea más lento. Yo he decidido usar un nodo area2D que le manda señales al código del jugador cada vez que un nodo que sea específicamente un cuerpo físico entre en el área, en caso de que sea parte del grupo "Balas" el area2D va a destruirlo.

Así tengo la escena del jugador, el nodo que dice "pos_inicio" es una Position2D un punto que uso para el inicio de la bala:

 Y así tengo la bala.

Como pueden ver, en el nodo de la bala hay un cuadro al lado del nombre y la hoja de código, eso indica que el nodo se encuentra dentro de un grupo. Un nodo puede ser parte de muchos grupos, añadirlos es muy fácil:

Pasamos al código

Sólo vamos a necesitar dos hojas de código, la primera para el jugador y la segunda para la bala. Ya que necesitamos controlar su dirección y alguna otra cosa que le quieran poner desde ella.

Al inicio del script para el jugador vamos a tener una "export var" para controlar la rapidez de movimiento en el nodo, con export la vamos a poder editar en el inspector de nodos.

Usando physics_process

 
Tenemos un proceso físico, es una función que se repite cada segundo y se usa para trabajar con las colisiones. Ahí dentro pongo una función creada por mi que se llama "_move" y se usa para controlar el movimiento y las colisiones del jugador (aunque en este caso no hay colisiones) se le tiene que pasar la variable "delta" para poder trabajar con el tiempo dentro de _move. En el proceso físico también se tiene que poner la condición para activar una función que se encargue de producir el disparo, yo he usado "is_action_just_pressed()" para que sólo se active una vez por toque, si quieren que sea seguido como una ametralladora tienen que usar un controlador de tiempo (ya tengo próximo artículo xd).

Dentro de _move



*Hay más comentarios que código, espero que entiendan todo .-. *
La variable moveX se usa para saber la dirección según las teclas presionadas. Si se presiona la tecla izquierda se le resta un 1 al 0 (-1 es izquierda) y en caso contrario se suma (1 es derecha) si no se presiona ninguna el resultado es 0.  En el move_and_collide() podemos retornar información cuando recibimos una colisión, pero como este proyecto es tan sencillo no hace falta. Como todo movimiento, se trabaja con un Vector2 y sólo tenemos que mover el eje X, así que usamos nuestras variables. Cuando multiplicamos el moveX sólo estamos aplicando un cambio de signo (- o +) ya que al multiplicarlo con la speed que es 400, sólo decimos que si moveX es negativo sea igual a -400 y positivo 400.

Dentro de _disparar

 
En la variable "bala" vamos a cargar el nodo de nuestra bala buscándolo dentro de la carpeta de proyecto. Usando un instance() lo estaríamos creando dentro de la escena, sólo queda añadirlo como hijo de alguien. Para eso lo recomendable es usar un "get_parent()" para saber sobre el padre del jugador y poner un add_child() (con nuestra variable "bala" como parámetro, ya que contiene la instancia que fue creada) para añadir el nuevo nodo a la escena y que no quede vagando por el limbo.

Si recuerdan el nodo de position2D que tenemos en el jugador, ya es hora de usarlo. Tenemos que buscar su posición y ya lo tenemos listo, ya podemos poner instancias de las balas.

Eliminando balas



Esta es la señal que el nodo del area2D envía al código del jugador para comprobar cada cuerpo físico que entre en su espacio. Vamos a preguntar si el cuerpo que detecta (body) se encuentra dentro del grupo "Balas", en ese caso el cuerpo se puede destruir con queue_free().

Movimiento para la bala

 
Nuestra bala no se iba a mover sola, le tenemos que añadir un código, dentro de su función de procesos le ponemos un movimiento fijo de -700 cada segundo  (el negativo es la dirección de arriba).

Eso es todo. Espero que les sea útil esta información, si tienen una duda pueden dejarla en los comentarios.

Desde el Nautilus, me despido

4 comentarios:

Con la tecnología de Blogger.