Useful JavaScript Game Extensions: Number#floor and Number#ceil

Parts 14 and 15 of my 256 part series on useful JavaScript game extensions.

JavaScript is missing a lot of features that help a language be object oriented. I don’t see why since they are so easy to add.

/**
 * @returns The number truncated to the nearest integer of less than or equal value.
 *
 * (4.9).floor(); // => 4
 * (4.2).floor(); // => 4
 * (-1.2).floor(); // => -2
 */
Number.prototype.floor = function() {
  return Math.floor(this);
};
/**
 * @returns The number truncated to the nearest integer of greater than or equal value.
 *
 * (4.9).ceil(); // => 5
 * (4.2).ceir(); // => 5
 * (-1.2).ceil(); // => -1
 */
Number.prototype.ceil = function() {
  return Math.ceil(this);
};

Quest for Meaning a game made in two days for Mini-LD #21

Here it is, my entry for the mini-Ludum Dare competition. The competition theme is “biggest fear”, and one of my biggest fears is a meaningless life. Not only that, but a meaningless eternity. Pictures for Sad Children has a very similar theme at times and it helped inspire parts of this game (though I couldn’t find a good way to work in “monster most vulnerable when heaving with sobs”).

This was my first 2 day competition and I’ve learned some things. First, two days is a long time. Second, having real tools would make me very, very happy. Third, I thought that doing all the art and all the programming for a game would be hard, but it seems to use different parts of the brain, so when working on art the programming part of my brain is relaxing and vice versa.

This was the first moderately legit game that I’ve done all my own art on (title screen and chest graphics contributed by Lana). Also, my first game with a 4 color grayscale pallet. And additionally, my first major undertaking on the Pixie platform.

Working with the Pixie platform had some serious trade-offs. JavaScript is a surprisingly productive language with it’s functional and dynamic nature, but it has a harsh and brutal syntax. The platform libraries helped a lot to smooth some things out, and as they become more complete it will get better and better. I have high hopes for CoffeeScript, now that it is getting close to 1.0 I’m going to try using it on all my new projects and hopefully never go back. Another advantage was the tight art and code integration. It was trivial to create an image and have it appear in the game seconds later. The biggest drawback of Pixie right now is that the code “editor” is pretty much just a text area. There are no tabs, no integrated source navigation, no auto-save, no version control, and all kinds of other terrible issues. Also, there is no real tile editor, though Noel Berry pioneered the way by using the pixel editor as a tile editor before, and the surprising thing is that it’s actually not too bad.

Using Pixie to make art is awesome, but the game “platform” is not fleshed out enough for me to recommend making an entire game in it to everyone yet.

A special thanks to everyone who helped playtest and discuss various elements of the game throughout it’s stages: Boltz, McGrue, DavMo, Lan, MW… props.

So check out the game and let me know what you think. By making heavy use of Pixie, especially in time limited competitions, I hope to really iron out the core usage scenarios and make it amazing.

The future is bright and full of meaning.

Useful JavaScript Game Extensions Part 8, Number#mod

Part 8/258 Number#mod

For some bizarre reason, JavaScript does not constrain the result of the % operator to be between 0 and the base. This can make computing the index into an array or “wrapping” a negative number a small pain. This method gives all numbers an improved mod method that will guarantee they end up inside the array.

/**
 * A mod method useful for array wrapping. The range of the function is
 * constrained to remain in bounds of array indices.
 *
 * Example:
 * (-1).mod(5) === 4
 *
 * @param {Number} base
 * @returns An integer between 0 and (base - 1) if base is positive.
 * @type Number
 */
Number.prototype.mod = function(base) {
  var result = this % base;

  if(result  0) {
    result += base;
  }

  return result;
};

This makes jumping into an index much easier.

// Example usage
var result = array[n.mod(array.length)];

Though still not quite as nice as in Ruby where you can do:

result = array[n] # Ruby cares enough to make it happen

I love Ruby…

2hr HTML5 Tetris

I’ve taken an interest in limited time game competitions recently and figured I’d better practice up. So as an exercise I tried to make Tetris in 1hr in Pixie. Except for the blocks getting stuck in the walls and that one thing about the lines, it was pretty good for an hour.

I decided that I got pretty close to a “working” game and forked the app to do the 2hr version. I learned that some beveled block graphics really make a difference! As well as actually removing completed lines. There is one bug where sometimes blocks overlap or won’t move into what appears to be empty space, as well as the “choice” of rotation points, but hey, times up.

Useful JavaScript Game Extensions: Array#shuffle

Do the shuffle! Array#shuffle

Part 7/256

Shuffling is important, especially in card games.

/**
 * Returns a new array with the elements all shuffled up.
 *
 * @returns A new array that is randomly shuffled.
 * @type Array
 */
Array.prototype.shuffle = function() {
  var shuffledArray = [];

  this.each(function(element) {
    shuffledArray.splice(rand(shuffledArray.length + 1), 0, element);
  });

  return shuffledArray;
};

Notice how building on the previous components of rand and each makes this method much easier to write. You’ll find that when you surround yourself with great APIs things constantly become easier and easier, whereas when you are surrounded with terrible APIs things become harder and harder.

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 this 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.