Saturday, August 18, 2012

Getting Started on a New Three.js Game

‹prev | My Chain | next›

Up tonight, I hope to get started on writing some simple Three.js / Physijs games for Gaming JavaScript. First up is going to be a simple raft game that bounces down a river.

I am going to need to start up new games often in the next few months. Tonight I talk through the setup. Hopefully that will not be necessary in the future.

I start by declaring my important games object and determine which renderer to use:
var raft, camera, scene, renderer;

var canvas = !! window.CanvasRenderingContext2D;
var webgl = ( function () { try { return !! window.WebGLRenderingContext && !! document.createElement( 'canvas' ).getContext( 'experimental-webgl' ); } catch( e ) { return false; } } )();

document.addEventListener( "DOMContentLoaded", function() {
  init();
  animate();
});
The initialization in the init() function sets up the appropriate renderer:
function init() {
  if (webgl) renderer = new THREE.WebGLRenderer();
  else if (canvas) renderer = new THREE.CanvasRenderer();
  if (renderer) {
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.setClearColorHex(0x87CEEB);
    document.body.appendChild(renderer.domElement);
  }
  else {
    alert("Can't make renderer. What kind of browser are you using?!");
  }
}
Also in the init() function, I define the scene, the camera and the raft:
  scene = new THREE.Scene();

  raft = new THREE.Mesh(
    new THREE.TorusGeometry(25, 10, 4, 4),
    new THREE.MeshNormalMaterial()
  );
  scene.add(raft);

  camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
  camera.position.y = 100;
  camera.lookAt(raft);

  scene.add(camera);
New to me is the torus object, which is just a tube thing. It ought to work just fine for a raft. I place the camera 100 pixels above the scene and look down at the raft.

That is all that I need for the init() function tonight. I will worry about physics tomorrow. Moving on to the animate() function, getting started is similarly simple:
function animate() {
  // requestAnimationFrame(animate);
  render();
}

function render() {
  renderer.render(scene, camera);
}
I have not quite gotten the hang of what goes in the animate() function and what goes in the render() function. For the most part, I have been putting everything in render(), but I have not really given it much thought. Where do control updates go, for instance? A question for another day.

Anyhow, at this early juncture there is very little in either. In fact, since nothing needs to be animated at all, I do not even need an animation frame (though I will definitely uncomment that tomorrow).

With that, I take a look at my scene and see... nothing. It turns out that my camera is not, in fact, looking at the raft. It seems that the lookAt() method needs a position, not an object. Fortunately, the fix is easy enough:
  camera.lookAt(raft.position);
With that, my raft now comes into view:


That is not quite right. But I only need to rotate the object 90°:

raft = new THREE.Mesh(
    new THREE.TorusGeometry(25, 10, 4, 4),
    new THREE.MeshNormalMaterial()
  );
  raft.rotation.x = Math.PI/2;
  scene.add(raft);
Now I get to see my raft:


Hrm... that is a bit boxy. I will file that away for future use, but tonight I want more of an inner tube. That is easy enough—I just need more that 4 segments to comprise my mesh. Sixteen ought to do:

  raft = new THREE.Mesh(
    new THREE.TorusGeometry(25, 10, 16, 16),
    new THREE.MeshNormalMaterial()
  );
  raft.rotation.x = Math.PI/2;
  scene.add(raft);


That is a good stopping point for tonight. Up tomorrow: physics and maybe a river.

Day #483

No comments:

Post a Comment