sábado, 30 de mayo de 2020

Bases para un juego 2D

Nuevo proyecto


Interfaz

En al interfaz tenemos las siguientes ventanas:
Viewport. Donde podemos visualizar la escena, y con el signo + podemos agregar otra escena.
Escenas. Dentro de la ventana "Escena" podemos agregar los nodos. Como si fuera un árbol genealógico nos indica el parentesco que hay entre ellos
Inspector. Los nodos tienen propiedades editables, las cuales se puede editar en inspector.
Importar. Si queremos importar un archivo desde importar podemos configurar algunos parámetros de importación
Nodos. Permite crear señales para cada nodo



Sistema de archivos

En la ventana de "sistema de archivos" tenemos la carpeta que hemos creado para guardar nuestro juego. Si vamos a "res://" y con el botón derecho del mouse abrimos el explorador de archivos veremos la carpeta con todos los archivos que podemos visualizar y otros ocultos

Menu principal

Escenas. En Godot los documentos que engloban todos los objetos y constituyen un nivel se conocen como escenas
Ajustes del proyecto. Dentro de la ventana proyecto tenemos esta opción que nos permite configurar la calidad gráfica de nuestro juego, la resolución y modo de reproducción. El conjunto de controles para manejar el juego llamados "mapa de entradas"
Exportar. Ésta opción nos permite publicar el juego en un formato legible para diversas plataforma
Configuración del editor tenemos la opción de editar al interfaz, la fuente de texto, color, idioma, etc.

 Escena 2d

Control del objeto. Arrastrando nuestro objeto 2d al escenario tenemos principalmente 4 opciones para manipular el objeto. Mover, escalar y rotar, pero si usamos el modo de selección podemos trabajar con las 3 opciones, podemos mover el objeto simplemente con el ratón, con Crl preciando y el mouse podemos rotar y moviendo desde los puntos podemos escalar.
Candado. El candado es muy útil para no seleccionar un objeto accidentalmente
Grilla. La grilla la podemos activar desde la opción ver
Iman inteligente. Éste lo que hace es pegar un objeto al lado de otro
Grilla iman. imanta a la rejilla


Nodo Label

Con el signo más podemos crear un nodo nuevo que será el hijo del anterior. Las propiedades más detectadas en el inspector del Nodo2D son la transformación para mover y rotar la imagen y visibilidad en donde podemos ocultar el escenario si es necesario

En el nodo Label tenemos opciones orientadas a texto como text para escribir el texto que deseemos, la propiedades de alineación horizontal y vertical, la propiedad rect donde podemos ajustar la posición y las dimensiones del nodo de texto y la propiedad te them donde podemos modificar la fuente, el color o el tamaño de la fuente


Para usar una fuente podemos copiar unas de la carpeta fonts de window y crear una carpeta en nuestro sistema de archivos y pegarla

Si vamos a Theme podemos crear un Nuevo Theme

Luego nos abren más opciones y podemos  crear un nuevo font. Si seleccionamos "Nuevo Dinami Font" nos permitirá editar un conjunto de propiedades como el tamaño de fuente, color y forma. Esas opciones se abre cliqueando DynamicFont. Luego en fon creamos un nuevo dinamicfontdata y en el icono de carpeta vamos al sistema de archivos y abrimos la fuente que hemos copiado

Ajustamos el tamaño y lo guardamos en la carpeta Theme


Nodo Botón

Al tener el nodo botón la ventana inspector nos muestra todas las propiedades ligadas a este objeto. Las más usadas son aline, rect y theme. Desde Theme podemos cargar el tema que hemos guardado en nuestra carpeta

Visual script

Podemos agregar un script presionando el icono del pergamino. Seleccionamos visualScript y en ruta abrimos para crear una carpeta de script y guardamos este creado


La primera ventana nos muestra todos los script creados, y la ventana inferior nos permite ver funciones y variables creadas en el script que estamos editando.
Funciones. Para comenzar un script es necesario usar una subrutina denominada funciones. Éste nos permite indicar el momento en que queremos que se ejecute un conjunto de acciones, así podemos restringir nuestras acciones al inicio de un nivel en el momento de pulsar un botón o al producir una colisión entre dos objetos. Por ejemplo si queremos que al iniciar, el texto no sea visible agregamos un nodo de función Ready

