Empieza a desarrollar juegos en HTML5 con Box2dWeb

Empieza a desarrollar juegos en HTML5 con Box2dWeb
Sin comentarios Facebook Twitter Flipboard E-mail

Box2D es una librería que implementa un motor de física, escrita inicialmente para C++ pero que dispone de versiones para varios lenguajes como Flash o JavaScript, que es en esta última en la que nos vamos a centrar. Box2dWeb, que es la versión para JavaScript, en principio opera a través de Canvas (de HTML5) y nos proporciona un entorno completo con leyes físicas muy potente.

Tampoco es la primera vez que hablamos del tema, ya que en Genbeta Dev ya hablamos de Box2D integrado con SFML.

Box2dWeb crea todo la simulación, pero no lo representa en pantalla, simplemente nos proporciona los datos de los objetos de la simulación. Por poner un ejemplo, si tenemos una bola botando dentro de una caja nos dará la posición en cada instante de las paredes de la caja y de la bola (que será dinámica), a partir de ahí nosotros podemos usar esos datos para representar esa escena con elementos HTML (como sería un elemento alargado para las paredes y un elemento con los bordes redondeados que sea circular para la bola). Pero esta forma de representarlo es la manera "difícil", ya que disponemos de unos muy buenos datos para generar con Canvas esa misma simulación.

Por suerte disponemos de un modo debug, que es sobre el que trabajaremos en este artículo, ya que nos ahorramos esa parte de dibujar el resultado. El siguiente ejemplo está en modo debug para ver rápidamente como funciona Box2dWeb, pulsando sobre la visualización se generan nuevas bolas.

Descargar el framework

Podemos descargar el código desde Google Code, está portado desde Box2dFlash y dispone de muy poca documentación, y hace difícil encontrar ciertas funciones, ya que hay que buscarlas en la documentación de Box2dFlash, pero lo más básico no es demasiado complicado de encontrar y os lo voy a ir explicando.

El framework es bastante pesado, ocupa 200kb reducido y simplemente tenemos que añadirlo a nuestra página.

Primeros pasos

Vamos a trabajar solo con el modo debug, por lo que solo vamos a necesitar un elemento Canvas donde se mostrará todos los elementos de nuestra simulación de forma básica. El Canvas tendrá 650px de ancho y 300px de alto.



    

</head>
<body style='margin:0px'>
    <canvas id="canvasDebug" width='650' height='300'></canvas>
</body>

La librería dispone de muchas clases y por eso es recomendable hacer atajos para las funciones más importantes. Es recomendable establecer las siguientes variables con los atajos.

var  b2Vec2 = Box2D.Common.Math.b2Vec2,
    b2BodyDef = Box2D.Dynamics.b2BodyDef,
    b2Body = Box2D.Dynamics.b2Body,
    b2FixtureDef = Box2D.Dynamics.b2FixtureDef,
    b2World = Box2D.Dynamics.b2World,
    b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape,
    b2CircleShape = Box2D.Collision.Shapes.b2CircleShape,
    b2DebugDraw = Box2D.Dynamics.b2DebugDraw;

Conceptos básicos

Este motor de física usa sistemas de medición propios de la física, no del diseño o del desarrollo. Para la medida de distancia se usan los metros que a proporción son 30 píxeles (1 metro = 30 px), para el peso se usan los kilogramos y para el tiempo los segundos.

Todo el entorno que simula el framework está dentro de "un mundo" y posee su propia gravedad, siempre que creemos un nuevo objeto debemos de introducirlo en el mundo. Por poner un ejemplo más claro, se hace de una forma muy similar a la de crear un elemento en el DOM, añadirle las propiedades necesarias y finalmente añadirlo (con un appendChild).

var gravity = new b2Vec2(0,20); // Se representa la gravedad mediante un vector (0 horizontal, 10 vertical)
var world = new b2World(gravity,  true); // Creamos el mundo y le establecemos la gravedad

Tipos de objetos

Por el momento solo crearemos círculos y rectángulos, que vamos a asignarles distintos estados según su función. Se diferencian estos tres tipos:

  • Estático (b2Body.b2_staticBody): elementos que no se mueven, como van a ser los límites del escenario, el suelo o plataformas.

  • Dinámico (b2Body.b2_dynamicBody): elementos que se verán afectados por las leyes físicas, como es la gravedad o aceleración si les aplicamos fuerza.

  • Cinemático (b2Body.b2_kinematicBody): elementos que admiten movimiento pero no se ven afectados por las leyes físicas, no sufren la gravedad ni reaccionan al aplicarle fuerza por parte de otros objetos, pero si que los demás objetos sufren su fuerza.

