domingo, 25 de julio de 2021

libGDX: Box2D El mundo, cuerpos, figuras y fixturas

El mundo (World)

Cada aplicación con Box2D comienza con la creación de un objeto del tipo World. La clase World se encarga de manejar la memoria, objetos y la simulación.

1- La creación del mundo es muy sencilla. Primero, necesitamos un vector que define la gravedad.

Vector2 gravity = new Vector2( 0, -9.8f ); // Gravedad de la tierra 9.8m/s²

La gravedad afecta a cada cuerpo dinámico que se encuentra en nuestro mundo en este caso x=0 lo que significa que no hay gravedad horizontal y y=-9.8f que es casi la misma gravedad que la Tierra.

Si quisiéramos un mundo sin gravedad nuestro código se vería así

Vector2 gravity = new Vector2( 0, 0);

2- Otro parámetros que necesita nuestro mundo es, si permitimos que nuestros cuerpos puedan dormir. Esto significa que cuando un cuerpo entra en reposo el mundo deja de hacer simulaciones en él. Esto incrementa el rendimiento de nuestra aplicación.

boolean sleep = true;

3- Finalmente podemos crear nuestro mundo con el siguiente código.

World oWorld = new World( gravedad, sleep);

4- Corriendo las simulaciones: Box2D utiliza un algoritmo computacional llamado ‘integrator’ que simula la física del mundo en pasos discretos de tiempo. Para simular tenemos que escoger un paso de tiempo ‘time step’. Normalmente los juegos corren a 60fps y tienen un ‘time step’ de 1/60 segundos.
Para nuestros ejemplos utilizaremos el tiempo transcurrido desde el frame pasado y el actual: delta.

Pero no solo necesitamos un time step. En cada paso de la simulación los cuerpos son actualizados dependiendo de las fuerzas que actúan en él. El algoritmo encargado de esto se llama ‘constraint solver’.

Existen 2 fases en la simulación, la fase de velocidad y la fase de posición. En la fase de velocidad los cuerpos se mueven de acuerdo a sus impulsos y en la fase de posición se ajustan las posiciones para prevenir que se traslapen los cuerpos.

Por lo que entre más iteraciones más precisa será nuestra simulación pero menor rendimiento. Para nuestro tutorial utilizaremos 8 iteraciones de velocidad y 6 iteraciones de posición. por lo que nuestro código se verá así:

oWorld.step(delta, 8, 6);

Cuerpos (Bodies)

Los cuerpos son parte fundamental de Box2D, cualquier cosa que se mueva y puedas interactuar en el mundo son cuerpos.

Existen diferentes tipos de cuerpos: dinámicos, cinemáticos y estáticos.

Los cuerpos tienen distintas formas (figuras) : Circulares, cuadrados o cualquier tipo de polígono.

También tienen diferentes propiedades como son: densidad, fricción , restitución, velocidad, posición en el mundo, etc.

1- Para crear un cuerpo en nuestro mundo el primer paso es crear un BodyDef que es la definición del cuerpo y sirve para mantener toda la información necesaria para crear nuestro cuerpo.

BodyDef bd = new BodyDef();
bd.position.set( 4 , 2 );
bd.type = BodyType.DynamicBody;

Creamos la definición del cuerpo y la posicionamos en el centro de la pantalla. Recordemos que el tamaño de nuestra cámara es de 8f x 4.8f. Y por último decimos que nuestro cuerpo será dinámico.

Nuestro cuerpo tendrá una figura circular por lo que tenemos que crear una figura circular (Shape)

Figuras (Shapes)

Una figura es un objeto geométrico, como un círculo, cuadrado o un polígono, en caso de que sea un polígono debe ser un polígono convexo ya que Box2D solo funciona con polígonos convexos.

Para crear nuestra figura circular utilizamos el siguiente código:

CircleShape shape = new CircleShape();
shape.setRadius(.1f);

Simplemente creamos un objeto circular y le damos radio de .1f, ahora es momento de crear una ‘fixtura’ para nuestro cuerpo.

‘Fixturas’ (Fixture)

Las ‘fixturas’ sirven para dar tamaño, forma y otras propiedades como densidad, fricción y restitución.

Las principales propiedades son:

  • Densidad - Que tan pesado es un cuerpo en relación con su área
  • Fricción - Que tan resbaloso es el cuerpo
  • Restitución - Que tanto rebote tiene el cuerpo
  • Figura (Shape) - Puede ser un cuadrado, polígono o un círculo.

Existen más propiedades que iremos explicando más adelante en estos tutoriales. Por el momento no nos vamos a preocupar de las propiedades y vamos a crear una ‘fixtura’.

FixtureDef fixDef = new FixtureDef();
fixDef.shape = shape;

Creamos la definición de la “fixtura” y le asignamos el cuerpo circular que creamos anteriormente.

Agregar el cuerpo al mundo

Para agregar nuestro círculo al mundo se ha creado una función llamada createBall() y contiene todo lo que aprendimos anteriormente. A este código se han agregado dos líneas más que son:

Body oBody = oWorld.createBody(bd);
oBody.createFixture(fixDef);

En la primera línea creamos el cuerpo con la definición del cuerpo que creamos anteriormente, y le agregamos a nuestro cuerpo la ‘fixtura’.

Poniendo todo junto

Puedes descargar el código con el ejemplo completo en Github o puedes ver el siguiente video donde construimos paso a paso este ejemplo. También puedes correr la aplicación en tu navegador.


Ahora corremos la aplicación y podremos ver la siguiente pantalla:

Una pelota en medio de la pantalla que cae y desaparece de nuestra vista. Pueden hacer pruebas cambiando el radio de la pelota, cambiando los valores de la gravedad, etc.

Conclusión

En este tutorial vimos como crear el mundo y cómo hacer que nuestro mundo corra las simulaciones. También aprendimos que son los cuerpos, que tipos de formas pueden tener y como agregarlos al mundo.

    

0 comments:

Publicar un comentario

Entradas populares