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 fixture
var 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 vector
var 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,006