Instanciar balas de nave espacial en Godot Engine

por Sep 10, 2018Godot Engine, Tutoriales0 Comentarios

Una buena parte de los desarolladores indie han realizado un “Space Shooter” en su vida. Si quieres aprender a realizar los “disparos” con una nave espacial desde Godot, pasemos al artículo.

Nodos para la nave del jugador

Doy por hecho que su nave ya esta preparada: es un nodo KinematicBody2D y tiene su imagen. Además de eso, vamos a crear un nuevo nodo llamado “Position2D”, seguro adivinarán que se trata de una posición que podemos asignar en cualquier parte de la escena. La colocamos por encima del jugador, a cierta distancia.

Escena de la bala

La bala se creará por separado. Al igual que el jugador, su nodo principal es un KinematicBody2D que llamaremos “Bala”. Dentro de ella crearemos su Sprite y el CollisionShape2D, la guardamos con Control+S y añadimos un nuevo Script.

Script de la bala

Tienen permiso para eliminar todas las líneas de comentario. En el principio vamos a añadir dos variables:

var dir = -1
var speed = 500

La variable “dir” define la dirección que debe tomar la bala cuando es instanciada en la escena. Si es -1 subirá y en 1 bajará.

Activamos la función “_process()” y dentro de ella ponemos lo siguiente:

func _process(delta):
	var move = move_and_collide(Vector2(0,dir*speed*delta))
	if move != null:
		if move.collider.is_in_group("Enemigos"):
			move.collider.queue_free()
		elif move.collider.is_in_group("Jugador"):
			move.collider.queue_free()
		
		self.queue_free()
	
	if global_position.y > 720 || global_position.y < 0:
		self.queue_free()

La variable “move” sólo se puede usar dentro de la función _process(), es una variable local. Le ponemos un “move and collide” de valor, ya que esa función se usa para mover cuerpos Kinematic y consume menos recursos que un “move_and slide”. Al ser una función de movimiento, le vamos a pasar un parámetro de Vector2().

Dentro del Vector2() vamos a colocar nuestra formula de movimiento para que la bala se mueva. Su segundo parámetro corresponde al eje “Y” (el vertical). Como nuestra bala se moverá hacía arriba, sólo usaremos el eje vertical. La operación “dir*speed*delta” hará que cada segundo se aplique la aceleración en la bala, así veremos como se mueve en la escena. Cuando “dir” es negativo hace que la aceleración también sea negativa, pero cuando “dir” es positivo la aceleración queda positiva y la bala se mueve para abajo.

Cuando quieran comprobar una colisión con la bala, usan lo siguiente:

if move != null:
		if move.collider.is_in_group("Enemigos"):
			move.collider.queue_free()
		elif move.collider.is_in_group("Jugador"):
			move.collider.queue_free()

En caso de que la variable “move” no valga “null”, significa que chocamos con algo. Para saberlo usamos “move.collider” eso indica con que nodo chocamos. Ustedes se pueden inventar muchas cosas a partir de eso, yo pondré esto:

Si el “collider” sea quien sea, se encuentra en el grupo de “Enemigos” o “Jugador”, entonces elimina al collider.

Además, cada vez que la variable “move” sea verdadera eliminamos a la bala con self.queue_free().

Por último en el script de la “bala”, vamos a decir que si la posición en el eje «Y» es mayor que “720” (El 720 lo pueden cambiar por el tamaño de pantalla en “altura” que tengan en la configuración de ventana), entonces se autodestruye. En caso de que sea menor que 0, también la autodestruyes. Cuando sea menor que 0 es porque salió de la pantalla y esta muy alto.

Aquí cambiamos el 720 de altura por el numero que quieran…

Script del jugador

Ya que tenemos una bala para instanciar, vamos con el script del jugador. Primero vamos a añadir esta variable:

var bala = load("res://Bala/Bala.tscn")

Con el «load» estamos cargando un recurso de nuestra carpeta de proyecto. La ruta de la escena que contiene la bala la podemos obtener así:

Clic derecho en el recurso que queramos y después «Copiar ruta»

En la función _process() del jugador añadimos lo siguiente:

if Input.is_action_just_pressed("disparar"):
		_disparar()

El «Input.is_action_just_pressed()» va a ser verdadero cada vez que se presione una vez la acción que indiquemos como parámetro, en este caso estoy usando una acción llamada «disparar». La podemos crear de la siguiente manera:

La función _disparar() tampoco esta creada, la vamos a definir para poner el siguiente código:

func _disparar():
	var newBala = bala.instance()
	get_parent().add_child(newBala)
	newBala.global_position = $pos_bala.global_position
	newBala.dir = -1

Cada vez que hagamos clic en el botón de espacio (se active la acción disparar), una nueva variable «newBala» creará una instancia de la variable bala que creamos arriba.

Esa nueva instancia se volverá hija del padre del jugador. Con get_parent estamos accediendo al nodo que sea padre de la escena portadora del script, en nuestro caso, el jugador es el que esta usando el «get_parent». Ya con el add_child estamos colocando a la nueva instancia como hija del padre (hermana del jugador :p).

Recuerden que para acceder a las propiedades de un nodo sólo tienen que poner el «.» después de una variable que contenga la instancia del nodo. newBala contiene al nodo de la bala, si usamos un «.» vamos a poder acceder a sus propiedades. Colocamos su posición global igual a la posición global del nodo «pos_bala» que fue el nodo que añadimos junto con entrar en el tutorial.

Con el signo de dólar ($) podemos acceder a los nodos que sean hijos del portador del script. En nuestro caso desde el jugador podemos acceder al pos_bala, el Sprite y el CollisionShape.

Ya con esto hemos terminado el tutorial. Espero que sea de su agrado y aprendan algo :).

Puedes acceder al código del proyecto buscando «SpaceShip» en la Biblioteca De demos: https://gitlab.com/indielibre/bdd/

¡Comenta! 👇️

0 comentarios

Enviar un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

¿Qué son los setters/getters en GDScript?

¿Qué son los setters/getters en GDScript?

En varios tutoriales donde hago uso de la palabra reservada "setget", dejo el enlace con la explicación de la documentación oficial sobre esa función. Sea porque en una que otra ocasión me haya olvidado de enlazar al manual, o todavía no se entienda bien, llegan...