Saturday, March 23, 2013

Simple Game Scoring

‹prev | My Chain | next›

Up today, I hope to introduce some simple scoring into the river rafting game in 3D Game Programming for Kids.

For starters, I want to increase the score simply for progressing through the game. This should do the trick:
  var next_x;
  function updateScore() {
    if (!next_x) next_x = raft.position.x + 25;
    if (raft.position.x > next_x) {
      scoreboard.score(scoreboard.getScore() + 10);
      next_x = next_x + 25;
    }
  }
This should defeat the gamer trying to retrace their steps to score points for crossing the same marker multiple points. I do need to clean up that scoreboard API a bit. Well, not so much clean up as add an addPoints() method.

That actually seems to work. Next up, bonus points for reaching the end of the game. If the player reaches the finish line in under 30 seconds, then the player should get 100 extra points. If the player reaches the finish line faster, those points should increase. I try this in my gameStep() loop:
  function gameStep() {
    if (!paused) scene.simulate(2/60, 2);
    // Finish line
    if (raft.position.x > 250) {
      paused = true;
      scoreboard.stopTimer();
      if (scoreboard.getTime() < 20) scoreboard.score(scoreboard.getScore() + 500);
      if (scoreboard.getTime() < 25) scoreboard.score(scoreboard.getScore() + 250);
      if (scoreboard.getTime() < 30) scoreboard.score(scoreboard.getScore() + 100);
    }
    // ...    
    // Update physics 60 times a second so that motion is smooth
    setTimeout(gameStep, 1000/60);
  }
I wind up with two problems here. First, the scoreboard timer continues to update. This turns out to be a bug in the scoreboard itself. I set a private variable whenever stopTimer() is called. The problem is that nothing in the above condition is halting the gameStep() loop—even when the game is over. This calls scoreboard.stopTimer() repeatedly, which continues to update that private variable in scoreboard. The end result is that the scoreboard timer is stopped and started dozens of times a second and effectively keeps the scoreboard timer running. The fix for that is to check for that private variable in scoreboard before setting it.

But that still leaves me with a problem with time bonus scores. Just as the timer is repeatedly called, so are the added scores, which leads to rapidly increasing scores when the game is over. Again the solution is easy enough—I need to introduce a game_over variable:
  var game_over = false;
  function gameStep() {
    if (game_over) return;
    if (!paused) scene.simulate(2/60, 2);
    if (raft.position.x > 250) {
      paused = true;
      scoreboard.stopTimer();
      if (scoreboard.getTime() < 20) scoreboard.score(scoreboard.getScore() + 500);
      if (scoreboard.getTime() < 25) scoreboard.score(scoreboard.getScore() + 250);
      if (scoreboard.getTime() < 30) scoreboard.score(scoreboard.getScore() + 100);
      game_over = true;
    }

    // Update physics 60 times a second so that motion is smooth
    setTimeout(gameStep, 1000/60);
  }

With that, I have my simple scoring working:



I need to add ways to lose points (and the game). I also need to add a method or two to the scoreboard. But this is a good start.


Day #699

No comments:

Post a Comment