var canvas;
var ctx;
var canvasWidth;
var canvasHeight;
var world;
function createWorld() {
var worldAABB = new b2AABB();
worldAABB.minVertex.Set(-4000, -4000);
worldAABB.maxVertex.Set(4000, 4000);
var gravity = new b2Vec2(0, 300);
var doSleep = false;
var world = new b2World(worldAABB, gravity, doSleep);
return world;
}
function drawWorld(world, context) {
for (var j = world.m_jointList; j; j = j.m_next) {
}
for (var b = world.m_bodyList; b != null; b = b.m_next) {
for (var s = b.GetShapeList(); s != null; s = s.GetNext()) {
if (s.GetUserData() != undefined) {
var img = s.GetUserData();
var x = s.GetPosition().x;
var y = s.GetPosition().y;
var topleftX = -img.clientWidth / 2;
var topleftY = -img.clientHeight / 2;
context.save();
context.translate(x, y);
context.rotate(s.GetBody().GetRotation());
context.drawImage(img, topleftX, topleftY);
context.restore();
}
drawShape(s, context);
}
}
}
function createBall(world, x, y, r, custom) {
var ballSd = new b2CircleDef();
ballSd.density = 1.0;
if (custom === 'fixed') ballSd.density = 0.0;
else ballSd.userData = custom;
ballSd.radius = 20;
ballSd.restitution = 1.0;
ballSd.friction = 0;
var ballBd = new b2BodyDef();
ballBd.AddShape(ballSd);
ballBd.position.Set(x || 0, y || 0);
return world.CreateBody(ballBd);
}
function createBox(world, x, y, width, height, custom) {
var boxSd = new b2BoxDef();
boxSd.extents.Set(width || 1200, height || 5);
boxSd.density = 1.0;
if (custom === 'fixed') boxSd.density = 0.0;
else boxSd.userData = custom;
boxSd.restitution = .3;
boxSd.friction = 1;
var boxBd = new b2BodyDef();
boxBd.AddShape(boxSd);
boxBd.position.Set(x || 10, y || 10);
return world.CreateBody(boxBd)
}
function step() {
world.Step(1.0 / 60, 1);
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
drawWorld(world, ctx);
setTimeout(step, 10);
}
function drawShape(shape, context) {
context.strokeStyle = '#003300';
context.beginPath();
switch (shape.m_type) {
case b2Shape.e_circleShape:
var circle = shape;
var pos = circle.m_position;
var r = circle.m_radius;
var segments = 16.0;
var theta = 0.0;
var dtheta = 2.0 * Math.PI / segments;
context.moveTo(pos.x + r, pos.y);
for (var i = 0; i < segments; i++) {
var d = new b2Vec2(r * Math.cos(theta), r * Math.sin(theta));
var v = b2Math.AddVV(pos, d);
context.lineTo(v.x, v.y);
theta += dtheta;
}
context.lineTo(pos.x + r, pos.y);
context.moveTo(pos.x, pos.y);
var ax = circle.m_R.col1;
var pos2 = new b2Vec2(pos.x + r * ax.x, pos.y + r * ax.y);
context.lineTo(pos2.x, pos2.y);
break;
case b2Shape.e_polyShape:
var poly = shape;
var tV = b2Math.AddVV(poly.m_position, b2Math.b2MulMV(poly.m_R, poly.m_vertices[0]));
context.moveTo(tV.x, tV.y);
for (var i = 0; i < poly.m_vertexCount; i++) {
var v = b2Math.AddVV(poly.m_position, b2Math.b2MulMV(poly.m_R, poly.m_vertices[i]));
context.lineTo(v.x, v.y);
}
context.lineTo(tV.x, tV.y);
break;
}
context.stroke();
}
function GetBodyAtPosition(x, y) {
var mousePVec = new b2Vec2(x, y);
var aabb = new b2AABB();
aabb.minVertex.Set(mousePVec.x - 0.001, mousePVec.y - 0.001);
aabb.maxVertex.Set(mousePVec.x + 0.001, mousePVec.y + 0.001);
var k_maxCount = 10;
var shapes = new Array();
var count = world.Query(aabb, shapes, k_maxCount);
var findBody = null;
for (var i = 0; i < count; ++i) {
if (shapes[i].GetBody().IsStatic() == false)
{
var tShape = shapes[i];
var inside = tShape.GetBody();
if (inside)
{
findBody = tShape.GetBody();
break;
}
}
}
return findBody;
}
function getMousePos(event) {
var e = event || window.event;
var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
var x = e.pageX || e.clientX + scrollX;
var y = e.pageY || e.clientY + scrollY;
return { 'x': x, 'y': y };
}
function handleMousedown(e) {
var e = e || window.event;
var newMouse = getMousePos(e);
var selectBody = GetBodyAtPosition(newMouse.x - canvas.offsetLeft, newMouse.y - canvas.offsetTop);
if (selectBody) {
var LinearVelocity = new b2Vec2(500, -200);
selectBody.WakeUp();
selectBody.SetLinearVelocity(LinearVelocity);
} else {
var width = parseInt(Math.random() * 50);
var height = parseInt(Math.random() * 50);
createBox(world, newMouse.x, newMouse.y, width, height);
}
}
document.addEventListener('mousedown', handleMousedown, false);
window.onload = function () {
canvas = document.getElementById('canvas');
ctx = canvas.getContext('2d');
canvasWidth = parseInt(canvas.width);
canvasHeight = parseInt(canvas.height);
world = createWorld();
var ball1 = createBall(world, 100, 20, 20);
var ball2 = createBall(world, 300, 60, 10);
var box1 = createBox(world, 100, 200, 25, 30, 'fixed');
var box2 = createBox(world, 200, 50, 20, 20);
var box3 = createBox(world, 400, 80, 20, 20, document.getElementById('box'));
var wallLeft = createBox(world, 0, 0, 10, 600, 'fixed');
var wallRight = createBox(world, 1290, 0, 10, 400, 'fixed');
var ground = createBox(world, 30, 595, 1200, 5, 'fixed');
step();
};