Los nodos representan funciones, palabras claves, operaciones,variables, etc. La etiqueta en la parte superior, especifica su nombre, y una o varias flechas y puntos, las cuáles se les denominan puertos.
Las flechas. Son puertos de secuencia y permitan añadir nuevas funciones
Los puntos.  Son puertos de datos y permiten introducir o extraer información

Si queremos programar que el texto de un nodo label solo aparezca tras presionar un botón primeramente arrastramos la propiedad visibilidad de la ventana inspector que aparece tras seleccionar el nodo Label

Entonces conectamos ambos nodos desde los puertos de secuencias que son las flechas. Podemos ver que por defecto el nodo set visible tiene la opción True que es equivalente a tener la visibilidad activada. Pero no queremos eso, por ello vamos a desactivar el true para que queda en False


Para poder visualizar el texto de label tras presionar un botón vamos al nodo button y agregamos un script de la misma forma que el anterior y lo guardamos en al misma carpeta. Ahora necesitamos una función que ejecute el código solo con pulsar el botón. Éste tipo de funciones que son exclusivas de un nodo determinado se les denomina señales. Los pasos son:
1. Seleccionar el nodo button
2. Ir a la ventana de nodos al lado de la ventana inspector y seleccionar la señal que queremos usar que en éste caso será "presset()"
3. Luego presionamos en la opción "conectar" que está al final de la ventana
4. Luego seleccionamos el script del boton

Ahora debemos indicarle a Godot la acción o acciones que queremos ejecutar, que en éste caso será visualizar el texto de label. Entonces hacemos lo mismo que hicimos anteriormente arrastrando la propiedad visibilidad, pero con el True activado y lo conectamos

Luego cuando ejecutemos al escena podemos ver como tras presionar el botón se visualiza el texto

Nodo sprite

Lo primero debemos hacer es crear una nueva carpeta para lso sprites y arrastrar allí la imagen que vamos a usar

Luego si queremos que la imagen se repita en el espacio 2d. Para ello debemos configurar los parámetros del archivo importado y eso lo hacemos en la ventana importar, habilitamos ahí el "Repeat" y presionamos "Reimportar"

Con el simple echo de arrastrar la imagen al visor 2d se crea un nodo sprite

Luego de las propiedades más destacadas en el inspector tenemos la textura que es básicamente al imagen que queremos usar, el parámetro Offset que nos permite mover el punto de pivote de la imagen, el parámetro región que nos permite recortar la imagen y el parámetro transformación que nos permite mover el sprite. Si desactivamos el centro en el parámetros  Offset podremos ver como la imagen se mueve del centro, si luego en transformación cambiamos las coordenadas de movimiento a cero. Luego para que se repita con la opción "enable" activada aumentamos el ancho a 3840 px y la altura a 1080 px

Nodo RigidBody2D

De los parámetros destacados en este nodo tenemos el gravity scale que nos permite aumentar o disminuir la fuerza de gravedad, la propiedad linear velocity que nos permite establecer la velocidad inicial del objeto y el parámetro linear Damp que permite establecer el coeficiente de fricción del objeto

Para conocer cual es el valor de la gravedad según Godot debemos ir a ajustes de proyecto y las opciones de físicas 2d podemos ver el valor absoluto de gravedad que es 98 lo que correspondería a 9,8 m*s^2, gravity vector establece al dirección de la gravedad. Como tiene el valor 0 en X y 1 en Y, eso indica que los objetos se empujan hacia a bajo. Si cambiamos este valor aquí afectará a todos los objetos de forma global.

Modificaciones

1. Si queremos hacer el cambio solo a un objeto, hacemos el cambio en el Gravity scale. Por lo tanto si queremos que la gravedad no afecte al objetos bajaremos el valor de "Gravity scale" a cero.
2. Si queremos que inicialmente nuestro objeto se mueva a la derecha con una velocidad constante de 250 unidades cambiaremos el valor del eje x a 250
3. Si no queremos que nuestro personaje presente coeficiente de fricción debemos cambiar el valor de "Linear Damp" a cero. De otra forma la velocidad disminuiría
4. Luego posicionaremos nuestro cuerpo rígido usando la propiedad de


Animaciones con sprites

Un sprite puede contener una serie de imágenes que reproducida a una velocidad determinada permite generar una animación. Para ello necesitamos una secuencia de imágenes o un sprite sheet que es un archivo de imagen que contiene un conjunto de pequeñas imágenes


Agregamos el nodo AnimatedSprite como hijo del nodo RigidBody2D