Cuando establecemos la posición de un objeto siempre se establece su punto central de la figura. Al establecer el ancho, el alto, o el radio de un rectángulo o círculo le damos la distancia desde su centro hasta el punto más alejado en el eje X o Y, es decir, damos el tamaño en el eje X o Y de la mitad del elemento (si queremos un bloque de 300px hay que establecer el ancho de 150px)

Limites del escenario

Una buena práctica en Box2dWeb es crear por separado los límites o el escenario por separado de los objetos en movimientos. Para poner el ejemplo haremos un los límites en los laterales de Canvas y una simple plataforma ligeramente elevada.

Ejemplo

Para hacer más cómodo y fácilmente personalizable crearemos un array con objetos donde estableceremos la posición de los elementos y su ancho y alto.

Nota: tenemos que recordar la proporción de 1 metro es igual a 30 píxeles, por lo que las dimensiones las dividiremos entre 30 al procesar los objetos.

canvasDebug = document.getElementById('canvasDebug');
// Tamaño del canvas
var _cw = canvasDebug.width,
    _ch = canvasDebug.height;
// Dimensiones y posiciones de los muros
var wallsDimensions =[
    //Eje X     Eje Y       Ancho       Alto
    {x:_cw/2,    y:  0,      w:_cw/2, h:  1}, // Superior
    {x:_cw/2,    y:_ch,       w:_cw/2, h:  1}, // Inferior
    {x:  0,     y:_ch/2, w:  1,      h:_ch},  // Izquierda
    {x:_cw,      y:_ch/2, w:  1,      h:_ch},  // Derecha
    {x:_cw/2,    y:200,      w:100,      h: 10}  // Muro de la parte inferior
];

Con esto tendríamos los datos de la posición de los muros y sus dimensiones (relativas al tamaño del Canvas). Ahora procesaremos el objeto para generar las muros en nuestro escenario, que aún es imaginario.

for(var i=0;i

Visualizar el escenario

Ahora configuraremos la visualización de la simulación para que nos muestre en un Canvas a modo de prueba cómo se comportan los elementos del escenario. Al ser simplemente unos muros no habrá movimiento, posteriormente se lo daremos.

var debugDraw = new b2DebugDraw();   // Objeto de visualización de depuración
debugDraw.SetSprite(canvasDebug.getContext("2d"));  // Establecemos el canvas para visualizarlo
debugDraw.SetDrawScale(30);     // Escala de la visualización
debugDraw.SetFillAlpha(0.3);    // Transparencia de los elementos (debug)
debugDraw.SetLineThickness(1.0);
debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
  
world.SetDebugDraw(debugDraw);  // Le proporcionamos al "mundo" la salida del debug

Tras tener la configuración realizada hay que establecer la tasa de refresco mediante un intervalo.

var FPS = 60;    // Establecemos la tasa de refresco por segundo
  
setInterval(function(){
    world.Step(1 / FPS, 10, 10);    // Avanzamos la escena
    world.DrawDebugData();
    world.ClearForces();
},1000/FPS);

Generar bolas con velocidad

Ahora le añadiremos al escenario bolas al pulsar en el canvas, que saldrán con una velocidad aleatoria hacia un lado u otro. Para generar bolas usamos el mismo proceso que antes, solo que en lugar de crear un polígono crearemos un círculo y le estableceremos el radio.

canvasDebug.addEventListener('click',function(){
    var ballDef = new b2BodyDef;
    ballDef.type = b2Body.b2_dynamicBody;
    ballDef.position.Set(_cw*0.5/30, _ch*0.2/30);
  
    var fixture = new b2FixtureDef;
    fixture.density = 10;
    fixture.friction = 0.5;
    fixture.restitution = 0.8;
    fixture.shape =  new b2CircleShape(10/30); // Establecemos el radio (1m=30px)
  
    var ball = world.CreateBody(ballDef)
    ball.CreateFixture(fixture);
  
    // Generamos una velocidad aleatoria
    var velocityFactor = 10,
        randVelocity = Math.round(Math.random()*velocityFactor*2)-velocityFactor;
  
    ball.SetLinearVelocity(new b2Vec2(randVelocity,0)) // Establecemos la velocidad con la que saldrá la bola
    balls.push(ball);
});

Resultado

El código del siguiente Canvas con el resultado lo podéis consultar aquí (viendo el código fuente, es un solo archivo).

Box2dWeb es una fantástica librería para el desarrollo de juegos, dentro de poco veremos como usar la simulación y crear una visualización más completa.

En Genbeta Dev | Introducción a Box2dWeb Más información | Box2dWeb

Comentarios cerrados
Inicio