Rot.js tutorial, part 3

From RogueBasin
Revision as of 15:47, 13 December 2012 by Ondras (Talk | contribs)

Jump to: navigation, search

This is the third part of a rot.js tutorial.


Looking inside the box

The game generates several boxes, but so far, none of the contains the prized ananas. Let us store the ananas in the first box generated:

Game.ananas = null;
Game._generateBoxes = function(freeCells) {
    for (var i=0;i<10;i++) {
        /* ...previous stuff... */
        if (!i) { this.ananas = key; } /* first box contains an ananas */

Apart from moving, there is one more interaction a player must perform: looking into boxes. We will allow both Enter (keyCode 13) and Spacebar (keyCode 32) for this action:

Player.prototype.handleEvent = function(e) {
    var code = e.keyCode;
    if (code == 13 || code == 32) {

Opening a box to verify its contents is as simple as comparing current player's position with our list of boxes and the stored ananas position:

Player.prototype._checkBox = function() {
    var key = this._x + "," + this._y;
    if ([key] != "*") {
        alert("There is no box here!");
    } else if (key == Game.ananas) {
        alert("Hooray! You found an ananas and won this game.");
        window.removeEventListener("keydown", this);
    } else {
        alert("This box is empty :-(");

Pedro, the angry owner

The game is now winnable! Let's add a villain as a second actor. We will place him using the same algorithm we used previously. To do this, let's refactor the original _createPlayer method into a more useful parametrized factory _createBeing by passing a constructor function as an argument:

var Pedro = function(x, y) {
    this._x = x;
    this._y = y;
Pedro.prototype.getSpeed = function() { return 100; }
Pedro.prototype._draw = function() {
    Game.display.draw(this._x, this._y, "P", "red");
Game._createBeing = function(what, freeCells) {
    var index = Math.floor(ROT.RNG.getUniform() * freeCells.length);
    var key = freeCells.splice(index, 1)[0];
    var parts = key.split(",");
    var x = parseInt(parts[0]);
    var y = parseInt(parts[1]);
    return new what(x, y);
Game._generateMap = function() {
    /* ...previous stuff... */
    this.player = this._createBeing(Player, freeCells);
    this.pedro = this._createBeing(Pedro, freeCells);

This might be confusing to some, but passing functions around (as function arguments, for instance) is very common in JavaScript.

Pathfinding-based AI

Pedro is missing its act method so far: we are going to use one of rot.js's pathfinding functions to model Pedro's behavior.

And that's all for part 3. The whole working code is available at

Personal tools