Luego seguimos los siguientes pasos.
1. Seleccionamos el nodo "AnimatedSprite" que renombraremos como "animación" y en las opciones de inspector creamos un nuevo Sprites frames

2. Luego seleccionamos el Sprite Frames para que se habrá la ventana de animación. Tenemos un cuadro en la parte izquierda que nos permitirá crear animaciones independientes y un cuadro en la parte derecha que nos permite agregar los fotogramas
3. Damos clic en "añadir frame de un sprite sheet"
4. Seleccionamos el archivo desde la carpeta sprite y hacemos clic
5. Tenemos la subdivisión en celdas. Debemos ajustarla de acuerdo a la cantidad de frames que tengamos
6. Seleccionaremos con shift desde la primera celda hasta la ultima y agregamos

7. Luego activamos el playing para tener una animación constante
8. Escalamos con shift el personaje y luego receteamos

Colisión

Un cuerpo rigido necesita un nodo de tipo colisión para funcionar correctamente. Nos ayudará a que el cuerpo rigido no traspase paredes y permitirá la interacción con otros objetos. Tenemos dos tipos de Nodo colision:
1. Collisionshape Permite crear un nodo de tipo collision basado en una forma predeterminada como por ejemplo un circulo, un rectángulo o una linea
2. Collisionpolygon Permite crear un nodo de tipo collision usando un polígono de n vértices

Vamos a usar el nodo Polygon como hijo del nodo Rigidbody
  
Vamos a usar el CollisionPolygon2D  y para ajustarlo tenemos tres opciones: El primero para añadir nuevos vértices, el segundo para editarlos y el tercero para eliminar vértices del polígono

Lo ajustamos

Mapa de entrada en Visual script

Vamos a agregar un script al nodo rigidbody
1. La Función que emplearemos como sistema de activación del script se denomina physicsprocess la cuál se emplea cuando se necesita mover objetos desde el motor de física. Se ejecuta el código en bucle y a una velocidad determinada, pero queremos que se ejecute cuando se pulsen las teclas direccionales de arriba y a bajo.
2. Para ello necesitamos que Godot identifique esas teclas por lo que usaremos el nodo condition (Se agregan nuevos nodos con al tecla derecha del ratón)
3. El puerto de datos de entrada del nodo permitirá incluir una variable boleana por lo que añadiremos el nodo Action que permite detectar si la tecla de un botón se a pulsado
4. Teniendo el nodo Action seleccionado vamos a inspector y seleccionamos la tecla ui_down
5. Ahora debemos indicarle a Godot cuál es la acción que debe ejecutar cuando se pulse la tecla de dirección "a bajo". Queremos que se aplique a una velocidad constante hacia a bajo. Por ello seleccionamos el nodo RigiBody y desde el inspector arrastraremos la propiedad velocity, entonces conectaremos la salida de True del nodo condition On Self
6. Cambiamos el valor de de velocidad. Eje X 250 y eje Y 400
7. Para la tecla de dirección arriba tenemos que hacer algo similar por lo que duplicaremos con Ctrl+D los nodos condition, Action y velocity.
8. Conectamos la salida False del nodo condition a la entrada del nuevo nodo condition
9. Cambiamos la tecla del nuevo nodo actiona ui_up
10. En el nuevo nodo Velocity cambiamos el eje Y  negativo
11. Duplicaremos el nodo velocity y lo conectaremos a la salida False para establecer que si no se presiona la tecla arriba o a bajo tendremos una velocidad de 200 en eje x y 0 en eje Y


Nodo are 2D

Agregaremos un nodo Area2D como hijo del nodo principal. El nodo área es un contenedor que puede albergar un sprite, una zona de colisión o cualquier otro lado que pueda presentar cierto interés para nosotros 


Vamos a usar una imagen svg que en este caso será una estrella y la vamos a guardar en la carpeta sprite. Luego agregamos un nodo sprite como hijo del nodo area 2D, arrastramos la imagen que tenemos desde la carpeta sprite hasta la textura, luego ajustamos su tamaño recateamos en transformación su posición. Luego agregamos un nodo collisionpolygon y lo ajustamos

Sonidos

Vamos a agregar un sonido general de fondo y un sonido de colisión. Tenemos una opción en https://www.youtube.com/audiolibrary/ para descargarmusica y efectos de sonido gratis. Godot solo te permite usar archivos de audio en formato Wave y Ogg por lo que debemos convertirlo a uno de esos formatos si nuetsros audios no lo tienen. Luego creamos una carpeta de sonidos y los arrastramos ahí y creamos un nodo de AudioStreamPlayer. En inspector arrastramos el sonido, controlamos el volumen y activamos autoplay para que se active solo

