Created
April 9, 2009 12:21
-
-
Save hisasann/92433 to your computer and use it in GitHub Desktop.
This file contains 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
/* | |
* protoBox2d JavaScript Library, version 1.0 | |
* http://lab.hisasann.com/protoBox2d/ | |
* require : prototype.js 1.6 | |
* | |
* Copyright (c) 2009 hisasann http://hisasann.com/ | |
* Dual licensed under the MIT and GPL licenses. | |
*/ | |
var protoBox2d = function() {}; | |
protoBox2d.prototype = { | |
worldAABB : null, | |
world : null, | |
stage : [], | |
walls : [], | |
elements : null, | |
bodies : [], | |
properties : [], | |
delta : [0, 0], | |
timeStep : 1.0/60, | |
iteration : 1, | |
mouseX : 0, | |
mouseY : 0, | |
mouseJoint : null, | |
isPlaying : false, | |
isMouseDown : false, | |
init : function() { | |
var size = this.getWindowSize(); | |
this.stage[0] = size.width; | |
this.stage[1] = size.height; | |
document.onmousedown = this.onDocumentMouseDown.bindAsEventListener(this); | |
document.onmouseup = this.onDocumentMouseUp.bindAsEventListener(this); | |
document.onmousemove = this.onDocumentMouseMove.bindAsEventListener(this); | |
worldAABB = new b2AABB(); | |
worldAABB.minVertex.Set(-200, -200); | |
worldAABB.maxVertex.Set( screen.width + 200, screen.height + 200); | |
this.world = new b2World(worldAABB, new b2Vec2(0, 0), true); | |
this.setWalls(); | |
this.elements = document.getElementsByClassName("box2d"); | |
for (i = 0; i < this.elements.length; i++) { | |
var element = this.elements[i]; | |
this.properties[i] = Position.cumulativeOffset(element); | |
this.properties[i][2] = element.offsetWidth; | |
this.properties[i][3] = element.offsetHeight; | |
} | |
for (i = 0; i < this.elements.length; i++) { | |
var element = this.elements[i]; | |
element.style["position"] = "absolute"; | |
element.style["left"] = this.properties[i][0] + "px"; | |
element.style["top"] = this.properties[i][1] + "px"; | |
var room = this.createBox(this.world, this.properties[i][0] + (this.properties[i][2] >> 1), | |
this.properties[i][1] + (this.properties[i][3] >> 1), | |
this.properties[i][2] / 2, | |
this.properties[i][3] / 2, | |
false); | |
room.m_linearVelocity = new b2Vec2((Math.random() - .5) * 10, (Math.random() - .5) * 10); | |
this.bodies[i] = room; | |
} | |
var _this = this; | |
setInterval(function() { | |
_this.loop(); | |
}, 25); | |
}, | |
setWalls : function() { | |
var wallSize = 200; | |
this.walls[0] = this.createBox(this.world, this.stage[0] / 2, - wallSize, this.stage[0], wallSize); // top | |
this.walls[1] = this.createBox(this.world, this.stage[0] / 2, this.stage[1] + wallSize, this.stage[0], wallSize); // bottom | |
this.walls[2] = this.createBox(this.world, - wallSize, this.stage[1] / 2, wallSize, this.stage[1]); // left | |
this.walls[3] = this.createBox(this.world, this.stage[0] + wallSize, this.stage[1] / 2, wallSize, this.stage[1]); // right | |
}, | |
createBox : function(world, x, y, width, height, fixed, element) { | |
if (typeof(fixed) == "undefined") fixed = true; | |
var boxSd = new b2BoxDef(); | |
if (!fixed) boxSd.density = 1.0; | |
boxSd.extents.Set(width, height); | |
var boxBd = new b2BodyDef(); | |
boxBd.AddShape(boxSd); | |
boxBd.position.Set(x,y); | |
boxBd.userData = {element: element}; | |
return world.CreateBody(boxBd) | |
}, | |
loop : function() { | |
this.delta[0] += (0 - this.delta[0]) * .5; | |
this.delta[1] += (0 - this.delta[1]) * .5; | |
this.world.m_gravity.x = 0 + this.delta[0]; | |
this.world.m_gravity.y = 350 + this.delta[1]; | |
this.mouseDrag(); | |
this.world.Step(this.timeStep, this.iteration); | |
for (i = 0; i < this.elements.length; i++) { | |
var element = this.elements[i]; | |
element.style["left"] = (this.bodies[i].m_position0.x - (this.properties[i][2] >> 1)) + "px"; | |
element.style["top"] = (this.bodies[i].m_position0.y - (this.properties[i][3] >> 1)) + "px"; | |
element.style["-webkit-transform"] = "rotate(" + (this.bodies[i].m_rotation0 * 57.2957795) + "deg)"; | |
} | |
}, | |
onDocumentMouseDown : function(e) { | |
this.isMouseDown = true; | |
return false; | |
}, | |
onDocumentMouseUp : function (e) { | |
this.isMouseDown = false; | |
return false; | |
}, | |
onDocumentMouseMove : function(e) { | |
if (!this.isPlaying) { | |
this.isPlaying = true; | |
var _this = this; | |
setInterval(function() { | |
_this.loop(); | |
}, 25); | |
} | |
this.mouseX = e.clientX; | |
this.mouseY = e.clientY; | |
}, | |
mouseDrag : function() { | |
// mouse press | |
if (this.isMouseDown && !this.mouseJoint) { | |
var body = this.getBodyAtMouse(); | |
if (body) { | |
var md = new b2MouseJointDef(); | |
md.body1 = this.world.m_groundBody; | |
md.body2 = body; | |
md.target.Set(this.mouseX, this.mouseY); | |
md.maxForce = 30000.0 * body.m_mass; | |
md.timeStep = this.timeStep; | |
this.mouseJoint = this.world.CreateJoint(md); | |
body.WakeUp(); | |
} | |
} | |
// mouse release | |
if (!this.isMouseDown) { | |
if (this.mouseJoint) { | |
this.world.DestroyJoint(this.mouseJoint); | |
this.mouseJoint = null; | |
} | |
} | |
// mouse move | |
if (this.mouseJoint) { | |
var p2 = new b2Vec2(this.mouseX, this.mouseY); | |
this.mouseJoint.SetTarget(p2); | |
} | |
}, | |
getBodyAtMouse : function() { | |
var mousePVec = new b2Vec2(); | |
mousePVec.Set(this.mouseX, this.mouseY); | |
var aabb = new b2AABB(); | |
aabb.minVertex.Set(this.mouseX - 1, this.mouseY - 1); | |
aabb.maxVertex.Set(this.mouseX + 1, this.mouseY + 1); | |
var k_maxCount = 10; | |
var shapes = new Array(); | |
var count = this.world.Query(aabb, shapes, k_maxCount); | |
var body = null; | |
for (var i = 0; i < count; ++i) { | |
if (shapes[i].m_body.IsStatic() == false) { | |
if (shapes[i].TestPoint(mousePVec)) { | |
body = shapes[i].m_body; | |
break; | |
} | |
} | |
} | |
return body; | |
}, | |
getWindowSize : function() { | |
function getWindowWidth(){ | |
if(window.innerWidth) return window.innerWidth; // Mozilla, Opera, NN4 | |
if(document.documentElement && document.documentElement.clientWidth){ // 以下 IE | |
return document.documentElement.clientWidth; | |
}else if(document.body && document.body.clientWidth){ | |
return document.body.clientWidth; | |
} | |
return 0; | |
} | |
function getWindowHeight(){ | |
if(window.innerHeight) return window.innerHeight; // Mozilla, Opera, NN4 | |
if(document.documentElement && document.documentElement.clientHeight){ // 以下 IE | |
return document.documentElement.clientHeight; | |
}else if(document.body && document.body.clientHeight){ | |
return document.body.clientHeight; | |
} | |
return 0; | |
} | |
return { | |
width: getWindowWidth(), | |
height: getWindowHeight() | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment