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.htmlI 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