Luego para agregarle efecto a la estrella agregamos un sonido 2D como hijo de aquella area 2D, arrastramos el audio

Interacción entre objetos 2D

Vamos a agregar un script en la estrella con el fin de ocultarla y reproducir el efecto de sonido pero que solo se ejecute cuando nuestro personaje entre en el área de la estrella, es decir, que atrape esa estrella. El script vamos a agregarlo en el nodo de Área 2D y lo vamos a guardar en nuestra carpeta de script. Luego para hacer la conexión de nodos seguimos los siguientes pasos:

1. Teniendo seleccionado ese nodo debemos ir a la ventana Nodo y seleccionar la señal "Body_entered(Body: Node)" y conectarlo al mismo script

Entonces se crea una nueva función que permite ejecutar las acciones solo cuando un cuerpo rígido entra en el área, en éste caso el personaje. Tenemos dos puertos:
* El puerto de secuencia de salida nos permite unir la función con nuevas acciones
* El puerto de datos de salida denominado body nos devuelve la referencia del objeto que ha entrado en contacto con el nodo de área 2D que ahora hemos llamado Item. Éste nos permite diferenciar la acción entre distintos objetos que puedan haber en el área

2. Para detectar un objeto y determinar si se ejecutan o no ciertas acciones existe un comando denominado Type cast que nos permite identificar el tipo de nodo y el script vinculado a dicho objeto. entonces conectamos el puerto de secuencia de salida del nodo "on_item_body_entered" a la entrada del nodo type cast

3. Para señalar que objeto queremos analizar uniremos los puertos de datos


4. Para especificarle a la función type cast que tipo de nodo o script es el que puede ejecutar las acciones usaremos la propiedad "base cript" que aparece en inspector teniendo seleccionado el nodo type cast. Entonces agregamos el archivo de scrip del personaje principal. Entocnes si el personaje principal entra en el área se activará la secuencia de acciones

5. La primera acción es hacer invisible el sprite que contiene la estrella. Para ello haremos clic sobre el nodo estrella y arrastraremos la propiedad "visbilidad" al editor de script lo conectaremos con el type cast desde el puerto de secuencia de salida a la entrada del nodo de visibilidad y activaremos false (que significa que se apagará la visbilidad)

6. También en esta acción debemos desactivar el polygono de colisión del área si no se hace el personaje principal podría recoger la estrella de forma infinita. Para ello haremos clic en el nodo colision y arrastraremos la propiedad desable desde el inspector. Lo conectamos como secuencia y lo desactivamos con True

7. Para añadir el efecto de sonido seleccionamos el nodo, vamos a inspector y arrastramos la propiedad playing, lo dejamos en True y lo conectamente siguienodo la secuencia


Camara 2d

Para que la cámara siga al personaje solo necesitamos añadir la cámara 2d en el cuerpo rígido. Luego de agregar el nodo la ventana inspector se actualiza con las propiedades de ese nodo. De las propiedades tenemos current que permite establecer la cámara seleccionada como la actual y limit que permite establecer los limites del movimiento de la cámara. Vamos a usar en este caso un valor de limite superior e izquierdo de cero pixeles, un valor de limite derecho de 3840 pixeles y un valor de limite inferior de 1080 pixeles

Interfaz de usuario

La interfaz debe situarse en el mismo lugar de la pantalla independientemente del resto de objetos y de la cámara, para ello necesitamos el nodo canvas layer, el cuál debemos agregarlo como hijo del nodo principal Dentro de este vamos a crear dos nodos, el nodo panel y el nodo label.

* En el nodo label ajustamos el tamaño, escribimos el valor cero dentro de la etiqueta, ajustamos en el centro, también podemos agregar una fuente en theme como lo vimos anteriormente

* En el nodo panel vamos Custom style y agregamos un nuevo estilo "box flat", cambiamos el color del fondo, el ancho y el color del borde y el radio de las esquinas

