Yesterday, I realized that my initial difficulties with Three.js and Box2dWeb integration were caused by my failure to account for rotation. Specifically, objects in Box2dWeb were rotating / falling down after a collision, but I was only representing the position change in Three.js.
The solution was to copy the rotation from the Box2dWeb world into the Three.js scene:
function gameStep() {
world.Step(
1 / 60, //frame-rate
10, //velocity iterations
10 //position iterations
);
world.ClearForces();
var pdef = player_fixture.GetBody().GetDefinition();
player.position.x = pdef.position.x;
player.position.y = pdef.position.y;
player.rotation.z = pdef.angle;
var fdef = fruit_fixture.GetBody().GetDefinition();
fruit.position.x = fdef.position.x;
fruit.position.y = fdef.position.y;
setTimeout(gameStep, 1000 / 60); // process the game logic
// at a target 60 FPS.
}That works, but I do not really want my player to rotate or fall down in this jumping game. Happily, Box2dWeb provides a fixedRotation property to accomplish this: // ...
// player
bodyDef.type = b2Body.b2_dynamicBody;
fixDef.shape = new b2PolygonShape;
fixDef.shape.SetAsBox(10, 25);
bodyDef.position.x = -75;
bodyDef.position.y = 10;
bodyDef.fixedRotation = true;
player_fixture = world.CreateBody(bodyDef).CreateFixture(fixDef);
// ...With that, I can collide without rotating:Next, I would like to detect the collision. This turns out to be fairly straight forward in Box2dWeb. Straight-forward, but a little different than typical JavaScript events.
Normally, I would add an event listener to the player or the game tokens. But in Box2dWeb, I need to create a
b2ContactListener object and, on that object, I need to set a BeginContact property. Lastly, I have to add the listener to the Box2dWeb world object as a contact listener: // ...
var myListener = new Box2D.Dynamics.b2ContactListener;
myListener.BeginContact = function(contact) {
if (contact.m_fixtureA === ground) return;
if (contact.m_fixtureB === ground) return;
console.log(contact);
score += 10;
writeScoreBoard("Score: " + score);
};
world.SetContactListener(myListener);
// ...In any collision, there are two objects. In Box2dWeb, these are properties of a contact object supplied to the listener's callback. The properties are named m_fixtureA and m_fixtureB. In my callback, I need guard clauses to ignore collisions with the ground. If it is a real collision, I update the game score.And it works:
Nice. This listener object, call back property, set-on-world process feels a bit awkward, but it works. And for something compiled from ActionScript, I'll take it.
Day #500


No comments:
Post a Comment