Hola, bienvenidos sean a mi nuevo post, hoy hablaremos sobre los scripts en godot, los scripts son controladores de los nodos estos pueden ser realizados a traves de 4 lenguajes distintos, a partir de la version 3.0 se incrementaron los lenguajes, estos son:

Anuncios
  • GDscript: Es el lenguaje nativo del motor, es el mejor integrado con las escenas, nodos y otros elementos, tiene funciones para ayudar con la algebra lineal y el mas practico para una persona que da sus primeros pasos en programacion.
  • VisualScript: Es un tipo de lenguaje orientado a los no-programadores, del estilo “bloques y conexiones” pero integrado al estilo de trabajo de godot.
  • .NET / C#: El lenguaje C# de Microsoft tambien es soportado por godot, es la gran opcion de las mayoria de los programadores de juegos y compañias, es decir menos tiempo de capacitacion y mayor tiempo de programacion.
  • GDnative / C++: De todas las integraciones nuevas, es la mas brillante porque se puede utilizar cualquier version de C++ sin necesidad de recompilar o reiniciar godot.

Los tres primeros lenguajes son propios o integrados pero el ultimo, GDNative, no solamente permite la integracion de C++ sino de otros lenguajes pero esta opcion no tiene un soporte completo (salvo en C++). Lo ideal seria aprender GDscript pero si se sienten mas comodos con otros lenguajes quedan libres de hacerlo, como digo siempre queda a criterio del programador pero en los instructivos utilizare GDscript, ahora vamos a programar via script nuestras primera escena.

Primero vamos a crear un nuevo proyecto, una vez creado tendremos solamente tres nodos, un panel, un boton(button) y una etiqueta (label). Esto lo hacemos como hasta ahora, vamos a la solapa Escena, le damos al signo Mas (+), buscamos y agregamos primero el elemento Panel, luego nuevamente con el Mas o con Ctrl+A agregamos unos nodos hijos a Panel, en este caso van a ser un boton (button) y uno de etiqueta (label), una vez creado todo en la solapa de Escena nos deberia quedar asi

godot32

Pueden modificar los tamaños de los elementos, y escribirles algun texto a traves de la solapa Inspector de cada elemento, les dejo un ejemplo de como lo modifique

godot33.png

Finalmente ya tenemos nuestra escena preparada, ahora pasaremos a hacer la “magia”, en la solapa Escena elegiremos a Panel y tenemos dos opciones: hacemos click con el boton derecho y elegimos Adjuntar script o le damos click al boton resaltado con el circulo

godot34

Una vez elegido, aparecera el siguiente cuadro de dialogo

godot35

Aca le muestro las opciones de Idioma para los scripts

godot36

En general. lo dejaremos por defecto lo unico modificado por nosotros va a ser la ruta, por lo menos por ahora, donde por ejemplo lo renombre de res://panel.gd a res://dihola.gd, luego le damos a crear y deberiamos tener nuestro script generado

Anuncios
godot37

Con esto tenemos nuestro script creado, observen a Panel ahora tiene un signo de script colocado, volviendo al script tendremos unas lineas cargadas por defecto: estas son:

extends Panel
func _ready()
pass 

Esto es una simple plantilla la cual no tiene injerencia es nuestra escena y nodos, empecemos con la manipulacion de las señales, una señal es emitida con una accion determinada, y estas pueden ser conectadas con alguna instancia del script, en la mayoria de los casos estan relacionadas con los nodos de GUI (Interfaz Grafica del Usuario por sus siglas en Ingles) con otros tambien e inclusive se pueden definir señales propias dentro del script, haremos un paso a paso para ver que son y como se utilizan las señales de los nodos.

En nuestro proyecto dentro de la solapa Escena elegimos el nodo Button, y en la solapa inferior elegimos Nodo, por defecto nos elegira Señales y hacemos doble click sobre pressed en BaseButton

godot38

Si hicimos doble click en pressed() o lo elegimos y luego clickeamos en Conectar nos aparecera el siguiente dialogo

godot39
Anuncios

Este deberian dejarlo como esta y hacer click en Conectar, antes de continuar observen como en Method In Node ya genero automaticamente el nombre de la funcion conectada entre el boton (Button en este caso) y Panel. Si todo sale bien deberia aparecerles algo asi

godot40.png

Se ve como aparecio una nueva funcion (func _on_button_pressed():) y en la siguiente imagen se ve como queda en la solapa Nodos, la señal conectada para este nodo

godot41

Hasta aqui hemos visto como manipular señales de forma grafica, ahora pasemos a hacerlo de forma “manual”. Primero vamos al script, esto lo pueden hacer a su izquierda donde tienen los archivos (SistDeArchivos) y buscan el archivo con extension GD (.gd) y le dan doble click, esto lo pondra en pantalla, salvo la primera linea (extends panel) deben borrar todo lo demas escrito