Ahora necesitamos que el texto cambie cada vez que colisionemos con una estrella sumando 1 al valor inicial por lo que debemos:
1. ir primeramente al script del item, seleccionar el nodo label y arrastrar la propiedad text desde el inspector a visual script el cual conectaremos seguidamente como secuencia al nodo set playing que teníamos
2. Arrastramos nuevamente la propiedad text pero presionando Ctrl para convertir el nodo en una variable de tipo string (simplemente texto) que tiene como objetivo obtener la información de la propiedad text.
3. Como no se pueden hacer operaciones matemáticas con este nodo debemos convertirlo de string a una valor numérico de tipo entero. Para ello debemos utilizar el nodo "string to int". entonces los conectamos. De esta forma tenemos el valor numérico que se muestra en el nodo label
4. Para sumar 1 a dicho valor debemos agregar el operador "Matt add". La operación Matt add por defecto tiene entradas y salidas str. Debemos cambiarlas a int en inspector teniendo seleccionado el nodo y lo conectamos con la salida int del nodo "string to int" y cambiamos el puerto de datos de entrada B al valor 1 para que se añada 1 a la cadena de texto contenida del nodo label
5. Si conectamos el puerto de salida int del nodo matt add al puerto de entrada str del nodo de propiedad text que teníamos creado se añadirá automáticamente una función llamada "Construct string" que permite convertir el valor numérico de la operación matt add a una variable tipo string


Duplicar item

Ahora duplicaremos nuestro item creado para posicionarlo en diferentes zonas de la escena. Lo primero es seleccionar el nodo item y con Ctrl+D lo duplicamos

Luego debemos activar esta opción para poder mover los items que iremos duplicando

Apuntes tomados de el siguiente curso
https://www.youtube.com/watch?v=53naN0LX9YA&list=PL2FA591jQnK-m2DtY4FShePYX6iW1HuTh

martes, 19 de mayo de 2020

Teoría básica de Godot

Vectores y sistema de coordenadas 2d

En el 2d se usan los vectores para ubicar una posición en el plano cartesiano
La primera regla es que la orientación desde el punto hacia arriba es negativa y desde el punto hacia a bajo es positiva


La función process (Delta)

El motor de juego intenta procesarse a 60 fps pero muchas veces los computadores o el mismo software no puede procesarlos de forma consistente. Para ello se utiliza el parámetro delta. si tenemos un objeto configurado para que se mueva 10 pixeles en cada fotograma. Si todo funciona correctamente se ejecutarían 600 pixeles e un segundo (10*60(fps)). Pero si se demora y se ejecutaron 50 fps entonces el objeto se movería 500 pixeles en un segundo. 
¿Como se soluciona?
Con el parámetro Delta el cuál contiene el tiempo transcurrido desde el fotograma anterior. La mayoría de las veces es 0.016 segundos (16 milisegundos). Si tomas la velocidad que deseas (en el ejemplo serían 600 px/s) y la multiplicas por delta entonces obtendrás un movimiento exacto de 10px.
Velocidad deseada expresada en px/s * Delta

Física de los cuerpo rígidos 

Cuando desarrollamos juegos es común saber contra que objeto estamos colisionando y que debemos hacer en pos de esa colisión. esto se conoce como "detección de colisión" y cuando la detecta se le conoce como "respuesta de colisión". Para trabajar con físicas se utilizan los siguientes nodos:

1. StaticBody2D

Un nodo estático no es movido por el motor de físicas ya que como su nombre lo dice, se espera que el nodo sea fijo.  Se suele utilizar para paredes, suelo, plataformas, objetos del entorno, etc. Pero si participa en la detección de colisiones. Podemos programar una plataforma y si detecta al player ella puede saber cuando el player a entrado en colision

2. RigidBody2d

Este cuerpo físico provee física simulada. Aquí es donde el motor puede programar un monton de comportamientos como gravedad, impulso, rebotes, etc.). No se controla directamente si no que se aplica una fuerza

3. KinematicBody2D

Este tipo de cuerpo provee detección de colisiones pero no tiene físicas simuladas. Todos los movimientos deben ser aplicados a código al igual que las respuestas 

Maquina de estado infinito

¿ Que es una Maquina de estado?

Es un mecanismo para controlar los distintos estados que tiene un personaje. la maquina de estado se crea con un tipo de dato llamado Enum que es una colección de constantes evaluados pro el ramificador multidireccional Match.
Acá tenemos 4 estados.
Idle: Cuando está quieto
Run: Movimiento
Jump: Salto
Dead: Game over

