4
\$\begingroup\$

I am making a game that uses a text map to draw obstacles and courses for the player to navigate. However, I am concerned that my method of looping through the text map to draw objects on the screen isn't as efficient as it could be.

View the playable project on Khan Academy.

Here is my code dealing with the text map:

var platforms = [];
platforms.add = function(xPosition, yPosition, width, height, colour) {
    platforms.push( new Block(xPosition, yPosition, width, height, colour) );
};

platforms.display = function() {
    for (var i = 0; i < platforms.length; i++) {
        platforms[i].display();
    }
};
var levelOne = [
    // each symbol is equivalent to 40 pixels
    ["##########"], // # - block
    ["#        #"], // S - starting position
    ["#        #"],
    ["#        #"],
    ["#        #"],
    ["#  #     #"],
    ["#       ##"],
    ["#     #  #"],
    ["#S  #    #"],
    ["##########"],
];
var symbol;
var playerX;
var playerY;
for(var i = 0; i < levelOne.length; i++) {

    for(var j = 0; j < levelOne[i].length; j++) {
        for(var v = 0; v < levelOne[i][j].length; v++) {
            var symbol = levelOne[i][j][v];
            if(symbol === "#") {
            // Platform arguments: X, Y, Width, Height, Color
                platforms.add(v*width/10, i*height/10, width/10, height/10, color(0, 174, 255));
            } else if (symbol === "S") {
                playerX = v*width/10;
                playerY = i*height/10;
            }
        }
    }
}

How can I make this code more efficient?

\$\endgroup\$
3
\$\begingroup\$

Well, for starters, you could reduce operations to \$O(n^2)\$ by skipping your third loop:

var levels = [
    ["##########",
     "#        #",
     "#        #",
     "#        #",
     "#        #",
     "#  #     #",
     "#       ##",
     "#     #  #",
     "#S  #    #",
     "##########"]
];

for(var i = 0; i < levels[0].length; i++){
    for(var j = 0; j < levels[0][i].length; j++){
        var symbol = levels[0][i][j];
        console.log(symbol);
    }
}

I changed levelOne to a levels array where you can refer to each level by index, since you probably want to add more levels later on.

jsFiddle

Why do you define symbol outside of the loop, and re-declare it inside?

Regarding your platforms:

var platforms = [];

platforms.add = function(xPosition, yPosition, width, height, colour) {
    platforms.push(new Block(xPosition, yPosition, width, height, colour) );
};

You are just declaring an add method for that specific array instance. It also creates an enumerable property on the array which isn't good if someone happens to use for..in to iterate the array (which I wouldn't recommend in the first place). Why not simply call push directly?

If you insist on creating your own add method, in my opinion, platforms should be either its own "type" (if you plan to create several instances):

function platform(){
    this.blocks = [];
}

platform.prototype.addBlock(function(block){
    this.blocks.push(block);
});

Or if you know that you'll only use one platform, create a "static" object:

var platform = {
    blocks: [],
    addBlock: function(block){
        this.blocks.push(block);
    }
};
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy