Box2d 

in a 

canvas


#HTML5GAMEJAM 2014

WHO AM i?



A geeky guy since Amstrad 464

Web and demoscene passionate

JS professor at ISART Digital (video game school)

bertrand.coizy@gmail.com 
@etribz

QUICK PHYSIC MOTOR DEFINITION


Provides quick simulation of physical system

 Providing

SOFT BODY DYNAMICS
RIGID BODY DYNAMICS
FLUID SIMULATION

Mainly used in video games

SOME BASICS



BODIES

rigid body => movable object with hard material

static body => static object, collisionable too

(kinetic body => no collision)

More Basics...



3 Parameters on each object

friction => rubbing of an object with another

restitution => act of restoring force while collisioning

density => determine the mass with object size

SOME JS PHYSICS MOTOR (2D)

Box2DWeb

Two different forks

1/ flash version (good but slow)
2/ asm.js version

Many implementation and examples on the web.
You can easily switch from a C++ or flash example to JS.

Used in many game (angry birds, thomas was alone)
And some engine too: Unity3D (2d version)

P2JS


Work In Progress

Few examples and light documentation

Has springs!
Some collision are not yet implemented
Used in phaser.js

Matter.JS



Javascript native

Very fast

Mobile compatible


(keep an eye on it)

Wait what about 3D engines?


PhysisJS 

Plugin for Three.js

"Five easy step to implement a scene"

MOAR 3D engines?


Cannonjs

Written in javascript from scratch

Lightweight (less than 100k)

A last one?


Ammo.js


"Avoided Making My Own js physics engine by compiling bullet from C++ "


Many features, and also used by playcanvas or babylon.js

//TODO box2d



First: implement a scene

Second: put some objects in it

Third: render it!

THE SCENE AKA WORLD


So you have to define a world

The first parameter corresponds to the gravity!
 var world = new b2World(new b2Vec2(0, 10), true); 

The world scale is the ratio beetween box2dScale and your canvas pixels

 world.b2dScale = 30;

An object declaration


// Step one: creating the fixturevar marioFixture = new b2FixtureDef;marioFixture.restitution = 0.0;
marioFixture.friction = 0.1;
marioFixture.density = 0.4 / ratioHeight;
marioFixture.shape = new b2PolygonShape;
marioFixture.shape.SetAsBox( 30 / SCALE, 30 / SCALE);//Step two: body definition
var marioBodyDef = new b2BodyDef;
marioBodyDef.type = b2Body.b2_dynamicBody;
marioBodyDef.position.x = 100 / SCALE;
marioBodyDef.position.y = 100 / SCALE;
var b2dMario = game.b2dWorld.CreateBody(marioBodyDef);
b2dMario.CreateFixture(marioFixture);

Setting up a ground


var groundBodyDef = new b2BodyDef;
//setting this as a static object!
groundBodyDef.type = b2Body.b2_staticBody;

// positions the center of the object (not upper left!)
groundBodyDef .position.x = canvas.width / 2 / SCALE;
groundBodyDef .position.y = (canvas.height / SCALE) - 1;

groundFixDef.shape = new b2PolygonShape;

// half width, half height.
groundFixDef.shape.SetAsBox((canvas.width / SCALE) / 2, 0.5 / 2);

//then we create a ground var ground =world.CreateBody(groundBodyDef ).CreateFixture(groundFixDef);

Let the force be with us


Applying a force, example

//First we set up a direction by with a vectorvar v = new b2Vec2((game.controls.right - game.controls.left) * 0.1, 0);
//then we can apply this force to a body!mario.ApplyImpulse(v, mario.GetWorldCenter());

Running the scene


You have to tell to box2D to update the world at each frame

 function update() {
   requestAnimationFrame(update);
   world.Step(1 / 60,  10,  10 ;
   world.DrawDebugData();
   world.ClearForces();

   mario.update();
}; 

First example



Canvas VS box2D


You can use the debug box2D function for debug purpose!

Draw your sprite from box2d object coordinates. 

Remember: you always have to use the world scale (30 by default)

 context.drawImage(marioImage,                     mario.GetBody().GetPosition().x * SCALE ,                     mario.GetBody().GetPosition().y * SCALE) 

For debug purpose


Box2D allows you a perform a debug drawing.
You can enable this with this code

 //setup debug draw
var debugDraw = new b2DebugDraw();
debugDraw.SetSprite(document.getElementById("c").getContext("2d"));
debugDraw.SetDrawScale(SCALE);
debugDraw.SetFillAlpha(0.3);
debugDraw.SetLineThickness(1.0);
debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
world.SetDebugDraw(debugDraw);

//TODO 2 : joints


To do a more funny and realistic experience,
joints & pulleys are avalaible

  

JOINTS USE


  • Used to constrain bodies to the world or to each other.
  • Can be combined in many different ways to create interesting motions.
  • Some joints provide limits so you can control the range of motion.


Examples in games: ragdolls, teeters, and pulleys. 


Setting up a joint


You will need two points of contact (bodies)

Basically that's all!!!

revoluteJointDef = new b2RevoluteJointDef();
revoluteJointDef.bodyA = firstPlatform;
revoluteJointDef.bodyB = secondPlatform;revoluteJoint = world.CreateJoint(revoluteJointDef);

A game with this?



DIFFERENTS TYPES OF JOIN

 Distance

 Revolute
Pulley 


Advanced Mode


You can use box2D for many goals.

And you can render it with webgl or canvas 2D.

Let's try a fluid simulation


Questions?

Box2d in a canvas

By trambz

Box2d in a canvas

  • 2,028