Flame: Comenzando: Ajustes iniciales

Viewport

Antes de comenzar a codificar, debemos aprender algunos conceptos relacionados con la representación del juego en Flame.

Supongamos que tenemos un dispositivo cuyo tamaño de pantalla abarca toda el área roja de la siguiente imagen:

Canvas: El área roja es el lienzo (canvas) y es el espacio disponible en el que podemos dibujar formas, imágenes, etc. La mayoría de las veces, el tamaño del canvas será igual al tamaño de la pantalla del dispositivo. Podemos utilizar el tamaño del canvas para conocer el tamaño del dispositivo en píxeles.

Viewport: El área negra es el viewport. Dado que tenemos que lidiar con diferentes pantallas, a menudo es necesario decidir cómo se manejarán diferentes tamaños de pantalla y resoluciones. El viewport intenta unificar múltiples tamaños de pantalla en una configuración única para tu juego mediante la traducción y redimensionamiento del lienzo.

En estos tutoriales, para facilitar la comprensión de todos los ejemplos, utilizaremos el FixedResolutionViewport. Este viewport permite trabajar con un tamaño de pantalla virtual. Esto significa que podemos asumir que la pantalla siempre tiene el mismo tamaño: virtualWidth x virtualHeight.

Para mantener siempre la misma resolución, se agregarán barras rojas, como se muestra en la siguiente animación:

Para mantener siempre la misma resolución, se agregarán barras rojas

Para mantener siempre la misma resolución, se agregarán barras rojas

En la imagen anterior, observa cómo al redimensionar la ventana se muestra el canvas rojo debajo; es decir, "agrega barras rojas" para mantener la relación de aspecto.

Al trabajar con Forge2D, recuerda que 1 unidad es igual a 1 metro. Esto significa que si tenemos un FixedResolutionViewport con valores de 1280 de ancho x 720 de altura y decidimos agregar un árbol que tenga la mitad de la altura, entonces para Forge2D tendremos un árbol de 360 metros, lo cual no tiene sentido. Para solucionar esto, agregamos un valor de zoom de 100 para que el tamaño del mundo se convierta en 12.8 de ancho x 7.2 de altura. Ahora, agregar un árbol de 3.6 metros tiene más sentido.

Hora de escribir código

En estos tutoriales, asumimos que ya tienes conocimientos sobre cómo crear proyectos de Flutter en tu IDE favorito, por lo que no repasaremos los pasos de configuración y creación de un proyecto de Flutter.

El primer paso consiste en crear un nuevo proyecto de Flutter y agregar Flame. Solo debes agregar los paquetes necesarios al archivo pubspec.yaml:

flame: ^1.8.0
flame_forge2d: ^0.14.0

Luego, crearemos una clase MyGame.

// Tamaño fijo del viewport
final screenSize = Vector2(1280, 720);

// Tamaño del viewport con zoom de 100
final worldSize = Vector2(12.8, 7.2);

class MyGame extends Forge2DGame {
  
  // Muestra el número de cuerpos en el mundo.
  final totalBodies = TextComponent(position: Vector2(5, 690))
    ..positionType = PositionType.viewport;

  // Muestra los cuadros por segundo (FPS)
  final fps = FpsTextComponent(position: Vector2(5, 665));

  // Escala el tamaño de la pantalla establece la gravedad en 15
  MyGame() : super(zoom: 100, gravity: Vector2(0, 15));

  @override
  Future<void> onLoad() async {
    
    // Establece el FixedResolutionViewport
    camera.viewport = FixedResolutionViewport(screenSize);

    // Agrega un fondo negro al viewport
    add(_Background(size: screenSize)..positionType = PositionType.viewport);

    add(fps);
    add(totalBodies);
  }

  @override
  void update(double dt) {
    super.update(dt);
    
    // Actualiza el número de cuerpos en el mundo
    totalBodies.text = 'Cuerpos: ${world.bodies.length}';
  }

  @override
  Color backgroundColor() {
    
    // Pinta el fondo del canvas en color rojo
    return Colors.red;
  }
}

// Componente auxiliar que pinta un fondo negro
class _Background extends PositionComponent {
  _Background({required Size size}) : super(size: size);

  @override
  void render(Canvas canvas) {
    canvas.drawRect(Rect.fromLTWH(0, 0, size.width, size.height), blackPaint);
  }
}

Los componentes totalBodies y fps pertenecen a la clase TextComponent y se utilizan para mostrar en pantalla el número de cuerpos en el mundo y los cuadros por segundo, respectivamente. Puedes ver un ejemplo de cómo se muestran en la siguiente imagen:

Cuadros por segundo y número de cuerpos en el mundo

Cuadros por segundo y número de cuerpos en el mundo

En el siguiente artículo, aprenderemos que son los cuerpos (body). Por ahora, podemos decir que los cuerpos son todos los componentes que forman parte de Forge2D y participan en simulaciones, colisiones, y demás. Normalmente, estos cuerpos son del tipo PositionType.game.

Por otro lado, existen componentes que no forman parte de Forge2D, como los componentes de la interfaz de usuario, el fondo, etc. Estos suelen ser del tipo PositionType.viewport.

Conclusión

En este artículo, hemos aprendido sobre dos conceptos clave en la representación de juegos en Flame: el lienzo (canvas) y el viewport.

Se ha introducido el FixedResolutionViewport, que nos permite trabajar con un tamaño de pantalla virtual y mantener una resolución constante en diferentes dispositivos.

En cuanto al código, hemos creado una clase llamada MyGame que extiende Forge2DGame. Esta clase la utilizaremos en cada uno de los ejemplos que creemos a lo largo de este curso.

Por último, recuerda que puedes encontrar el código fuente de todos los tutoriales en Github, y también puedes probar todos los ejemplos en tu navegador.

Videotutorial en YouTube

Comparte este artículo