Professional Documents
Culture Documents
0 manual de usuario
Copyright 2007 2011 Erin Catto
Box2D es una librera para videojuegos de simulacin de cuerpos rgidos en 2D. Los
programadores pueden utilizarla en sus videojuegos para conseguir que los objetos se muevan de
varias maneras para conseguir que el mundo del videojuego sea lo ms interactivo posible. Desde
el punto de vista del motor de videojuegos, un motor de fsicas is nicamente un sistema de
animacin por procedimientos.
Box2D est escrito en C++ portable. Muchos de los tipos definidos en el motor empiezan con el
prefijo b2. Afortunadamente es suficiente para evitar combinar los nombres con tu motor de juego.
1.2 Prerequisitos
En este manual asumimos que estas familiarizado con los conceptos bsicos de fsica, como la
masa, la fuerza, la rotacin y los impulsos. Si no, por favor consulta Google y Wikipedia.
Como Box2D est escrito en C++, deberas tener experiencia en la programacin con C++. Box2D
no debe ser tu primer proyecto en C++. Deberas estar comodo con la compilacin, la vinculacin
y la depuracin (compiling, linking and debugging en Ingls).
Advertencia
Box2D no debe ser tu primer proyecto C++. Por favor, aprende programacin con C++, compilacin,
vinculacin y depuracin antes de empezar a trabajar con Box2D. Hay muchos recursos para esto en internet.
Diccionario
Testbed: (banco de pruebas en espaol) Un Testbed es una plataforma para experimentacin de proyectos de
gran desarrollo.
Doxygen: Es un generador de documentacin para C++, C, Java, Objetive-C, Python, IDL (versiones Corba y
Microsoft), VHDL y en cierta medida para PHP, C# y D.
Por favor, los archivos con errores y las solicitudes de ediciones van aqu: http://code.google.com/p/box2d
Puedes ayudar a asegurar que tus errores se solucionan si proporcionas suficientes detalles. Lo
ideal es que proporciones un testbed que reproduzca el problema. Puedes leer sobre los ltimos
testbed en este documento.
Box2D trabaja con varios objetos fundamentales. A continuacin vamos a definir dichos objetos y
a dar ms detalles sobre ellos.
Forma (Shape)
Es una forma geomtrica en 2D. Un ejemplo de ella es un crculo o un polgono.
Adorno (Fixture)
Un adorno define la forma de un cuerpo y le aade propiedades de material como la densidad, la
friccin y la restitucin.
Limitacin (Constraint)
Una limitacin es una conexin fsica que elimina el movimiento libre de los cuerpos rgidos.
Unin (Joint)
Es una limitacin usada para tener dos o ms cuerpos juntos. Box2D soporta varios tipos de
uniones: Revolute (gira en torno a algo), Prismatic (por ejemplo unir dos objetos simulando una
cuerda), Distance (limita la distancia de un objeto frente a otro) y ms.
Mundo (World)
Un mundo fsico es una coleccin de cuerpos, adornos y lmites que interactan entre s. Box2D
soporta la creacin de mltiples mundos a la vez, pero usualmente no es necesario, ya que hay
pocos videojuegos que hacen uso de esta caracterstica.
Solucionador (Solver)
Las fsicas de un mundo tienen un solucionador que es utilizado para avanzar en el tiempo y
resolver contactos y limitaciones de uniones. El solucionador de Box2D es un solucionador
iterativo de alto rendimiento que opera conforme el tiempo N, donde N es el nmero de
limitaciones.
Box2D contiene algoritmos especializados para operar con la tunelizacin. Primero, el algoritmo
de la colisin puede interpolar el movimiento de dos cuerpos para encontrar el primer tiempo de
impacto. En segundo lugar un solucionador mueve los cuerpos al primer tiempo de impacto y
resuelve la colisin.
1.6 Mdulos
Box2D est compuesto por tres mdulos: Common, Colisin y Dinmicas. El mdulo Common
tiene cdigo para asignacin, matemticas y configuraciones. El mdulo de colisin define las
formas, una amplia etapa y funciones/preguntas de colisin. Y finalmente el mdulo de dinmicas
distribuye la simulacin de mundo, cuerpos, adornos y uniones (world, bodies, fixtures and joints).
1.7 Unidades
Box2D trabaja con nmeros con coma flotante y los asentimientos tienen que ser usados para
conseguir que el rendimiento de Box2D sea bueno. Estos asentimientos tienen que ser ajustados
para trabajar con las unidades metros-kilogramo-segundo(MKS). En particular, Box2D tiene que
ser ajustado para trabajar bien con el movimiento de objetos entre 0.1 y 10 metros. Los objetos
estticos pueden recibir una fuerza de ms de 50 metros sin que le afecte lo ms mnimo.
Siendo un motor de fsicas en 2D puedes utilizar pxeles como si fueran unidades. Pero
desgraciadamente eso puede dar lugar a una simulacin pobre y posiblemente a una rara
conducta por parte del juego.
Advertencia
Box2D est ajustado para las unidades MKS(Metros-kilogramos-segundos). Guarda el tamao del movimiento
de los objetos aproximadamente entre 0.1 y 10 metros. Vas a necesitar usar algn sistema de escala cuando
vayas a renderizar el entorno y los actores (actors). El Banco de trabajo (testbed) de Box2D hace esto usando
una transformacin del viewport. NO USES PXELES.
Diccionario
Viewport: El viewport es la zona rectangular donde se muestra parte de una escena renderizada en tu
videojuego.
Es mejor pensar que sobre los cuerpos de Box2D se mueve una valla que tiene acopladas las
imgenes de tu videojuego. La valla podra moverse en un sistema de unidades de metros, pero
puedes convertirla a coordenadas de pxeles con un simple factor de escala. Puedes usar
aquellas coordenadas de pxeles para poner tus sprites, etc.
Box2D usa radians para los ngulos. La rotacin del cuerpo es almacenada en radians por lo que
podra crecer de manera ilimitada. Considerando normalmente el angulo de tus cuerpos ,si la
magnitud del angulo se hace demasiado grande podemos usar b2Body::SetAngle.
Cuando creas un cuerpo o una unin, necesitas poner una definicin. Estas definiciones contienen
toda la informacin necesitada para construir el cuerpo o la unin. Si usamos este mtodo
evitaremos errores, mantener pequeos los nmeros de los parmetros de la funcin proporciona
predeterminados sensibles y reduce el nmero de accededores.
Puesto que los adornos tienen que ser creados por un cuerpo, son creados y destrozados usando
varios metodos en b2Body:
b2Fixture* b2Body::CreateFixture(const b2FixtureDef* def)
void b2Body::DestroyFixture(b2Fixture* fixture)
Tambin hay una manera rpida de crear un adorno directamente desde la forma y la densidad.
Los factores no retienen las referencias a las definiciones. Aunque puedes crear definiciones en la
pila y mantenerlas en recursos temporales.
Las clases b2Fixture, b2Body y b2Joint te permiten vincular datos de usuario utilizando un puntero
void. Esto es prctico cuando ests examinando la estructura de los datos de Box2D y quieres
determinar como estn relacionados con las entidades en tu motor de juego.
Por ejemplo, es tpico crear una funcin para vincular un actor al cuerpo rgido en dicho actor.
Gracias a esto se consigue total control sobre los elementos vinculados. Si tienes el actor, puedes
conseguir el cuerpo. Si tienes el cuerpo, puedes conseguir el actor.
Aqu hay algunos ejemplos de casos donde tu preferirs utilizar los datos de usuario:
Mantener en medio los datos de usuario es opcional y puedes poner lo que quieras en llos. De
todas maneras, deberas ser constante. Por ejemplo, si quieres almacenar un puntero de un actor
en un cuerpo, deberas mantener un puntero de actor en todos los cuerpos. No almacenes un
puntero de actor en un solo cuerpo y un puntero X, ya que se te podra crashear el juego.
A continuacin vamos a crear el mundo. Fjate que estamos creando el mundo en la pila de
variables, por lo que podremos acceder a la variable desde cualquier lugar de la clase.
Ahora que hemos creado el mundo podremos empezar a dar vida a nuestro videojuego.
Para el primer paso crearemos el cuerpo que ser el suelo. Para hacer esto necesitamos una
definicin del cuerpo, con esa definicin especificaremos la posicin inicial del cuerpo.
b2BodyDef groundBodyDef;
groundBodyDef.position.Set(0.0f, -10.0f);
En segundo lugar necesitaremos pasar la definicin del cuerpo al mundo para que lo cree. Los
cuerpos son estticos por defecto, as que si no definimos el tipo de cuerpo siempre ser esttico.
Los cuerpos estticos no colisionan con otros cuerpos del mismo tipo (estticos) y no se pueden
mover.
En tercer lugar crearemos la forma del suelo, usaremos un polgono para conseguir que el suelo
sea un rectngulo. Para conseguir que sea un rectngulo simplemente usaremos el mtodo
SetAsBox.
b2PolygonShape groundBox;
groundBox.SetAsBox(50.0f, 10.0f);
La funcin SetAsBox necesita dos valores; lo ancho que va a ser el rectngulo y lo alto. En este
caso el rectngulo tendr 100 unidades de ancho y 20 unidades de alto. Puedes poner estas
unidades en metros, ya que generalmente Box2D trabaja mejor cuando el tamao de los objetos
es el mismo que el de los objetos reales. Por ejemplo, un barril est sobre el metro de altura.
Debido a las limitaciones del algoritmo de la coma flotante, no es una buena idea utiliza Box2D
para conseguir el movimiento de los glaciares o las de partculas de polvo.
Vamos a finalizar la creacin del suelo en el cuarto paso creando la forma del adorno. Para este
ya que podemos pasar la forma directamente al cuerpo sin necesidad de crear una definicin de
adorno. Por ltimo vamos a ver como usar una definicin de adorno para propiedades de la
materia customizados. El segundo parmetro es la densidad en kilogramos por metro cuadrado.
Un cuerpo esttico siempre tiene 0 masa, por lo que no usaremos al densidad en este caso.
groundBody->CreateFixture(&groundBox, 0.0f);
Box2D no mantiene la referencia de la forma, simplemente clona los datos dentro de una nueva
forma.
Tienes que saber que todos los adornos tienen que tener un cuerpo, incluso los adornos que son
estticos tienen que tener un cuerpo. Aunque de todas maneras puedes vincular todos los
adornos estticos a un solo cuerpo esttico.
Primero creamos el cuerpo usando CreateBody. Por defecto los cuerpos son estticos, por lo que
deberamos cambiar el b2BodyType a dinmico.
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(0.0f, 4.0f);
b2Body* body = world.CreateBody(&bodyDef);
Advertencia
Tienes que cambiar el tipo de cuerpo a b2_dynamicBody si quieres que el cuerpo sea dinmico.
El siguiente paso es crear y vincular una forma poligonal usando la definicin de adorno. Primero
tenemos que crear una forma rectangular:
b2PolygonShape dynamicBox;
dynamicBox.SetAsBox(1.0f, 1.0f);
b2FixtureDef fixtureDef;
fixtureDef.shape = &dynamicBox;
fixtureDef.density = 1.0f;
fixtureDef.friction = 0.3f;
Usando la definicin de adorno ahora podemos crear el adorno. Esto lo que hace es actualizar
automticamente la masa del cuerpo. Debes saber que puedes agregar tantos adornos como
quieras a un cuerpo. Ten en cuenta que cada uno contribuye a la masa total del cuerpo.
body->CreateFixture(&fixtureDef);
Box2D utiliza un algoritmo de computacin llamado integrador. Los integradores simulan las
ecuaciones fsicas desde puntos discretos de tiempo. Esto fue a lo largo del bucle tradicional de
juego donde esencialmente tenemos un gran libro en movimiento en la pantalla. Por lo que
necesitamos conseguir un sistema de tiempo para Box2D. Generalmente los motores de fsicas
para videojuegos el tiempo es como mnimo tan rpido como 60Hz o 1/60 segundos. Se puede ir
ms lejos con tiempos ms largos, pero vas a tener que ser ms cuidadoso a la hora de definir las
configuraciones para tu mundo. Igualmente no nos gusta cambiar el paso del tiempo demasiado.
Una variable en el tiempo produce resultados, por lo que es ms difcil de depurar.
Adems, Box2D tambin usa grandes partes de cdigo llamado solucionadores de lmites. Los
solucionadores de lmites son los encargados de simular los lmites, uno a cada segundo. Un solo
lmite puede ser solucionador perfectamente. Sin embargo, cuando resolvemos un lmite,
perturbamos ligeramente otros lmites. Para conseguir una buena solucion, necesitamos
transformar todos los lmites un nmero de veces.
El actual nmero de iteraciones para Box2D son 8 para velocidad y 3 para posicin. Puedes
ajustar este nmero como tu quieras, solo mantn en medio que estn ajustados entre velocidad y
exactitud. Utilizando pocas iteraciones aumenta el rendimiento pero la precisin es menor. Al igual
que si utilizas muchas iteraciones el rendimiento baja pero aumenta la calidad de tu simulacin.
Para este simple ejemplo, no necesitamos muchas iteraciones. Aqu est nuestro nmero elegido
de interaciones.
int32 velocityIterations = 6;
int32 positionIterations = 2;
Date cuenta de que el paso del tiempo y el nmero de interaciones no estn relacionados. Una
iteracin no es un subpaso. Un resolvedor de iteraciones es un solo paso por encima de todos los
lmiten con el paso del tiempo. Puedes tener varios pasos encima de los lmiten con un solo paso
del tiempo.
Ahora ests listo para el bucle de simulacin. En tu videojuego el bucle de simulacin puede ser
combinado con el bucle de tu videojuego. En cada paso a travs del bucle de tu videojuego puede
ser llamado b2World::Step. Normalmente con llamarlo una vez es suficiente, pero depende de tu
nmero de fotogramas por segundo y tu paso del tiempo de las fsicas.
El programa Hola Mundo ha sido diseado para ser simple, aunque no tiene una salida grfica. El
cdigo imprime la posicin y rotacin del cuerpo dinmico. Aqu est el buble de simulacion que
simula 60 pasos en el tiempo para un total de 1 segundo de tiempo simulado.
for (int32 i = 0; i < 60; ++i)
{
world.Step(timeStep, velocityIterations, positionIterations);
b2Vec2 position = body->GetPosition();
float32 angle = body->GetAngle();
printf("%4.2f %4.2f %4.2f\n", position.x, position.y, angle);
}
La salida ensea la caja cayendo y aterrizando en el suelo. En tu salida debera verse algo como
esto:
2.5 Limpieza
Cuando un mundo est fuera del alcance o es eliminado por un puntero, toda la memoria
reservada para los cuerpos, los adornos y los lmites es liberada. Esto se hace para conseguir
rendimiento y hacerte la vida ms fcil. Sin embargo, vas a necesitar eliminar un cuerpo, adorno o
punteros de lmites que tengas porque van a convertirse en invlidos.