Useful JavaScript Extensions: Number#times

Part 5/256

For loops… I hate them so much. Fortunately, a well established functional iteration convention is the Number#times method.

/**
 * Calls iterator the specified number of times, passing in a number of the 
 * current iteration as a parameter. The number will be 0 on first call, 1 on 
 * second call, etc. 
 * 
 * @param {Function} iterator The iterator takes a single parameter, the number 
 * of the current iteration.
 * @param {Object} [context] The optional context parameter specifies an object
 * to treat as <code>this</code> in the iterator block.
 * 
 * @returns The number of times the iterator was called.
 */
Number.prototype.times = function(iterator, context) {
  for(var i = 0; i < this; i++) {
    iterator.call(context, i);
  }
  return i;
}

This hides the inner workings of the iteration from the calling code so there’s no need to keep track of an external dummy iterator variable if you don’t want to.

var n = 3;
 
// Greets you three times, with respect
n.times(function() {
  alert("O HAI!");
});
 
// logs: 0, 1, 2
n.times(function(i) {
  console.log(i);
});

Useful JavaScript Game Extensions: Array#remove

Debris Removal
Part 4: Array#remove

JavaScript Arrays are missing some very common, very useful functions. One of those is the remove method. We want to be able to say “Hey you, array, remove this object from yourself! Now!!” But our poor JS array’s don’t know how. They can barely remove elements from specific indices, let alone a specified object. Well no longer! Now they’ll do what we say.

/**
 * Remove the first occurance of the given object from the array if it is
 * present.
 *
 * @param {Object} object The object to remove from the array if present.
 * @returns The removed object if present otherwise undefined.
 */
Array.prototype.remove = function(object) {
  var index = this.indexOf(object);
  if(index >= 0) {
    return this.splice(index, 1)[0];
  } else {
    return undefined;
  }
};

By building off of the Array‘s built in methods we can keep this code very short. We find the first occurrence of the specified object using indexOf, then we remove and return it using splice. If it wasn’t found we return undefined instead.

// An illustrative test suite
 
test("Array#remove", function() {
  ok([1,2,3].remove(2) === 2, "[1,2,3].remove(2) === 2");
  ok([1,3].remove(2) === undefined, "[1,3].remove(2) === undefined");
  ok([1,3].remove(3) === 3, "[1,3].remove(3) === 3");
 
  var array = [1,2,3];
  array.remove(2);
  ok(array.length === 2, "array = [1,2,3]; array.remove(2); array.length === 2");
  array.remove(3);
  ok(array.length === 1, "array = [1,3]; array.remove(3); array.length === 1");
});

John Resig has another take on Array#remove, remove by index. You may want to take a look at that as well, though for me it feels more natural to remove by specified object rather than by specified index.

Useful JavaScript Game Extensions: Array#rand

Ayn Rand

Part 3 of 256.

/**
 * Randomly select an element from the array. The array remains unmodified.
 *
 * @returns A random element from an array, or undefined if the array is empty.
 */
Array.prototype.rand = function() {
  return this[rand(this.length)];
};

Building on the last installment of a global rand method, we can easily extend Array to provide simple random element selection.

// Example:
["rock", "paper", "scissors"].rand()

Selecting options from a loot table, or random AI actions is now wonderfully easy. With all these extensions the theme is the same, start with the best interface for the programmer and extend what you must to make it happen.

Useful JavaScript Game Extensions: rand

Rand Atlas Shrugged
Part 2 of my 256 part series: Useful JavaScript Game Extensions!

/**
 * Generate uniformly distributed random numbers.
 *
 * @param {Number} [n]
 * @returns A Random integers from [0, n) if n is given, otherwise a random float
 * between 0 and 1.
 * @type Number
 */
function rand(n) {
  if(n !== undefined) {
    return Math.floor(Math.random() * n);
  } else {
    return Math.random();
  }
}

Some games make use of random numbers… a lot. So when choosing the best interface it is important to keep that in mind. Often times uniform distributions are the way to go, such as when selecting from an array, or rolling a six sided die. If one often has need of a variety of random distributions then having different methods live in a Random namespace would probably be best. For simple, everyday use a little rand(6) is very convenient.

Useful JavaScript Game Extensions: Clamp

Give him the clamps!

Part 1 of my new 256 part series on simple JavaScript extensions to make game programming easy and fun!

/**
 * Returns a number whose value is limited to the given range.
 *
 * Example: limit the output of this computation to between 0 and 255
 * (x * 255).clamp(0, 255)
 *
 * @param {Number} min The lower boundary of the output range
 * @param {Number} max The upper boundary of the output range
 * @returns A number in the range [min, max]
 * @type Number
 */
Number.prototype.clamp = function(min, max) {
  return Math.min(Math.max(this, min), max);
};

Note that this extends the behavior of the Number class. Some may consider it poor form to “mess with” the JS built-ins, but I consider it poor form to expose a worse than necessary interface to the programmer. Compare:

// Namespace?
STRd6.Util.clamp(x * 255, 0, 255);
 
// global function clamp?
clamp(x * 255, 0, 255);
 
// Clean, simple and object oriented!
(x * 255).clamp(0, 255);

Stay tuned for the next 255 parts of the series!

Matrix.js 1.0.1 Released

Thoroughly documented, tested, and minifies very small (1.4k), this is the best release yet!

Observe the sweetness:

  // Rotate 90 degrees
  var matrix = Matrix.rotation(Math.PI / 4);
 
  // Scale and move
  var finalTransform = matrix.scale(1/2).translate(125, 175);
 
  canvas.withTransform(finalTransform, function() {
    // Draw a circle or whatever in the transformed coordinates
    // canvas.fillCircle(0, 0, 50);
  });

New Pixie Color Palette

On Pixie we recently redesigned our color palette.

It’s important to choose a good default color palette for your application. For most people the color palette is one of their first impressions of your product, and the palette will largely determine the kinds of things they can make. In addition less than half the people who interact with your product for the first time will even use a custom color, or a different tool. That makes the default choice doubly important.

Let’s say you were stranded on a desert island and only got to take 10 crayons, what would you take? Answering that question is very similar to answering the default palette question.

Since prehistoric times people have enjoyed drawing what they see in their environment. I have a friend, and he wears a blue shirt, so I need the color Shirt Blue. Sometimes he eats apples; I’d better also have Apple Red. The apple came from an apple tree, good thing there’s Leaf Green, and Tree Brown.

Modularity and context are also important. Each of these colors shouldn’t only be a uni-tasker. Shirt Blue can double as Lake Blue when drawn on the ground. Hair Blonde or Hay-bale Yellow? Same color, but it depends on the context. Remember, you’re trapped on an island and need to make these colors count.

The classic defaults are pretty weak. If they had crayola names they’d be something like Maximum Red, Maximum Green, Maximum Blue, Horrendo Cyan, Staring into the Sun Yellow and Good God Man Make it Stop Magenta.

Maybe your friend eats GMO Apples (for maximum redness), as well as wearing outrageous clothing. Mine usually don’t, that’s why I developed the Best Friend’s Apple / Desert Island default color palette.