Up tonight, I am going to get started on a new Three.js game for Gaming JavaScript. I ran into a bit of a problem with the last game that used the Physijs physics engine to simulate physics. It worked just fine—except when running from the file system.
To minimize the dependencies, I have been trying to write games for kids such that they could make a simple web page that referenced all library code from a web site. That works fine for normal JavaScript, but no so much for web worker code. Physijs smartly uses a web worker for its work. Unfortunately that complicates things for me.
So tonight I hope to get started with Box2D.js and Three.js. For all I know, it could suffer from similar "problems".
I start by grabbing the download:
wget http://box2dweb.googlecode.com/files/Box2dWeb-2.1a.3.zipI unzip and am ready to go:
➜ scripts git:(gh-pages) ✗ sha1sum Box2dWeb-2.1a.3.zip
315bb2b1c603f6dae2cf886b2ebc9ef242579ac6 Box2dWeb-2.1a.3.zip
➜ scripts git:(gh-pages) ✗ unzip -l Box2dWeb-2.1a.3.zip
Archive: Box2dWeb-2.1a.3.zip
Length Date Time Name
--------- ---------- ----- ----
429833 2011-06-07 11:55 Box2dWeb-2.1.a.3.js
224935 2011-06-07 11:45 Box2dWeb-2.1.a.3.min.js
6764 2011-06-15 13:04 demo.html
3030 2011-06-15 13:04 example.html
--------- -------
664562 4 files
➜ scripts git:(gh-pages) ✗ unzip Box2dWeb-2.1a.3.zip
Archive: Box2dWeb-2.1a.3.zip
inflating: Box2dWeb-2.1.a.3.js
inflating: Box2dWeb-2.1.a.3.min.js
inflating: demo.html
inflating: example.html I start my Three.js Javascript with a boring (non-physics) "player" in a blank scene:function init() {
renderer = initRenderer(0x87CEEB);
scene = new THREE.Scene;
player = new THREE.Mesh(
new THREE.CubeGeometry(20, 50, 10),
new THREE.MeshBasicMaterial({color: 0xB22222})
);
scene.add(player);
camera = new THREE.PerspectiveCamera(
75, window.innerWidth / window.innerHeight, 1, 10000
);
camera.position.z = 100;
camera.lookAt(player.position);
scene.add(camera);
}The initRenderer() is just something that I wrote for the rafting game to initialize a WebGL Three.js renderer (if present) or a canvas renderer otherwise, with the specified background color. The rest is straight-forward Three.js—adding a firebrick red cube, representing the game player, to the scene as well as a camera that looks at the player.I then start the physics, copying most of this straight from the Box2dWeb example file:
function startPhysics() {
var b2Vec2 = Box2D.Common.Math.b2Vec2
, b2World = Box2D.Dynamics.b2World
, b2FixtureDef = Box2D.Dynamics.b2FixtureDef
, b2BodyDef = Box2D.Dynamics.b2BodyDef
, b2Body = Box2D.Dynamics.b2Body
, b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape;
world = new b2World(
new b2Vec2(0, 10), //gravity
true //allow sleep
);
var fixDef = new b2FixtureDef;
fixDef.density = 1.0;
fixDef.friction = 0.5;
fixDef.restitution = 0.2;
var bodyDef = new b2BodyDef;
//create ground
bodyDef.type = b2Body.b2_staticBody;
bodyDef.position.x = 9;
bodyDef.position.y = 13;
fixDef.shape = new b2PolygonShape;
fixDef.shape.SetAsBox(10, 0.5);
world.CreateBody(bodyDef).CreateFixture(fixDef);
// player
bodyDef.type = b2Body.b2_dynamicBody;
fixDef.shape = new b2PolygonShape;
fixDef.shape.SetAsBox(
Math.random() + 0.1 //half width
, Math.random() + 0.1 //half height
);
bodyDef.position.x = 0;
bodyDef.position.y = 100;
player_fixture = world.CreateBody(bodyDef).CreateFixture(fixDef);
}
Last up, I create a gameStep() function to periodically update my player's position as it falls:function gameStep() {
world.Step(
1 / 60, //frame-rate
10, //velocity iterations
10 //position iterations
);
world.ClearForces();
var body = player_fixture.GetBody().GetDefinition();
player.position.x = body.position.x;
player.position.y = body.position.y;
setTimeout(gameStep, 1000 / 60); // process the game logic
// at a target 60 FPS.
}And that works. Only not quite. My player drop up instead of down. This is because the Box2D animation was written for canvas and its inverted y-axis. The fix is easy enough—I only need to mark physics as working down in the startPhysics() function:function startPhysics() {
// ...
world = new b2World(
new b2Vec2(0, -10), //gravity
true //allow sleep
);
// ...
}
With that, I have my "player" falling under the influence of gravity:That will do for a stopping point tonight. Up tomorrow I will add movement controls to the player and reflect those changes in the Box2dWeb world. I also need to clean up that Box2DWeb code. I can't be inflicting that on kids.
Day #497


No comments:
Post a Comment