Ошибка консоли при рисовании на холст

У меня есть основной файл javascript, который пытается нарисовать тайловую карту на холсте для игры, и у меня есть включенный файл, который фактически рисует карты и т. д., но я получаю эту ошибку в firebug:

TypeError: значение не может быть преобразовано ни в один из следующих элементов: HTMLImageElement, HTMLCanvasElement, HTMLVideoElement. [Перерыв на этой ошибке]

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

основной js, который вызывает мой файл level.js, выглядит так:

$(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 
      });

и файл, в котором эта строка кода (level.js) выглядит так:

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);

    }
}
};

}

Кто-нибудь из вас когда-нибудь сталкивался с этой ошибкой?

и как мне исправить проблему, спасибо Том


person Tom Burman    schedule 26.03.2013    source источник


Ответы (1)


Забудьте о холсте и обо всем остальном и посмотрите на массив map и код, который его использует. Давайте вырвем код холста и изучим доступ к массиву с помощью некоторых console.log() вызовов:

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] );
    }
}

Ты видишь проблему? Вы можете заметить это, подумав о том, что будут печатать эти console.log() вызовы. Если нет, вставьте этот код в консоль разработчика Chrome и посмотрите, что он делает. (Кстати, где последний аргумент имеет map[x] && map[x][y], это по сути то же самое, что и map[x][y], но защищает код от сбоя, когда map[x] равно undefined, как вы увидите в журнале.)

Теперь, когда мы знаем, что map[x][y] иногда равно undefined, вернемся к вызову drawImage(), который использует это как аргумент изображения:

mapTiles[ map[x][y] ]

Когда map[x][y] равно undefined, что будет оцениваться этим выражением?

person Michael Geary    schedule 26.03.2013
comment
Сократ, ты ли это? :p Ответ: мы пытаемся получить доступ к элементам массива карт, количество которых выходит за пределы установленного нами количества элементов. (PS Привет, Майкл Гири, я уже достаточно взрослый, чтобы в колледже меня учили методу Сократа!) - person markE; 29.03.2013
comment
Платон! Как приятно тебя видеть, старый друг. Да, по-другому можно сказать: Что оценивает mapTiles[undefined]? А как наш друг Аристотель? Вы слышали о нем в последнее время? Я давно хотел спросить его, что значит переполнить стек. - person Michael Geary; 30.03.2013