godot42

Ahora procederemos a ingresar nuestro primer codigo fuente, y como hacemos siempre en el blog primero ponemos el codigo y luego lo explicamos, veamos el ejemplo:

extends Panel

func _on_Button_pressed():
	get_node("Label").text = "Me presionaron!!!"

func _ready():
	get_node("Button").connect("pressed", self, "_on_Button_pressed")

Un codigo simple, la primera linea le informa al programa que el script es una extension de Panel, luego definimos nuestra funcion para la señal de apretado el boton, esta es _on_Button_pressed(), la estructura para crearlas es

_on_{el nombre del nodo}_{el nombre de la señal}:

con los dos puntos (:) empiezan a la funcion y todo el contenido por debajo con un tabulador le informa al programa ser parte de la misma funcion, en este caso es una sola linea, nuestro siguiente sera hablar sobre el metodo mas utilizado por todos los programadores de godot, este es:

get_node() 

Este metodo sirve para ubicar el path del nodo informado entre los parentesis, en la primera funcion le pedimos buscar al nodo Label para luego usar la propiedad Text y asignarle un nuevo valor, si conocen algo de Javascript este comando trabaja como getElementById() donde busca el elemento en base al id puesto en la pagina, aca es exactamente lo mismo, ahora pasemos a la funcion _ready(), esta es una funcion basica donde el programa al estar listo ejecutara automaticamente la funcion o las funciones asignadas, en este analicemos la linea:

Anuncios
get_node("Button").connect("pressed", self, "_on_Button_pressed")

Primero le pedimos la busqueda del nodo Button, y este la asignara el metodo .connect() donde nosotros diremos, la señal a asociar (pressed), la forma como se va a mostrar (self equivale a en si mismo) y por ultimo la funcion a la cual se va a conectar la señal), les muestro una pantalla para ver como queda un script

godot43.png

Los colores son para ver resaltados los distintos tipos de datos, ya sean funciones, señales, variables, etc. observen los tabuladores debajo de cada func les recomiendo no copiar y pegar el texto aca puesto sino escribanlo porque es probable que no funcione por no tener los tabuladores, esto me paso al principio, o no se diferencien bien las funciones esto es por si ejecutan el programa y falla o no hace lo visto en el tutorial, entonces en este caso es bien simple primero declaramos la funcion donde vamos a ejecutar en base la señal del nodo Button, en este caso pressed, y luego vamos a tener la funcion _ready() para conectar el nodo Button a la funcion previamente creada y ejecutarla. La salida del programa seria asi:

godot44
godot45.png
Anuncios

Si todo salio bien y pudieron llegar a estas pantallas, Felicitaciones hicieron su primer script para una Escena!!!

Ahora procederemos a ver otras posibilidades disponibles desde la programacion en Script y esto nos servira como trampolin para intentar nuestro primer juego.

Pasemos al siguiente nivel, muchas acciones en godot son disparadas por devolucion de llamadas o funciones virtuales por esto no es necesario un codigo corriendo todo el tiempo pero si es necesario un script en cada de uno de los frames, para esto se utilizan dos tipos de procesamiento:

  • procesos inactivos
  • procesos fisicos.

Los procesos inactivos puedes ser utilizados mediante la funcion Node._process() y esta puede ser activada o desactivada con Node.set_process(), y esta es disparada cuando un frame es dibujado, es decir esto va a estar relacionado a los Frames Per Second (FPS), la forma de declararlo es

func _process(delta):
# Funciones para hacer
pass

El parametro delta es un valor flotante donde se acumula el tiempo transcurrido en segundos desde la llamada anterior de la funcion _process(), el parametro delta es utilizado para mantener una misma cantidad de tiempo entre todos los elementos, por ejemplo se multiplica el movimiento por delta para mantener una velocidad de movimiento constante e independiente del frame rate.

El proceso fisico es controlado por _physics_process() es similar pero se deben usar antes de la ejecucion de cada paso fisico, como por ejemplo controlar un personaje, siempre es llamado en cada paso fisico y se ejecuta cada un cierto intervalo de tiempo, son 60 segundos por defecto, esto se puede modificar por medio de Ajustes del proyecto -> Physics -> Common -> Physics FPS.

Anuncios

La funcion _process() no esta sincronizada con lo fisico, el frame rate al no ser constante, va a depender del hardware y la optimizacion del juego y su ejecucion es posterior a los pasos fisicos, pasemos a los grupos, los nodos pueden ser agregados a grupos y es ideal para organizar grandes escenas, poseemos dos formas de hacerlo: uno a traves de modo grafico por medio de la solapa Inspector, elegimos Nodo, seleccionamos Grupos, escribimos el nombre y luego Añadir

