Tonight I continue my exploration of hooking Box2dWeb into Three.js. So far, I have Box2dWeb physics affecting movement in my Three.js visualization and am able to move Box2dWeb objects with key presses. Tonight, I would like to see about getting collisions working.
In my Three.js representation, I add some fruit (because what kid doesn't want to play a game with health foods?):
fruit = new THREE.Mesh(
new THREE.CylinderGeometry(20, 20, 1, 24),
new THREE.MeshNormalMaterial({color: 0xB22222})
);
fruit.rotation.x = Math.PI/2;
scene.add(fruit);
Then, I add a corresponding circle in the Box2dWeb initialization: // fruit
bodyDef.type = b2Body.b2_dynamicBody;
fixDef.shape = new b2CircleShape(20);
bodyDef.position.x = 75;
bodyDef.position.y = 10;
fruit_fixture = world.CreateBody(bodyDef).CreateFixture(fixDef);
And, lastly, in my gameStep()
, I link the position of the fruit in the Three.js animation with it in the Box2dWeb world:function gameStep() { world.Step( 1 / 60, //frame-rate 10, //velocity iterations 10 //position iterations ); world.ClearForces(); var ppos = player_fixture.GetBody().GetDefinition().position; player.position.x = ppos.x; player.position.y = ppos.y; var fpos = fruit_fixture.GetBody().GetDefinition().position; fruit.position.x = fpos.x; fruit.position.y = fpos.y; setTimeout(gameStep, 1000 / 60); // process the game logic // at a target 60 FPS. }And it works. Kind of.
I can see both the "player" (the rectangle) and the fruit (the circle):
I can even bump into the fruit. Only weird stuff happens. Like the player suddenly falls below ground level:
I cannot figure out what is going on. Maybe Box2dWeb and Three.js disagree over the placement or shape of one or both objects.
To figure this out, I make use of the debug draw that comes with Box2dWeb. In the Box2dWeb setup, I add the following (more or less copied from the Box2dWeb samples):
var b2DebugDraw = Box2D.Dynamics.b2DebugDraw;
var debugDraw = new b2DebugDraw();
debugDraw.SetSprite(document.getElementById("canvas").getContext("2d"));
debugDraw.SetDrawScale(1.0);
debugDraw.SetFillAlpha(0.3);
debugDraw.SetLineThickness(1.0);
debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
world.SetDebugDraw(debugDraw);
And tell gameStep()
to update the debugging drawing:function gameStep() { world.Step( 1 / 60, //frame-rate 10, //velocity iterations 10 //position iterations ); world.DrawDebugData(); world.ClearForces(); // ... }The result is that... my player has fallen down:
Sigh. That seems obvious in retrospect. I had it in the back of my mind that I ought to be replicating the rotation as well as the position between the two worlds. Somehow I managed to forget this. It was not until I could visualize the two side-by-side that I was able to work out the problem.
So I set the Three.js rotation to the Box2dWeb rotation:
function gameStep() { // ... var ppos = player_fixture.GetBody().GetDefinition().position; player.position.x = ppos.x; player.position.y = ppos.y; player.rotation.z = player_fixture.GetBody().GetDefinition().angle; // ... setTimeout(gameStep, 1000 / 60); // process the game logic // at a target 60 FPS. }Which seems to resolve the issue:
Well, except that I do not want my player to fall. Still, knowing what the problem is gets me started on a solution. Tomorrow.
Day #499
No comments:
Post a Comment