Wednesday, February 13, 2013

Pretty Simple Scoreboards

‹prev | My Chain | next›

My recent efforts have likely provided me with enough material to write the next two (possibly three) chapters in 3D Game Programming for Kids. Rather than pushing ahead to new material, now seems a good time to shore up the infrastructure.

There are a few improvements that I need to make in my fork of Mr Doob's code editor. It may be good to add a new template or two. I think that I will need a URL shortener of some kind to facilitate sharing of games. I still think it would be cool if I could get Faye in the book for multi-player gaming.

Before tackling that laundry list, I am going to stick closer to the code on which I have been working. Specifically, I would like to enable simple scoring and timing for games. That is, I would like to provide a simple scoreboard that kids can use.

At about the midway point in the book, I have kids type in the following:
  function addScoreboard() {
    var text = document.createElement('div'); = 'scoreboard'; = 'absolute'; = 'white'; = "5px"; = "0px 20px"; = "50px"; = "75px";

      'arrows to move;
space to jump'
Earlier incarnations of the book introduced the basics of the DOM. I am wavering on the matter somewhat at this point. If I remove it, then I have more time to introduce saner topics. But not touching on DOM coding at all seems a disservice to that which gave rise to the language that we all know and love.

For now, I am going to write the library so that I cannot use the lack of one as an excuse for keeping DOM coding in the book. If it warrants staying of its own merits, then so be it.

I spend a fair amount of time in the Scoreboard constructor deciding when to display different sections of the scoreboard (a text message, the score, the time). But it is just boolean logic and not all that difficult. I do end up spending time on the timer, which I make a separate class to be used as a property of the scoreboard:
function Scoreboard(options) {
  // ...
  this.timer = new __Timer();
  // ...
Rather than fiddle with timeouts or intervals, I stick with dates in that __Timer class:
function __Timer() {
  this.start = (new Date).getTime();
This makes the difference calculation easier:
__Timer.prototype.diff = function() {
  var now = (new Date).getTime();
  return now - this.start;
I then use that difference to format the elapsed time, zero padding as needed.:
__Timer.prototype.toString = function() {
  var minutes = "" + this._minutes(),
      seconds = "" + this._seconds();

  if (minutes.length == 1) minutes = "0" + minutes;
  if (seconds.length == 1) seconds = "0" + seconds;

  return minutes + ":" + seconds;
I do use an interval to update via a callback:
__Timer.prototype.onUpdate = function(cb) {
  var that = this;
  setInterval(function() {cb(that.toString());}, 100);
And, back in the Scoreboard class, I can update the timer element with that onUpdate callback:
Scoreboard.prototype.setTimer = function() {
  var that = this;
  this.timer.onUpdate(function(time) {
    that.timer_el.innerHTML = time;
  }); = this.showTimer ? 'block' : 'none';
All of this means, that I can create a scoreboard with:
  var scoreboard = new Scoreboard({
    showTimer: true,
    message: "Get the green ring. " +
             "Click and drag blue ramps. " +
             "Click and R to rotate. " +
             "Left and right arrows to move player. " +
             "Be quick!"

Which makes:

That is a lot easier than teaching beginners DOM methods. And after all, the goal of the book is to make JavaScript enjoyable—very few ever claimed working with the DOM was fun.

Day #661

No comments:

Post a Comment