godot46

Y el otro metodo es via script de la siguiente manera:

func _ready():
	add_to_group("Enemigos")

Sigamos con este ejemplo, tenemos un personaje el cual se infiltra a la base enemiga y es descubierto lo cual activa la alarma y esto puede ser llamado por SceneTree.call_group()

func _on_discovered():
 	get_tree().call_group("enemies","player_was_discovered")

El codigo superior llama a una funcion player_was_discovered() en cada uno de los miembros del grupo Enemigos, otra posibilidad de conseguir la lista de los nodos enemigos es a traves de SceneTree.get_nodes_in_group().

var enemies = get_tree().get_nodes_in_group("enemies")

SceneTree esta mostrado de forma incompleta, a medida se vayamos viendo  nuevos temas se ira completando un poco mas.

Anuncios

Pasemos  a las notificaciones, estas no son esenciales para la programacion de los scripts pero es importante de conocer su existencia porque si nos pueden ayudar para cuando haya algun error en el script y deseemos ver el estado de una funcion o llamada, la sintaxis podria ser asi:

func notificaciones(what):
 	match what:
 		NOTIFICATION_READY:
 			printf("Esto es lo mismo que anular _ready()...")
 		NOTIFICATION_ERROR:
 			printf("Esto es lo mismo que anular _process()...")

Nosotros tenemos notificaciones para cada una de las clases pero en GDscript tenemos funciones anulables mas simples por esto vamos a hacer un listado de las mismas:

  • func _enter_tree(): Se activa cuando el nodo entra en SceneTree
  • func _ready(): Se activa cuando todos los nodos (incluido hijos) entran en el SceneTree
  • func _exit_tree(): Se activa cuando el nodo sale del SceneTree.
  • func _process(delta): Es llamada en cada frame
  • func _physics_process(delta): Es llamada en cada frame fisico

Ahora pasemos a ver la creacion de nodos via GDscript, el metodo utitlizado es .new() vamos a verlo en un ejemplo

var s
func _ready():
 	s = Sprite.new()
 	add_child(s)

Primero creamos una variable, en este caso s, despues dentro de la funcion _ready(), vamos a crear un nuevo Sprite y en la siguiente linea lo agrega como hijo del nodo actual, una vez finalizado de usar debemos liberarlo (o eliminarlo), para esto usamos el .free()

func algunaaccion():
 	s.free()

Cuando se libera un nodo tambien se liberan a sus hijos, pero puede ocurrirnos el inconveniente de encontrarnos con el nodo bloqueado por estar emitiendo una señal o siendo utilizado por una funcion, esto nos podria detener el juego y derivar en un error para evitar esto se utiliza el metodo .queue_free()

func algunaaccion():
 	s.queue_free()

Ahora pasemos a ver instancias por medio de GDscript, la creacion de una instancia por codigo se utiliza a traves de dos pasos:

  • El primer paso es cargar la escena del disco rigido.
  • Debe ser llamado a traves del metodo Instance()

Veamos el primer paso:

var scene = load("res://escenaA.tscn")

En este caso se cargara cuando el script ya este cargado y verificado en la escena, para evitar esto podemos usar esta opcion:

var scene = preload("res://escenaA.tscn")

La diferencia con el caso anterior es el metodo de carga, en este caso se hara mientras se analiza el script, esto nos permitira una carga mas rapida de la escena. el segundo paso es el llamado de la escena cargada:

var node = scene.instance()
add_child(node)

Al momento de cargar la escena, esta todavia no es un nodo y por ende no puede ser implementada, como vemos en el codigo anterior lo primero es crear una variable a la cual vamos a utilizar la variable donde cargamos la escena junto con el metodo .instance() el cual efectuara la creacion de la instancia, en la siguiente linea se lo asignara como hijo en el nodo actual, tal como habiamos visto antes.

Anuncios

Hemos llegado al final, resumiendo hemos nombrado los distintos tipos de lenguajes utilizados en los scripts de godot, tambien como implementarlo en modo grafico, crearlo y asignarlo a una escena o nodo, como son las señales y la posibilidad de asignarlos de forma grafica o de forma manual, hemos visto funciones basicas y como crear tanto escenas como nodos, poco a poco iremos poniendonos un poco mas complejos para el proximo post vamos a realizar nuestro primer proyecto, es decir nuestro primer juego, espero les haya sido util sigueme en Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Tambien podes donar

Es para mantenimiento del sitio, gracias!

$1.00