Flame: El mundo, cuerpos, figuras y accesorios

El mundo (world)

En Forge2D, el mundo es como un contenedor donde suceden las simulaciones de objetos físicos. En él, podemos agregar diferentes objetos y ver cómo interactúan entre sí. Por ejemplo, imagina que estás jugando un videojuego donde puedes lanzar una pelota y ver cómo rebota en las paredes o choca con otros objetos. El mundo se encarga de calcular cómo se moverá la pelota, cómo se comportará al colisionar con otros objetos y cómo interactuará con la gravedad.

Tal vez no te diste cuenta, pero en el artículo anterior ya creamos un mundo.

En Flame, para crear un mundo, debemos extender la clase Forge2DGame e internamente se creará el mundo.

class MyGame extends Forge2DGame {

}

También debemos definir la gravedad de nuestro mundo:

MyGame() : super(gravity: Vector2(0, 15)); 

La gravedad simula la fuerza de atracción que experimentan los objetos en la vida real. La gravedad es un vector que tiene una dirección y una magnitud, y afecta a los cuerpos dentro del mundo de Forge2D.

Podemos ajustar la gravedad de acuerdo con los requisitos específicos de la simulación. Se pueden tener valores de gravedad cero para crear un entorno sin gravedad, o se pueden establecer en diferentes direcciones y magnitudes para simular situaciones especiales.

En el fragmento de código anterior, definimos una gravedad con el vector Vector2(0, 15), en otras palabras, no hay gravedad horizontal y los objetos son atraídos hacia abajo. Recuerda que en Forge2D, una unidad es igual a un metro.

Si deseas un mundo sin gravedad, entonces el código se verá así:

MyGame() : super(gravity: Vector2(0, 0)); 

Cuerpos (bodies)

En Forge2D, los objetos se llaman cuerpos y son las piezas fundamentales en el mundo. Los podemos imaginar como objetos físicos reales, como una pelota, una caja o cualquier otra cosa que puedas tocar y mover.

Cada cuerpo tiene diferentes características, como su forma, tamaño, posición, velocidad y masa. Podemos decirle a un cuerpo cómo debe moverse, cómo debe reaccionar ante las fuerzas y cómo debe interactuar con otros cuerpos.

Por ejemplo, si tenemos un cuerpo que representa una pelota y le aplicamos una fuerza, el cuerpo se moverá según las leyes de la física. Si hay otros cuerpos cerca, podrían colisionar y rebotar entre sí, tal como lo harían objetos reales.

Además, los cuerpos en Box2D pueden tener diferentes tipos, como cuerpos estáticos que no se mueven, cuerpos dinámicos que responden a las fuerzas aplicadas y cuerpos cinemáticos que se mueven según una trayectoria específica.

En Flame, para crear un cuerpo, necesitamos crear una clase que extienda de BodyComponent.

class Ball extends BodyComponent {  
  @override  
  Body createBody() {  
     
  }  
}

Dentro de la función createBody(), creamos un BodyDef que contendrá los datos necesarios para crear el cuerpo:

final bodyDef = BodyDef(  
  position: Vector2(worldSize.x / 2, 0),  
  type: BodyType.dynamic,  
);

Podemos ver que este será un cuerpo dinámico, posicionado verticalmente en la parte superior de la pantalla y centrado horizontalmente.

Formas (shapes)

En Forge2D, las formas determinan la apariencia y las propiedades físicas de los cuerpos en la simulación. Pueden ser círculos, rectángulos o polígonos, y tienen atributos como la densidad, la fricción y la restitución que influyen en cómo interactúan con otros cuerpos.

Si queremos crear una forma circular con radio de 0.35 el código es el siguiente:

final shape = CircleShape()..radius = .35;

Accesorios (fixtures)

Los accesorios son componentes asociados a los cuerpos que les dan forma, propiedades físicas y características de colisión. Podemos pensar en ellos como una especie de "accesorio" que se adjunta a un cuerpo para definir su comportamiento físico.

Un accesorio tiene una forma, densidad, fricción y restitución asociadas.

  • La densidad determina la masa del cuerpo y cómo interactúa con otros cuerpos durante las colisiones. Un cuerpo con mayor densidad será más difícil de mover o empujar.
  • La fricción determina la resistencia al deslizamiento de un cuerpo cuando entra en contacto con otros objetos.
  • La restitución se refiere a la elasticidad de un cuerpo y determina cómo rebota después de una colisión.

Veamos cómo podemos crear un accesorio de forma circular:

final shape = CircleShape()..radius = .35;
final fixtureDef = FixtureDef(shape);

Ahora vamos a crear un cuerpo al cual le vamos a adjuntar el accesorio que hemos creado. El código se verá así:

final body = world.createBody(bodyDef)..createFixture(fixtureDef);

Juntando todo el código, la clase Ball se verá así:

class Ball extends BodyComponent {
  @override
  Body createBody() {
    final bodyDef = BodyDef(
      position: Vector2(worldSize.x / 2, 0),
      type: BodyType.dynamic,
    );

    final shape = CircleShape()..radius = .35;
    final fixtureDef = FixtureDef(shape);
    return world.createBody(bodyDef)..createFixture(fixtureDef);
  }
}

Agregar la pelota al juego

Finalmente, debemos agregar la Ball al juego. Para ello, crearemos una nueva clase llamada GameLesson01 que extienda de MyGame.

class GameLesson01 extends MyGame {

  @override
  Future<void> onLoad() async {
    super.onLoad();
    add(Ball());
  }
}

En esta nueva clase, sobreescribimos el método onLoad() para agregar una nueva instancia de Ball al juego utilizando la función add().

Ahora, al ejecutar el código, podremos ver la pelota en acción, cayendo desde la parte superior hasta la parte inferior de la pantalla.

Puedes experimentar cambiando los valores de gravedad, el radio de la pelota, entre otros. ¿Cuáles son los resultados?

Conclusión

Este artículo nos enseñó sobre el mundo de Forge2D y cómo agregar cuerpos a él. También aprendimos que un cuerpo puede tener diferentes formas y atributos.

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