Lluvia (Box2D + Processing)

He realizado una aplicación en Processing, que será parte de la escena de la lluvia.

La aplicación es una lluvia, es progresiva, empieza con una tormenta débil, de modo que según pase el tiempo se hacen tormentas más fuertes, las particulas colisionan en los elementos fijos.

La aplicación es la primera parte de una aplicación más grande, donde queremos conectar esta con PD u otro sistema de tranking video para detectar personas, y que esta “colisione” también con la lluvia.
La aplicación contiene gráficos de relámpagos y sonido, aunque al exportarlo estoy teniendo problemas para que se oiga.De todos modos aqui está.***

Librería de física Box2D

He decidido usar una librería de física para poder simular  de manera realista el mundo en el que vivimos.

Normalmente las librerías de física suelen ser complejas y llenas de clases y se necesitan bastantes conocimientos de vectores, fuerzas y trigonometría.Para empezar por algo más o menos sencillo he encontrado Box2D.

 ¿Qué es Box2D?

Box2D es un motor de física open source en C ++, con muchos puertos a otros lenguajes y entornos.

En concreto existe uno Java port of Box2D que trabaja con Processing para el render de gráficos. Si vemos alguno de los ejemplos de JBox2D, veremos que son un monton de clases Java complicadas a simple vista, pero Daniel Shiffman, en su página, nos introduce al mundo Box2D con Processing, compartiendo unas librerías que hacen un poco más sencilla la tarea de la física de partículas con Processing. Aunque no es tan completo como  en jbox2d.org, es una buena manera de empezar con Box2D.

http://www.shiffman.net/teaching/nature/box2d-processing/

Descargar la librería.

https://github.com/shiffman/PBox2D

En la programación de Box2D hay que saber tres conceptos básicos:

El mundo(World)

Es en el cual está todo incluido. Están  almacenados los cuerpos presentes en el mundo y las articulaciones(joins) que conectan estos organismos.

Se necesitan saber de dos parámetros importantes:

  • AABB: Define los bordes de su universo donde existe el mundo Box2D, lo  que existe fuera de esta delimitación se ignorará.
  • Gravedad – un vector de la gravedad, que indica como de fuerte es la gravedad y que dirección toma
Aunque esto no se incluye en la programación, ya que va incluido en la librería PBox2D, es necesario saber para entender que:
El sistema de coordenadas Box2D no es igual al sistema de coordenadas en píxeles de Processing! 

Tendremos que hacer conversiones del mundo real al mundo Box2D para que todo funcione correctamente. Existen unas funciones en la librería PBox2D que nos realizan estos cálculos.

// Crear un objeto Box2D
PBox2D box2d = new PBox2D(this);
Vec2 mouseWorld = box2d.coordPixelsToWorld(mouseX,mouseY);
//------------------------
Vec2 worldPosition = new Vec2(-10,25);
Vec2 screenPosition = box2d.coordWorldToPixels(worldPosition);
No podemos usar PVector
Box2D viene con su propia clase vector: vec2, aunque cambie un poco la sintaxis, se utiliza de la misma manera. Por ejemplo, aquí, definimos la posición en el mundo.
Vec2 worldPosition = new Vec2(-10,25);

El Cuerpo (body)

Un cuerpo Box2D es el elemento principal en el mundo Box2D.Tiene una ubicación, tiene una velocidad, pueden experimentar fuerzas, también puede ser estático.

Es importante tener en cuenta, que un body no es una forma, un body tiene una masa, pero no existe en el mundo si no tiene una forma  donde colocar esa masa.

Lo primero que hay que hacer es definir un cuerpo con BodyDef (y con él se puede ajustar las propiedades tales como la ubicación en mundo Box2D), y con esa definición, crear el cuerpo.

// Define y crea el cuerpo
    BodyDef bd = new BodyDef();
    bd.position.set(box2d.coordPixelsToWorld(center));
    body = box2d.createBody(bd);

Y una vez que tengamos el cuerpo, podemos establecer algunas propiedades más, como la velocidad inicial:

  // coje una velocidad aleatoria inicial
    body.setLinearVelocity(new Vec2(random(-1,3),random(-1,3)));

Forma (Shape)

