Search code examples
javascriptcanvasdictionarytile

Console error when drawing to canvas


I have a main javascript file which is trying to draw a tilemap to a canvas for a game, and i have an included file which actually draws the maps etc, but im getting this error in firebug:

TypeError: Value could not be converted to any of: HTMLImageElement, HTMLCanvasElement, HTMLVideoElement. [Break On This Error]

ctx.drawImage(mapTiles[map[x][y]],x*tilesize, y*tilesize);

the main js which calls my level.js file looks like this:

$(document).ready(function(){

var canvas = document.getElementById("TBG");
var context = canvas.getContext("2d");

var ui = new Gui();
var level = new Level();

//----------Login/Register Gui --------------
$('#TBG').hide();
$('#load-new').hide();
$('#reg').hide();
$('#login').hide();

//if login_but is clicked do ui.login function
$('#login_but').click(ui.login);
//if reg_but is clicked do ui.register function
$('#reg_but').click(ui.register);

$('#new_but').click(function(){
    game_settings("new");
});

$('#load_but').click(function(){
    game_settings("load");
});

//if login_sumbit button is clicked do ui.login_ajax function
$("#login_submit").click(ui.login_ajax);

$("#reg_submit").click(ui.register_ajax);

$("#welcome").on("click", "#logout_but", ui.logout);

//____________________________________________
//Initialisation of game

function game_settings(state){
    if(state == "load"){
        ui.load_game();
        //do ajax call to load user last save
        //level.level_init(0,1);

        draw();
    }
    else{
        //set beginning params


        //Change screens
        ui.new_game();
        alert("new game");
    }
}

function draw () {

    context.clearRect(0,0,canvas.width,canvas.height);

    level.draw(context);

    setTimeout(draw, 30);


}
// End Loop 
      });

and the file where this line of code (level.js) looks like this:

function Level(){

var tilesize = 32;
var map = 0;
var mapTiles = [];

   // var saved_level = level;
    //var saved_location = location;


map = [
    [1,1,1,1,1,1,1,1,1,1],
    [2,2,2,2,2,2,2,2,2,2]
];

    for (x = 1; x <= 256; x++) {
        var imageObj = new Image(); // new instance for each image
        imageObj.src = "images/prototype/"+x+".jpg";
        mapTiles.push(imageObj);
    }


this.draw = function(ctx) {
 for (var x = 0; x <= 31; x++){
        for ( var y = 0; y <= 31; y++){
            ctx.drawImage(mapTiles[map[x][y]],x*tilesize, y*tilesize);

    }
}
};

}

Have any of you ever encountered this error?

and how would i correct the issue, thanks tom


Solution

  • Forget about canvas and everything else and look at the map array and the code that uses it. Let's rip out the canvas code and examine the array accesses with some console.log() calls:

    map = [
        [1,1,1,1,1,1,1,1,1,1],
        [2,2,2,2,2,2,2,2,2,2]
    ];
    
    console.log( map.length );
    console.log( map[0].length );
    
    for (var x = 0; x <= 31; x++){
        for ( var y = 0; y <= 31; y++){
            console.log( x, y, map[x], map[x] && map[x][y] );
        }
    }
    

    Do you see the problem? You may be able to spot it by thinking about what those console.log() calls will print. If not, paste that code into the Chrome developer console and see what it does. (BTW, where the last argument has map[x] && map[x][y], that's essentially the same as map[x][y] but it protects the code from crashing when map[x] is undefined as you will see happen in the log.)

    Now that we now that map[x][y] is undefined some of the time, go back to the drawImage() call, which uses this as the image argument:

    mapTiles[ map[x][y] ]
    

    When map[x][y] is undefined, what will that expression evaluate to?