Scripts en Godot

Para desarrollar nuestros juegos necesitamos aprender sobre un lenguaje de programación, en Godot tenemos cuatro opciones:

  • GDScript: es un lenguaje diseñado para Godot, se adapta perfectamente con el editor y esta basado en la sintaxis de Python.
  • VisualScript: te permite crear funcionalidades con una «programación visual», también se adapta perfectamente con el editor de Godot y se asemeja a los Blueprints usados en Unreal Engine.
  • C++: el lenguaje con mejor rendimiento que podemos tener en un motor de videojuegos, ahora en Godot 3 podemos incluirlo fácilmente como GDNative.
  • C#: incluido en la última actualización de Godot, disponemos de soporte oficial para el lenguaje de programación mas querido para el desarrollo de vídeojuegos. Para usarlo necesitaremos descargar la versión Mono de Godot.

Es recomendable que aprendas un lenguaje de programación como C# o C++, son más generales y aprenderlos te puede ser útil para otro trabajo de software. Actualmente se esta mejorando la integración de C# en Godot, aunque todavía no se encuentra la estabilidad de Unity (motor que lleva años usándolo), ya puedes empezar a hacer pruebas con C# desde Godot.

Me parece que el flujo de trabajo en VisualScript es mas lento, es una buena alternativa al código para las personas que recién empiezan a programar. Si ya tienes conocimientos previos sobre un lenguaje de programación y entiendes sobre los fundamentos básicos, te vendría mejor aprender un poco sobre GDScript, no es difícil y, al igual que VisualScript, esta preparado para funcionar perfectamente en Godot.

Si somos unos maestros y queremos el mejor rendimiento para nuestro proyecto, podemos combinar los cuatro lenguajes. No hay límites para trabajar en Godot.

Agregar un Script

Para agregar un nuevo Script, vamos a hacer clic derecho en un nodo y buscamos la opción «Adjuntar Script»:

Es importante especificar el lenguaje que usaremos y la ruta donde guardaremos el documento. Por defecto se guarda en la misma carpeta del nodo al que adjuntamos el script.

Funciones básicas en GDScript

Si creamos el script con la plantilla «Predeterminado», vamos a encontrar lo siguiente:

extends KinematicBody2D

# class member variables go here, for example:
# var a = 2
# var b = "textvar"

func _ready():
	# Called every time the node is added to the scene.
	# Initialization here
	pass

#func _process(delta):
#	# Called every frame. Delta is time since last frame.
#	# Update game logic here.
#	pass

Todas las líneas con un signo «#» se consideran comentarios, no influyen en el juego. Además, también se añaden dos funciones:

  • _ready(): se usa para programar todo lo que pasa al momento de iniciar el nodo, sólo se ejecuta una vez. En ella tenemos que indicar el inicio de otras funciones necesarias.
  • _process(delta): es una función muy importante, todo lo que pongamos se ejecutará mientras el nodo este activo.

Si ponemos:

func _ready():
	print("Hola Mundo")

Se imprimirá en la consola una sola vez: «Hola Mundo», cuando iniciemos la escena.


Esto es un resumen de los lenguajes disponibles en Godot, en Indie Libre se traerán más tutoriales que expliquen sobre GDScript.

Cómo instanciar escenas en Godot

En Godot cada escena puede ser un componente para nuestro juego. Tenemos la posibilidad de juntar muchas escenas dentro de un nodo principal (visto de este modo las escenas son como familias de nodos que se juntan con un nodo padre).

Puedes descargar el proyecto Aquí.

Instanciar escenas desde el editor

Cuando guardamos una escena, se convierte en un PackedScene y genera una extensión «.tscn».  Podemos hacer la instancia de una escena para colocarla dentro de un nivel. Para instanciar desde el editor tenemos que hacer clic en el siguiente botón:

Se nos abrirá el buscador de recursos y seleccionaremos la escena que queremos instanciar.

Después, en la posición (0,0) de nuestro nivel, se colocará la nueva escena.