Idle a Run: Vamos a programa que sea cuando se detecte la tecla izquierda y derecha.
Run a Idle: Será cuando después de estar en Run el speed es igual a cero
Idle a Jump: La transición se cumple cuando estamos en el suelo y cuando pulsamos la tecla hacia arriba
Jump a Idle: Se cumple cuando estamos en el suelo y el speed es igual a cero
Jump a Run: Si estamos en el suelo y la velocidad es distinta de cero
Run a Jum: La transición se cumple cuando estamos en el suelo y cuando pulsamos la tecla hacia arriba
A Dead: Todos los estados generan una transición a dead





Teniendo la escena de un personaje, vamos a ella y creamos dos nodos. Un sprite y un animation player

Luego al sprite le arrastramos un aset de los cuadros de la aniamción del personaje en formato png a texture

El aset contiene 19 imágenes. Para colocarlas en la misma posición, debemos seleccioanr primero el sprite, luego en inspector abrimos "animation" y cambiamos el valor de Hframe a 19. Con Frame vamos moviéndonos entres todos ellos

En animationPlayer creamos una animación nueva

Luego abrimos el inspector y modificamos algunos parámetros de la animación como el largo del cuadro

Luego hacemos los siguientes pasos. seleccionamos el sprite, vamos al inspector, seleccionamos el frame que corresponda a la animación que queremos hacer que en este caso es el Edle y corresponde al frame 7 hasta el 10. Al 7 que es el primer 4 le agregamos una clave

Seguidamente presionamos el key para agregar los otros cuadros de la animación. Para agrandar la planilla de tiempo usamos el Ctrl y la rueda

Luego hacemos lo mismo con los otros estados. Run que son 6 imágenes por ello en inspector colocamos 0.6 de lenght. Luego Jump que es solo una imagen y Dead que son dos

1. Ahora pasamos al código y lo primero que vamos a hacer es crear una variable tipo Enum definiendo los 4 estados en mayúscula por convención.
2. Luego necesitamos 3 variables
var state Para conocer el estado actual de las 4 constantes.
var current_animation Para mantener la animación actual
var new animation Para que diga si la animación a cambiado

3. La animación ira cambiando pero para ello necesitamos la funcion func transition_to y que esté recibiendo como parámetro el new_state
4. Luego tenemos que asignar el new_state (nuevo estado) a la variable state. Para ello simplemente igualamos new_state = state
5. Luego para evaluar el contenido de state usamos al palabra reservada Match. Match state
6. Al match con dos puntos señalamos los posibles casos que son los 4 estados que tenemos
7. Ahora para determinar por donde ingresará el flujo del código usamos el new animation para cada uno de los estados. Entonces a cada estado señalado seguido de dos puntos, expresaremos el new_animation = "estado"

(todo esto tiene que quedar al final)

8. Ahora vamos a usar la función Ready con "transition_to" y el estado idle para que empiece por defecto ahí. También agregamos el OS.center_window()
9. Luego usamos la funcion func physics_process(delta) y seguido de dos puntos lo que hacemos es evaluar si la animación actual es distinta a la nueva animación (new_animation) y siendo así se asigne a lo nuevo. Usamos la siguiente operación: Si (if) current_animation es distinto (!=) a new_animation (seguido de dos puntos) igualamos current_aniamtion con new_aniamtion, y lo enviamos a reproducir por medio del nodo $Animationplayer.play(current_aniamtion)

10. Ahora debemos programar las transiciones

Evaluemos que tenemos para poder determinar el estado actual. Si queremos programar la transición de:
IDLE a RUN preguntamos: Si (if) state es igual (==) a IDLE y (andvelocity.x es distinta (!=) de cero, quiere decir que estamos corriendo (:transition_to(RUN))

RUN a IDLE preguntamos: Si (if) state es igual (==) a RUN y (andvelocity.x es igual (==) a cero, quiere decir que estamos quietos  (:transition_to(IDLE))

IDLE o RUN a JUMP preguntamos: Si (if) state está en (in[IDLE, RUN] y (and) no está en el suelo (!is_on_floor()), quiere decir que estamos en el aire (:transition_to(JUMP))

JUMP a IDLE preguntamos: Si (if) state es igual (==) a JUMP y (and) está en el suelo (is_on_floor()), quiere decir que estamos quietos (:transition_to(IDLE))



Apuntes tomados del tutorial de Irwin Rodriguez:https://www.youtube.co m/watch?v=jRpao7ztWBg&list=PLlFOKoWJ_eWbujM7hiUVB7ioPom94ShIL&index=21