<html lang="en">
<head>
<script src="http://cdnjs.cloudflare.com/ajax/libs/modernizr/2.5.3/modernizr.min.js"></script>
<script src="http://orm-other.s3.amazonaws.com/html5canvasexamplecontent/chapter5/Box2dWeb-2.1.a.3.js"></script>
<meta charset="UTF-8">
<title>CH5EX24: Box2DWeb Box Battle</title>
</head>
<body>
<p><button onmouseup="go();">Run the example!</button></p>
<canvas id="canvasOne" width="450" height="350" style="position: absolute; top: 60px; left: 0px;">
Your browser does not support the HTML 5 Canvas.
</canvas>
<canvas id="canvasTwo" width="450" height="350" style="position: absolute; top: 60px; left: 451px;">
Your browser does not support the HTML 5 Canvas.
</canvas>
</body>
</html>
button {
background-color: #3994b6;
padding: 10px;
border-radius: 5px;
border-radius: 5px;
border-radius: 5px;
color: #FFF;
text-align: center;
text-decoration: none;
font-size: 12px;
font-weight: bold;
width: auto;
}
window.addEventListener('load', eventWindowLoaded, false);
function eventWindowLoaded() {
theCanvas = document.getElementById('canvasOne');
context = theCanvas.getContext('2d');
theCanvasTwo = document.getElementById('canvasTwo');
context2 = theCanvasTwo.getContext('2d');
looper = false;
}
function canvasSupport () {
return Modernizr.canvas;
}
// This function is an add-on to ensure you can click to rerun example
function go() {
clearTimeout(looper);
canvasApp();
}
function canvasApp() {
if (!canvasSupport()) {
return;
}
function drawScreen () {
world.Step(1 / 60, 10, 10);
world.DrawDebugData();
world.ClearForces();
context.strokeStyle = '#000000';
context.fillStyle = '#EEEEEE';
context.fillRect(0, 0, theCanvas.width, theCanvas.height);
//Box
context.fillStyle = '#000000';
context.strokeRect(1, 1, theCanvas.width-2, theCanvas.height-2);
for (i =0;i <boxes.length;i++) {
var position = boxes[i].GetPosition();
var fixtureList = boxes[i].GetFixtureList();
var shape = fixtureList.GetShape();
var userData = boxes[i].GetUserData();
context.save();
context.setTransform(1,0,0,1,0,0);
context.translate(position.x * scaleFactor,position.y * scaleFactor);
context.rotate(boxes[i].GetAngle());
context.fillRect(0-(userData.width*scaleFactor/2) , 0-(userData.height*scaleFactor/2), userData.width * scaleFactor, userData.height * scaleFactor);
context.restore();
}
for (i =0;i <balls.length;i++) {
var position = balls[i].GetPosition();
var fixtureList = balls[i].GetFixtureList();
var shape = fixtureList.GetShape();
context.fillStyle = "#FF0000";
context.beginPath();
context.arc(position.x * scaleFactor , position.y * scaleFactor ,shape.GetRadius() *scaleFactor ,0,Math.PI*2,true);
context.closePath();
context.fill();
}
}
function createBall(event) {
var x;
var y;
if (event.pageX || event.pageY) {
x = event.pageX;
y = event.pageY;
}
else {
x = e.clientX + document.body.scrollLeft +
document.documentElement.scrollLeft;
y = e.clientY + document.body.scrollTop +
document.documentElement.scrollTop;
}
x -= theCanvas.offsetLeft;
y -= theCanvas.offsetTop;
mouseX=x;
mouseY=y;
var ballDef = new b2BodyDef;
ballDef.type = b2Body.b2_dynamicBody;
var ypos = mouseY/scaleFactor;
var xpos = mouseX/scaleFactor;
var size = 7/scaleFactor;
ballDef.position.Set(xpos, ypos);
var ballFixture = new b2FixtureDef;
ballFixture.density = 30.0;
ballFixture.friction = 0.6;
ballFixture.restitution = .2;
ballFixture.shape = new b2CircleShape(size);
var newBall = world.CreateBody(ballDef)
newBall.CreateFixture(ballFixture);
var xVelocity = 15;
var yVelocity = 0;
newBall.SetLinearVelocity(new b2Vec2(xVelocity,yVelocity))
balls.push(newBall);
}
theCanvas.addEventListener("mouseup",createBall, false);
var scaleFactor = 30;
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;
var world = new b2World(new b2Vec2(0,20), true);
var numBoxes = 8;
var boxes = new Array();
var balls = new Array();
var boxHeight = 25;
var boxWidth = 25;
var startX = (theCanvas.width-100);
var startY = (theCanvas.height-boxHeight)-100
for (var i=0; i < numBoxes; i++) {
var boxDef = new b2BodyDef;
boxDef.type = b2Body.b2_dynamicBody;
var ypos = (startY-(i*boxHeight))/scaleFactor;
var xpos = (startX)/scaleFactor;
boxDef.position.Set(xpos, ypos);
var newBox = world.CreateBody(boxDef)
var boxFixture = new b2FixtureDef;
boxFixture.density = 20.0;
boxFixture.friction = .5;
boxFixture.restitution = .1;
boxFixture.shape = new b2PolygonShape;
boxFixture.shape.SetAsBox((boxWidth/scaleFactor)/2, (boxHeight/scaleFactor)/2);
newBox.CreateFixture(boxFixture);
newBox.SetUserData({width:boxWidth/scaleFactor, height:boxHeight/scaleFactor})
boxes.push(newBox);
}
var wallDefs = new Array( {x:theCanvas.width,y:0,w:theCanvas.width ,h:1}, //top
{x:theCanvas.width,y:theCanvas.height,w:theCanvas.width ,h:1}, //bottom
{x:0,y:theCanvas.height,w:1 ,h:theCanvas.height}, //left
{x:theCanvas.width,y:theCanvas.height,w:1 ,h:theCanvas.height} ); //right
var walls = new Array();
for (var i = 0; i <wallDefs.length; i++) {
var wallDef = new b2BodyDef;
wallDef.type = b2Body.b2_staticBody;
wallDef.position.Set(wallDefs[i].x/scaleFactor, wallDefs[i].y/scaleFactor);
var newWall = world.CreateBody(wallDef)
var wallFixture = new b2FixtureDef;
wallFixture.density = 10.0;
wallFixture.friction = 0.5;
wallFixture.restitution = .5;
wallFixture.shape = new b2PolygonShape;
wallFixture.shape.SetAsBox(wallDefs[i].w/scaleFactor, wallDefs[i].h/scaleFactor);
newWall.CreateFixture(wallFixture);
walls.push(newWall);
}
var debugDraw = new b2DebugDraw();
debugDraw.SetSprite (context2);
debugDraw.SetDrawScale(scaleFactor); //define scale
debugDraw.SetFillAlpha(0.3); //define transparency
debugDraw.SetLineThickness(1.0);
debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
world.SetDebugDraw(debugDraw);
function gameLoop() {
looper = window.setTimeout(gameLoop, 20);
drawScreen()
}
gameLoop();
}
Output
You can jump to the latest bin by adding /latest
to your URL
Keyboard Shortcuts
Shortcut | Action |
---|---|
ctrl + [num] | Toggle nth panel |
ctrl + 0 | Close focused panel |
ctrl + enter | Re-render output. If console visible: run JS in console |
Ctrl + l | Clear the console |
ctrl + / | Toggle comment on selected lines |
ctrl + ] | Indents selected lines |
ctrl + [ | Unindents selected lines |
tab | Code complete & Emmet expand |
ctrl + shift + L | Beautify code in active panel |
ctrl + s | Save & lock current Bin from further changes |
ctrl + shift + s | Open the share options |
ctrl + y | Archive Bin |
Complete list of JS Bin shortcuts |
JS Bin URLs
URL | Action |
---|---|
/ | Show the full rendered output. This content will update in real time as it's updated from the /edit url. |
/edit | Edit the current bin |
/watch | Follow a Code Casting session |
/embed | Create an embeddable version of the bin |
/latest | Load the very latest bin (/latest goes in place of the revision) |
/[username]/last | View the last edited bin for this user |
/[username]/last/edit | Edit the last edited bin for this user |
/[username]/last/watch | Follow the Code Casting session for the latest bin for this user |
/quiet | Remove analytics and edit button from rendered output |
.js | Load only the JavaScript for a bin |
.css | Load only the CSS for a bin |
Except for username prefixed urls, the url may start with http://jsbin.com/abc and the url fragments can be added to the url to view it differently. |