Podemos moverla y usar las propiedades del nodo padre, pero no podemos cambiar sus nodos. Para eso tenemos que entrar en la escena, haciendo clic en el icono que se encuentra al lado de su nombre:


Instanciar escenas desde código

Al momento de instanciar objetos aleatorios o balas, no podemos usar el editor, ya que no sabemos en qué lugar vamos a poner la instancia.

Para instanciar algo mediante código, podemos hacer lo siguiente:

func _disparar():
	var newBala = load("res://Bala/Bala.tscn").instance()
	get_parent().add_child(newBala)
	newBala.global_position = $spr/pos_disparo.global_position
	newBala.direction = int($spr.scale.x)
	newBala.scale.x = $spr.scale.x

Con «load()» podemos indicar la ruta de los recursos que queramos cargar. Tenemos que usar la dirección del archivo dentro de nuestra carpeta de proyecto, empezando con «res://». Además de eso, hay que tener en cuenta que se tiene que especificar el tipo de archivo «.tscn», «.gd», etc.

Cuando vamos a instanciar una escena, la debemos guardar en una variable para poder trabajar con sus propiedades.

Si colocamos «add_child(var_Instancia)» vamos a añadir nuestra nueva instancia como hija del nodo que esta ejecutando el código. Cuando estamos en un nivel, podemos usar un «get_parent().add_child(var_Instancia)» para obtener al padre del nodo que ejecuta el código y colocar nuestra nueva instancia como hija.

Recordemos que al instanciar un objeto, su posición inicial dentro del nivel es la (0,0). Con «global_position» podemos cambiar su posición usando un valor en «Vector2()». En caso de que sólo queramos cambiar su posición horizontal o vertical, usamos «global_position.x» o «global_position.y» y como valor ponemos un número entero.


Ya terminamos. Con estos sencillos pasos van a poder instanciar escenas en sus proyectos de Godot, si tienen una duda pueden dejarla en los comentarios.

¿Qué son los Nodos y las Escenas en Godot?

Cuando una persona con experiencia en otro motor llega a Godot, va a comparar el flujo de trabajo y se asegurará de que su nueva herramienta sea «mejor» o, al menos, cumpla sus expectativas. Si llegan con la intención de manipular escenas como si de Unity se tratara, van a encontrar que están diseñadas de una forma diferente, mientras que en Godot las escenas son un «todo» en Unity no consiguen un nivel tan alto de importancia. Hoy voy a explicar un poco sobre los nodos y escenas en Godot.

Seguir leyendo ¿Qué son los Nodos y las Escenas en Godot?

Movimiento y salto de un cuerpo

Vamos a aprender sobre las funciones básicas para el movimiento de un cuerpo KinematicBody2D. Haremos que se mueva y pueda saltar en la tierra.

Puedes descargar el proyecto final desde Aquí.

Creando los nodos

Nuestro jugador es un KinematicBody2D. Sus hijos son:

  • Sprite2D (spr): encargado de guardar la imagen del jugador.
  • CollisionShape2D (col): es la mascara que define el lugar donde el cuerpo tiene colisiones.
  • Camera2D: es la cámara que centra la imagen del juego en el protagonista.

Además de eso, nuestro jugador tiene una hoja al lado de su nombre. Es un script, lo tenemos que crear para poder programar su movimiento.

Programando dentro del script

Dentro del proyecto que han descargado, van a encontrar todo el código que yo he realizado. Voy a explicarlo por partes:

Primero vamos a crear las variables.

# Contenedores de resultados fisicos para el movimiento
var distance = Vector2()
var velocity = Vector2()

# Velocidades
var speed = 140
var gravity = 650
var jump_speed = 250

Con las variables de tipo Vector2() vamos a controlar el movimiento del Kinematic en la pantalla, podemos cambiar su aceleración desde las variables que declaramos debajo. Si quieren más información sobre el movimiento que vamos a realizar, pueden buscar en internet sobre el Movimiento Rectilíneo Uniforme (M.R.U).