Las  formas se unen a los bodys para que puedan colisionar con ellos. Con ellas podemos ajustar propiedades como la fricción, la densidad, el deslizamiento… Solo podemos usar formas ya definidas, polígonos o círculos, pero con ellos podemos formar otro tipo de formas. Lo bueno de poder separar los cuerpos de las formas, es que se puede crear un cuerpo que contenga muchas formas, para crear figuras mas complejas.

Para definir una forma, utilizamos PolygonDef, CircleDef, o cualquier clase Shape.

// Medidas, pasadas al mundo box2d.
float box2dW = box2d.scalarPixelsToWorld(w/2);
float box2dH = box2d.scalarPixelsToWorld(h/2);
Vec2 center = new Vec2(x,y);
//definimos las propiedades fisicas a traves de una definicion de forma;
PolygonDef sd = new PolygonDef();
sd.setAsBox(box2dW, box2dH);
sd.density = 0;    // densidad 0 significa q no se mueve!
sd.friction = 0.3f;

Para forma de círculo:

// hago un circulo para q las gotas salgan en forma de circulo.
CircleDef cd = new CircleDef();
//el radio del circulo
r = box2d.scalarPixelsToWorld(random(0,1));
cd.radius = r;
//  Parámetros que afectan a la física
cd.density = 10f;// A la densidad de 0 a crear un cuerpo fijo que no se mueve
cd.friction = 0.1f;    // Resbaladizo cuando está mojado!
cd.restitution = 0.3f;//rebote

Colocar la forma al cuerpo:

Una vez definido, le añadimos la forma al cuerpo y lo creamos en el mundo.

body.setMassFromShapes();
//añadimos al mundo
body.createShape(cd);

La función llamada setMassFromShapes(). Le dice a Box2D he terminado haciendo el cuerpo y  que puede calcular su masa de todas las formas adjuntas. Se pueden crear o destruir las formas de un cuerpo sobre la marcha, siempre puede llamar a setMassFromShapes() para ajustar la masa en consecuencia.

Para poder visualizar nuestros cuerpos y formas en Processing, necesitamos darle una forma gráfica, con las mismas medidas y posiciones para que coincida con la forma creada.

Esto es, por cada forma de Box2D hay que crear (si quieremos visualizarlo), su forma, por ejemplo, mi fijo en este caso, tiene una función display, que mostrará un rectángulo, con la forma del cuerpo que hemos definido, ya que los bodys y shapes son elementos invisibles en el mundo con masa, física, etc…

// dibujamos los Fijos
void display() {
fill(227,195,135);//color beige
stroke(227,195,135);
strokeWeight(1);
rectMode(CENTER);
float a = b.getAngle();
pushMatrix();
translate(x,y);
rotate(-a);
rect(0,0,w,h);
popMatrix();
}

En Resumen, qué pasos hay que seguir para crear un mundo Box2D?

Para hacerlo más fácil y entendible, he creado una pestaña por cada clase que utilizamos, una será la clase principal de Processing, donde está el draw() y el setup(), que se encargan de todo el proceso y de llamar a los constructores de las partículas(sueltas), otra los elementos fijos, otra la lluvia(array de partículas) y la ultima, que será el audio.

En el setup(), destacamos:

// inicializar la fisica box2d y crear el mundo
box2d = new PBox2D(this);
//crea la caja que compone el mundo principal
box2d.createWorld();
//crea nuestro componente de gravedad
box2d.setGravity(0, -9.8);
// Crea ArrayLists de particulas y objetos fijos
sistema_particulas = new ArrayList<SistemaParticulas>();
fijos = new ArrayList<Fijo>();
// Añado casa
// Fijo(float x_,float y_, float w_, float h_, float angle)
fijos.add(new Fijo(80,100,110,5,0.5f));//tejado

….

En draw(), destacamos:

  • Que hay que llamar a box2d.step(), sin esta función no sucedería nada. En cada “paso” el motor de física mira en todos los elementos y decide que hacer con ellos.
  • Llamar a las funciones ejecutar Sistema de partículas (mostrará finalmente cada grupo de partículas) y display de fijos(mostrará los fijos)
  • La llamada progresiva a las creación de Sistema de partículas, según pasa el tiempo (framerate) para que se produzca una lluvia progresiva (el sonido también va cambiando).

Etiquetas: , , , , , , ,

About Miriam Esteve

Ingeniera & creativa. Amiga de mis amigos. Me gustan las cosas bonitas, el diseño, el video y la fotografía, cocinar, reír y disfrutar de la vida! Spain&Germany www.control-art.com

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: