Created
May 4, 2012 06:18
-
-
Save mkuklis/2592550 to your computer and use it in GitHub Desktop.
Leonardo + Box2D = Bonnet.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function (b2d, L) { | |
// Box2d shortcuts | |
var b2Vec2 = b2d.Common.Math.b2Vec2, | |
b2BodyDef = b2d.Dynamics.b2BodyDef, | |
b2Body = b2d.Dynamics.b2Body, | |
b2FixtureDef = b2d.Dynamics.b2FixtureDef, | |
b2Fixture = b2d.Dynamics.b2Fixture, | |
b2World = b2d.Dynamics.b2World, | |
b2PolygonShape = b2d.Collision.Shapes.b2PolygonShape, | |
b2CircleShape = b2d.Collision.Shapes.b2CircleShape, | |
b2DebugDraw = b2d.Dynamics.b2DebugDraw, | |
scale = 30; | |
// creates correct shapes for fixtures | |
var shapeCommands = { | |
circle: function (fixDef, attrs) { | |
fixDef.shape = new b2CircleShape(attrs.r / scale); | |
}, | |
rect: function (fixDef, attrs) { | |
fixDef.shape = new b2PolygonShape(); | |
fixDef.shape.SetAsBox(attrs.w / scale, attrs.h / scale); | |
} | |
}; | |
/** | |
* Initialize `Bonnet` | |
*/ | |
function Bonnet(leonardo) { | |
this.l = leonardo; | |
this.fr = 1 / 60 //frame-rate | |
this.vi = 10 // velocity iterations | |
this.pi = 10 //position iterations | |
} | |
// bonnet API | |
Bonnet.prototype = { | |
/** | |
* Creates new box2d world | |
* | |
* @api public | |
*/ | |
world: function () { | |
if (!this.w) { | |
this.w = new b2World(new b2Vec2(0, 10), true); | |
} | |
return this; | |
}, | |
/** | |
* Runs world. | |
* | |
* @api public | |
*/ | |
run: function () { | |
this.w.Step(this.fr, this.vi, this.pi); | |
this.l.redraw(this.update); | |
this.w.ClearForces(); | |
requestAnimationFrame(L.proxy(this.run, this)); | |
}, | |
/** | |
* Updates positions of the elements | |
* in the world. | |
* | |
* @param {Element} el | |
* @api private | |
*/ | |
update: function (el) { | |
var body = el.attr('body'); | |
if (body) { | |
p = body.m_body.GetPosition(); | |
//el.rotate(L.deg(body.m_body.GetAngle())); | |
el.attr({x: p.x * scale, y: p.y * scale}); | |
} | |
}, | |
/** | |
* Adds dynamic element to the world. | |
* | |
* @param {Element} element | |
* @param {object} options | |
* @api publc | |
*/ | |
add: function (el, opts) { | |
// TODO: reuse bodyDef and fixDef? | |
var bodyDef = new b2BodyDef(), | |
fixDef = new b2FixtureDef(), | |
attrs = el.attrs; | |
opts = opts || {}; | |
fixDef.density = opts.d || 1.0; | |
fixDef.friction = opts.f || 0.5; | |
fixDef.restitution = opts.r || 0.2; | |
bodyDef.position.x = attrs.x / scale; | |
bodyDef.position.y = attrs.y / scale; | |
shapeCommands[el.type].call(this, fixDef, attrs); | |
bodyDef.type = b2Body.b2_dynamicBody; | |
// create new body | |
var body = this.w.CreateBody(bodyDef).CreateFixture(fixDef); | |
// associate body with element | |
el.attr({body: body}); | |
return this; | |
}, | |
/** | |
* Adds static element to the world. | |
* | |
* @api public | |
*/ | |
addStatic: function (el, opts) { | |
// TODO: reuse bodyDef and fixDef? | |
var bodyDef = new b2BodyDef(), | |
fixDef = new b2FixtureDef(), | |
attrs = el.attrs; | |
opts = opts || {}; | |
fixDef.density = opts.d || 1.0; | |
fixDef.friction = opts.f || 0.5; | |
fixDef.restitution = opts.r || 0.2; | |
bodyDef.position.x = attrs.x / scale; | |
bodyDef.position.y = attrs.y / scale; | |
shapeCommands[el.type].call(this, fixDef, attrs); | |
bodyDef.type = b2Body.b2_staticBody; | |
// create new body | |
this.w.CreateBody(bodyDef).CreateFixture(fixDef); | |
return this; | |
} | |
}; | |
Leonardo.fn.world = function () { | |
this.b = new Bonnet(this); | |
return this.b.world(); | |
} | |
})(Box2D, Leonardo); | |
// usage | |
var leo = leonardo(0, 0, 1100, 500), | |
world = leo.world(), | |
circle1 = leo.circle(70, 70, 50, {fill: "#ff0000"}), | |
circle2 = leo.circle(75, 75, 10, {fill: "#ff0000"}), | |
rect = leo.rect(10, 450, 500, 10, {fill: "#000000"}); | |
world.add(circle1).add(circle2); | |
world.addStatic(rect); | |
world.run(); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment