Monday, February 11, 2013

Object Literals vs. Function Constructors

‹prev | My Chain | next›

I put proverbial pen to proverbial paper today on the objects chapter in 3D Game Programming for Kids. After the first sentence, I realize that my plans to stick with a pure prototypical introduction to object oriented coding would skip something very important: the new keyword. I have the kids using new as early as the first chapter, so it would seem bad manners not to explain it at all.

In the post-OOP game chapter that I am currently working, I have been making the ramps (in blue) from
Three.js / Physijs objects:


I had been doing this with an object literal describing the prototypical ramp:
  var ramp = {
    startAt: function(location) {
      // constructor things here...
    },
    addMouseHandler: function() { /* ... */ },
    addKeyHandler: function() { /* ... */ },
    // ...
  };
And then I take this prototypical ramp to create real ones:
  var ramp1 = Object.create(ramp);
  ramp1.startAt({
    position: [ /* ... */ ],
    rotation: /* ... */
  });
  scene.add(ramp1.mesh);
Of course, the startAt() method is little more than a constructor, so I can rewrite this as:
  function Ramp(options) { /* ... */ }

  Ramp.prototype.addMouseHandler = function() { /* ... */ };
  Ramp.prototype.addKeyHandler = function() { /* ... */ };
Easy-peasy, except that I now have to explain what that prototype thing is to the poor kids. I am also not sure that I can continue to use object literals quite as freely. Since I had been building the ramp from a single object, I could re-use the concept elsewhere. For instance, I had been creating new ramps by supplying the position and orientation in an object literal:
  var ramp1 = new Ramp({
    position: [0.4 * width * randomPlusMinus(), 0.4 * height * randomPlusMinus()],
    rotation: 2 * Math.PI * Math.random()
  });
  scene.add(ramp1.mesh);
I could even perform that scene.add() inside the constructor if I supply the scene:
  var ramp1 = new Ramp({
    position: [0.4 * width * randomPlusMinus(), 0.4 * height * randomPlusMinus()],
    rotation: 2 * Math.PI * Math.random(),
    scene: scene
  });
The only trouble is that, with my switch to function constructors, I would now be required to introduce both object literal and function constructed objects. Bother.

I specifically avoided object literals when I introduced arrays as I thought they might be too much, too soon. Now they seem too much, even later. If I really want to explain the new keyword that I have the kids use throughout the book, I think it may be best to avoid object literals, if at all possible. Then again, how can I not mention something that fundamental at all?

I think it best to step away from this for a while. I have two working implementations for this game. I will take some time to write the chapter to see which works better with the narrative that I choose. One thing is for certain, as much as I love JavaScript, it does not make this an easy concept to introduce.


Day #659

No comments:

Post a Comment