Saturday, September 1, 2012

Timing Three.js Games

‹prev | My Chain | next›

Up tonight, I hope to build on the "Game Over" text that I added my Three.js / Physijs game yesterday.

I start by generalizing slightly so that initializing my scoreboard, initializes an absolutely positioned <div> with an ID by which I refer it later:
function initScoreBoard() {
  var text = document.createElement('div');
  text.id = 'scoreboard';
  text.style.position = 'absolute';
  text.style.backgroundColor = 'white';
  text.style.borderRadius = "5px";
  text.style.padding = "0px 20px";
  text.style.left = "50px";
  text.style.top = "75px";
  text.style.height = "100px";
  document.body.appendChild(text);

  writeScoreBoard(
    'j / k to turn; space to move' +
    '
    '<br/>' +
    'Press space to start'
  );
}
At the very end of that function, I invoke writeScoreBoard(), which does the job of overwriting the innerHTML of the scoreboard <div>, but in a reusable way:
function writeScoreBoard(message) {
  var text = document.getElementById('scoreboard');
  text.innerHTML = message;
}
With that out of the way, I modify the start of the game to store the start time and to start a timer:
var start;
function startGame() {
  start = new Date();
  runTimer();
  animate();
}
The runTimer() gets called recursively until the game is over, continuously updating the time on the scoreboard:
function runTimer() {
  if (game_over) return;

  var now = new Date()
    , diff = now.getTime() - start.getTime()
    , seconds = diff / 1000;
  writeScoreBoard(seconds);
  setTimeout(runTimer, 500);
}
And that seems to work fairly well:


Last up, I need to stop the game when the raft reaches the end point. For that, I add a ray to the raft pointing straight down. I continuously check to see what it intersects and, once it hits the lake at the bottom, the game is over with the final score:
function checkForWin() {
  var ray = new THREE.Ray(
    raft.position,
    new THREE.Vector3(0, -1, 0)
  );

  var intersects = ray.intersectObject(lake);
  if (!intersects[0]) return;

  game_over = true;

  var time = writeTime();

  writeScoreBoard(
    '<h1>Win!</h1>' +
    '<p>You won it in' +
      '<br>' +
    time + ' seconds. Yay!</p>'
  );
}
And, indeed that does the trick:


I still hope to shrink the game—both in size and complexity. But I think this more or less completes it for Gaming JavaScript.


Day #496

2 comments:

  1. Replies
    1. You play it in your browser. But the only way to get it is to buy the book and build the game yourself :D

      If you're interested, the book is available at here: http://gamingjs.com/ (and just about every bookseller as well).

      Delete