function createRigidBody(propList){
var fixDef = new b2FixtureDef;
fixDef.density = propList.density;
fixDef.friction = propList.friction;
fixDef.restitution = propList.restitution;
var bodyDef = new b2BodyDef;
if(propList.type == "StaticBody"){
bodyDef.type = b2Body.b2_staticBody;
}
if(propList.type == "DynamicBody"){
bodyDef.type = b2Body.b2_dynamicBody;
}
if(propList.shape == "Box"){
fixDef.shape = new b2PolygonShape;
fixDef.shape.SetAsBox(propList.width, propList.height);
}
if(propList.shape == "Sphere"){
fixDef.shape = new b2CircleShape(propList.width)
}
bodyDef.position.x = propList.x;
bodyDef.position.y = propList.y;
rbData = new Object();
rbData.name = propList.name;
rbData.width = propList.width;
rbData.height = propList.height;
rbData.skin = propList.skin;
bodyDef.userData = rbData;
world.CreateBody(bodyDef).CreateFixture(fixDef);
}
var fixDef = new b2FixtureDef;
fixDef.density = propList.density;
fixDef.friction = propList.friction;
fixDef.restitution = propList.restitution;
var bodyDef = new b2BodyDef;
if(propList.type == "StaticBody"){
bodyDef.type = b2Body.b2_staticBody;
}
if(propList.type == "DynamicBody"){
bodyDef.type = b2Body.b2_dynamicBody;
}
if(propList.shape == "Box"){
fixDef.shape = new b2PolygonShape;
fixDef.shape.SetAsBox(propList.width, propList.height);
}
if(propList.shape == "Sphere"){
fixDef.shape = new b2CircleShape(propList.width)
}
bodyDef.position.x = propList.x;
bodyDef.position.y = propList.y;
rbData = new Object();
rbData.name = propList.name;
rbData.width = propList.width;
rbData.height = propList.height;
rbData.skin = propList.skin;
bodyDef.userData = rbData;
world.CreateBody(bodyDef).CreateFixture(fixDef);
}
There are three parts to a b2Body
1. Fixture Definition - It defines the attributes of the object, such as density, friction, and restitution (bounciness).
2. Body Definition - It defines where in the world the object is, and if it is dynamic (reacts to things) or static.
3. Shape - it defines the actual 2D geometrical object, such as a circle/box or polygon. Right now this code handles only box/circle
Rendering the Box2D object on the Canvas
The Box2D object can be drawn on the canvas using the Debug2draw method like in the previous example, but that is only for debugging purpose. For gaming we need to render images on the canvas.
When creating the b2Body, i have attached the skin(image to be rendered) information to it for housekeeping purpose.
rbData.skin = propList.skin;
..
bodyDef.userData = rbData;
I am using the updateskin(b) method to redraw the canvas for each step in the game world. When Dynamic physics bodies move in the world the canvas has to be updated to make sure that the image is in the exact same position and of same size as the b2Body.
function updateSkin(b)
{
var pos = b.GetPosition();
context.save();
console.log(b.GetWorldCenter().x * SCALE, b.GetWorldCenter().y *SCALE);
context.translate(b.GetWorldCenter().x * SCALE,b.GetWorldCenter().y * SCALE);
context.rotate(b.GetAngle());
width = b.GetUserData().width * SCALE;
height = b.GetUserData().height * SCALE;
context.drawImage(b.GetUserData().skin, -width, -height, (width)*2, (height)*2);
context.restore();
}
Putting it to Together
Now using the above methods, you can create an Box2D object and render it on screen as follows,
function initGround() {
propertyList = new Object();
propertyList.density = 1.0;
propertyList.friction = 0.5;
propertyList.restitution = 0.2;
propertyList.x = 200;
propertyList.y = 390;
propertyList.width = 350;
propertyList.height = 10;
propertyList.type = "StaticBody";
propertyList.shape = "Box"
var image = new Image();
image.src = "image/brick.png";
propertyList.skin = image;
propertyList.name = "Ground";
createRigidBody(propertyList);
}
propertyList = new Object();
propertyList.density = 1.0;
propertyList.friction = 0.5;
propertyList.restitution = 0.2;
propertyList.x = 200;
propertyList.y = 390;
propertyList.width = 350;
propertyList.height = 10;
propertyList.type = "StaticBody";
propertyList.shape = "Box"
var image = new Image();
image.src = "image/brick.png";
propertyList.skin = image;
propertyList.name = "Ground";
createRigidBody(propertyList);
}
function gameLoop() {
world.Step(1 / 60, 8, 3);
world.ClearForces();
context.clearRect(0, 0, canvas.width, canvas.height);
for (b = world.GetBodyList() ; b; b = b.GetNext()) {
// draw the static world objects
if (b.GetType() == b2Body.b2_staticBody && b.GetUserData() != null){
updateSkin(b);
}
if (b.GetType() == b2Body.b2_dynamicBody && b.GetUserData() != null) {
updateSkin(b);
}
}
}
world.Step(1 / 60, 8, 3);
world.ClearForces();
context.clearRect(0, 0, canvas.width, canvas.height);
for (b = world.GetBodyList() ; b; b = b.GetNext()) {
// draw the static world objects
if (b.GetType() == b2Body.b2_staticBody && b.GetUserData() != null){
updateSkin(b);
}
if (b.GetType() == b2Body.b2_dynamicBody && b.GetUserData() != null) {
updateSkin(b);
}
}
}
Hi,
ReplyDeleteI following your blog, reading all articles.
I have a doubt. Can I get a specific element using GetBodyList? Or an element in the list?