Game loop: Bucle de juego en Flame con Flutter

- Andrés Cruz

In english
Game loop: Bucle de juego en Flame con Flutter

El módulo de Flame llamado GameLoop o bucle de juego no es más que una simple abstracción del concepto de bucle de juego. Básicamente, la mayoría de los juegos se basan en dos métodos:

  • El método de renderizado toma el canvas/lienzo para dibujar el estado actual del juego.
  • El método de actualización, que recibe el tiempo (delta) desde la última actualización y permite pasar al siguiente estado, es decir, actualizar el estado del juego.

El Game Loop se puede considerar como el proceso más importantes en el desarrollo de videojuegos; ya que, a partir del mismo es que nosotros podemos implementar nuestra aplicación.

El GameLoop tal cual puedes suponer por su nombre, es un bucle infinito que se encarga de actualizar el estado del juego; esto va desde agregar elementos en pantalla, mover al player o a los enemigos y en pocas palabras, cualquier cambio en pantalla, se realiza desde el GameLoop; en Flame, es basicamente la función de update() la que se ejecuta de manera infinita, y es aquí, en donde se colocan verifiaciones de diversos tipos como a escuchadores, etc. Este bucle es el encargado de que el juego se ejecute de la forma adecuada; usando primitivas podemos controlar la velocidad de ejecución del juego para que se ejecute de manera correcta, y en el caso de Flame, para que se ejecute a la misma velocidad en todos los dispositivos; en otras palabras, cuantas actualizaciones por segundo van a ocurrir; esto es importante ya que, el número de veces por segundo que se ejecute esta función, depende de la velocidad de procesamiento, y al tener la aplicación ejecutandose en diversos entornos, es importante realizar este tipo de configuraciones.

En general, el Game Loop se encarga de procesar todo lo que sucede en el juego y actualizar la interfaz gráfica del usuario en consecuencia.

En Flame tenemos un método para inicializar el juego y otro para realizar actualizaciones; Flame sigue estos principios y tenemos un par de funciones que permiten realizar dichas operaciones.

Función render

La función render() recibe un parámetro tipo objeto que hace referencia al lienzo o canvas:

@override
void render(Canvas canvas) {
  canvas.drawRect(squarePos, squarePaint);
}

Que es al igual que ocurre con otras tecnologías como HTML5, no es más que un lienzo en blanco que dibujar sobre el mismo; aquí, podemos dibujar cualquier cosa, por ejemplo, un círculo:

@override
void render(Canvas canvas) {
  canvas.drawCircle(const Offset(10, 10), 10, BasicPalette.red.paint());
}

Función update

Los elementos que estén en el juego, necesitan ser redibujados constantemente según el estado actual del juego; para entender esto más claramente, veamos un ejemplo:

Supongamos que un elemento del juego representado por un sprite (una imagen), que en este ejemplo llamaremos cómo "player"; cuando el usuario da un click sobre un botón, entonces el player debe de actualizar su posición; esta actualización, se aplica en el juego mediante una función llamada update().

Al igual que vimos en el ejemplo del círculo en movimiento, es esta función la que se encarga de actualizar la posición del círculo en pantalla.

La función de update() es tal cual indica su nombre, una función de actualización, la cual, recibe un parámetro, llamado "deltatime" (dt) que nos dice la hora que ha transcurrido desde que se dibujó el cuadro anterior. Esta variable debe usarla para hacer que su componente se mueva a la misma velocidad en todos los dispositivos.

Los dispositivos funcionan a diferentes velocidades, dependiendo de la potencia de procesamiento (es decir, según el procesador que tenga el dispositivo, específicamente, la frecuencia en la cual trabaja el procesador), por lo que si ignoramos el valor delta y simplemente ejecutamos todo a la velocidad máxima que puede ejecutar el procesador, es decir, el juego podría tener problemas en la velocidad para controlar su carácter correctamente ya que sería demasiado rápido o lento. Usando el parámetro deltaTime en nuestro cálculo de movimiento, podemos garantizar que nuestros sprites se moverán a la velocidad que nosotros deseemos en dispositivos con diferentes velocidades de procesador.

Al actualizar cualquier aspecto del juego mediante la función de update() es reflejado automáticamente mediante la función de render() y con esto, la actualización del juego a nivel gráfico.

El Game loop es utilizado por todas las implementaciones de las clases tipo Game y sus componentes:

https://docs.flame-engine.org/1.6.0/flame/game.html

Este articulo forma parte de mi curso y libro completo sobre el desarrollo de juegos con Flame.

Andrés Cruz

Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz en Udemy

Acepto recibir anuncios de interes sobre este Blog.