Ahora vamos a activar el proceso físico y dentro le ponemos nuestra función para calcular el movimiento.

func _ready():
	set_physics_process(true)

func _physics_process(delta):
	_move(delta)

La función _move no viene por defecto en Godot, es necesario que nosotros la creemos. Vamos con eso.

# Controlador de todo lo relacionado con el movimiento
func _move(delta):
	
	# Dirección del jugador según la tecla presionada
	var direction_x = int(Input.is_action_pressed("ui_right"))-int(Input.is_action_pressed("ui_left"))

Ya hemos creado la función _move (recordemos que se le tiene que pasar como parámetro el Delta, por ser el tiempo). Dentro de _move tenemos casi todo el código del tutorial, primero declaramos una variable para la dirección (direction_x).

El valor de esa variable parece difícil de entender, pero es muy  fácil: vamos a obtener el valor de las flechas «derecha» y «izquierda» cada vez que sean presionadas. Cuando usamos una función con «is_action…» vamos a tener un valor booleano, así que lo pasamos a «int»(número entero), cuando es True nos llega un 1, con False llega un 0. Si se presiona la flecha de la izquierda, se resta al 0, y si es la derecha, se suma.

Ahora vamos a aplicar un cambio en nuestra imagen.

if direction_x < 0:
		$spr.flip_h = true
	elif direction_x > 0:
		$spr.flip_h = false

Si nuestra dirección es -1, vamos a voltear la imagen de nuestro jugador. En caso contrario, la ponemos normal.

Recordemos que para voltear la imagen tenemos que entrar en el Sprite2D (spr) y alterar sus parámetros. Para entrar en un nodo hijo del jugador (o cualquier nodo), usamos el «$» con el nombre del nodo ($spr) y después de un «.» escribimos el parámetro que queremos usar.

Ahora vamos a usar las formulas físicas que se usan en el M.R.U.

# Formulas fisicas para obtener la velocidad y la gravedad
	distance.x = speed*delta
	velocity.y += gravity*delta
	velocity.x = (distance.x*direction_x)/delta

En la «velocity.x» es necesario calcular la distancia junto con la dirección, ya que la dirección se encarga de convertir el valor en negativo o positivo. Si no se usa, siempre será positivo y siempre irá a la derecha.

Para aplicar todo lo que hemos calculado ponemos:

# Aplicar el movimiento y ajustar un suelo
	move_and_slide(velocity, Vector2(0,-1))

Con eso tenemos el movimiento, calculado en nuestra variable velocity. Además, aplicamos la gravedad.

En el segundo parámetro (Vector2(0,-1)) estamos indicando que la parte de un objeto, que nosotros conocemos como «piso» es arriba.


Ahora tenemos el movimiento, sólo falta arreglar los problemas con la gravedad y aplicar el salto del jugador.

Primero tenemos que obtener una lista de las colisiones cada vez que nos movemos (todo dentro del _move()).

# Obtener las colisiones cada vez que chocamos con otro cuerpo
	var get_col = get_slide_collision(get_slide_count()-1)

Con esto vamos a tener la última colisión que se realice entre nuestro jugador con otro cuerpo. Ahora vamos con el salto:

if is_on_floor():
		velocity.y = 0
		
		if Input.is_action_just_pressed("jump"):
			velocity.y = -jump_speed

Esto es sencillo: con «is_on_floor» estamos diciendo que cada vez que estemos en el piso (lo definimos arriba), se cancele la gravedad y se ejecute lo que tengamos dentro. En nuestro caso, sólo tenemos dentro otro «if» que usamos para que al momento de presionar la tecla de espacio se aplique la velocidad de salto. Recuerden que el negativo es para arriba y el positivo para abajo, por eso la velocidad de salto es negativa… la acción «jump» no esta por defecto, si quieres aprender a crear tus propias acciones ven Aquí.

Ya hemos terminado. Si tienen una duda, déjenla en los comentarios y trataré de responderla.

Puedes complementar lo que has leído aquí con el siguiente vídeo:

Juegos Indie y Software Libre