You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

mapCanvas绘制失败求助:drawImage调用无效,多次修改仍未解决

mapCanvas无法绘制,drawImage调用无效问题排查

mapCanvas无法完成绘制,this.canvas.getContext("2d").drawImage调用不生效。canvas已成功创建,mapData中的数值能正常打印,但就是画不出内容。先后修改过两段代码,问题仍未解决。

第一段尝试代码

const mapData = [
    [0, 1, 2],
    [3, 4, 5],
];

function Sprite(name, width, height, type, Col_Sprite,) {
    this.name = "Spr_" + name;
    this.ID = "Spr_" + name;
    this.Sprite =  new Image();
    this.type = type;
    this.width = width;
    this.height = height;
    this.Canvas = document.createElement("canvas");
    this.CanvasContext = this.Canvas.getContext("2d");  
    
    this.Canvas.id = this.ID;
    this.Canvas.width = this.width;
    this.Canvas.height = this.height;
    let self = this;
    
    if (this.type == "sprite") {
        this.Sprite.onload = function() {
            self.CanvasContext.drawImage(self.Sprite, 0, 0, self.width, self.height);
        };  
        this.Sprite.src = Col_Sprite;
    }else if (this.type == "color") {
        this.color = Col_Sprite
        this.CanvasContext.fillStyle = this.color;
        this.CanvasContext.fillRect(0, 0, this.width, this.height);
    }
}
function Tilesheet (name, sprite, tilewidth, tileheight) {
    this.name = name;
    this.sprite = sprite;
    this.tilewidth = tilewidth;
    this.tileheight = tileheight;
    this.tileIndex = [];
    
    for (let y = 0; y < this.sprite.height; y += this.tileheight) {
        for (let x = 0; x < this.sprite.width; x += this.tilewidth) {
            const tile = [x, y];
            tile.width = this.tilewidth;
            tile.height = this.tileheight;
            this.tileIndex.push(tile);
        }
    }
    console.log(this.tileIndex);
    
}
function Map(name, tilesheet, mapdata, canvas) {
    this.name = name;
    this.id = "map_" + name
    this.mapdata = mapdata;
    this.tilesheet = tilesheet;
    this.numofrow = mapdata.length;
    this.numofcolumn = mapdata[0].length;
    this.canvas = canvas;
    this.canvas.id = this.id;
    this.tileImg = this.tilesheet.sprite
    this.tilewidth = this.tilesheet.tilewidth;
    this.tileheight = this.tilesheet.tileheight;
    this.tileindex = this.tilesheet.tileIndex;
    this.canvascontext = this.canvas.getContext("2d");
    this.canvascontext.clearRect(0, 0, this.canvas.width, this.canvas.height);
    for (let x = 0; x < this.numofrow; x++) {
        for (let y = 0; y < this.numofcolumn; y++) {
            this.canvascontext.clearRect(0, 0, this.canvas.width, this.canvas.height);
            this.tileId = this.mapdata[x][y];
            this.tileX = x * this.tilewidth;
            this.tileY = y * this.tileheight;
            this.tileData = this.tileindex[this.tileId]; // Get the tile data
            if (this.tileData) {
                this.canvas.getContext("2d").drawImage (
                    this.tileImg.Canvas, //image
                    this.tileData[0] ,  //starting x of image
                    this.tileData[1],  //y
                    this.tilewidth, // ending x of the sprite
                    this.tileheight, // same thing befor just wil y
                    this.tileX, //where the sprite will be draw on the canvas x
                    this.tileY, //same thing befor just with y
                    this.tilewidth, //sprite width
                    this.tileheight //sprite height
                );
            }
            
        }
    }
}
const Objects = {
  Sprites: {},
  Tilesheets: {},
  Collisions: {},
  Players: {},
  Entities: {},
  Obstacles: {},
  Maps: {},
  Sounds: {},
};

const mySprite = new Sprite("PlayerSprite", 300, 300, "sprite", "Images/Hole.png");
Objects.Sprites[mySprite.name] = mySprite;

const myTilesheet = new Tilesheet("test", mySprite, 100, 100); // Adjust tile width and height
Objects.Tilesheets[myTilesheet.name] = myTilesheet;

const mapCanvas = document.createElement("canvas");
mapCanvas.width = myTilesheet.tilewidth * mapData[0].length;
mapCanvas.height = myTilesheet.tileheight * mapData.length;
mapCanvas.style.backgroundColor = "lightgray"; // Add this line to set a background color
document.body.appendChild(mapCanvas);

const myMap = new Map("testMap", myTilesheet, mapData, mapCanvas);
Objects.Maps[myMap.name] = myMap;

document.body.appendChild(mySprite.Canvas);

第二段修改后的代码

const mapData = [
    [0, 1, 2],
    [3, 4, 5],
];

function Sprite(name, width, height, type, Col_Sprite) {
    this.name = "Spr_" + name;
    this.ID = "Spr_" + name;
    this.Sprite =  new Image();
    this.type = type;
    this.width = width;
    this.height = height;
    if (this.type == "sprite") {
        this.Sprite.src = Col_Sprite;
    }else if (this.type == "color") {
        this.color = Col_Sprite
    }
}
function Tilesheet (name, sprite, tilewidth, tileheight) {
    this.name = name;
    self = this;
    sprite.onload = function() {
        
    };
    this.sprite = sprite;
    this.tilewidth = tilewidth;
    this.tileheight = tileheight;
    this.tileIndex = [];
    
    for (let y = 0; y < this.sprite.height; y += this.tileheight) {
        for (let x = 0; x < this.sprite.width; x += this.tilewidth) {
            const tile = [x, y];
            tile.width = this.tilewidth;
            tile.height = this.tileheight;
            this.tileIndex.push(tile);
        }
    }
    console.log(this.tileIndex);
    
}
function Map(name, mapdata) {
    this.name = name;
    this.id = "map_" + name
    this.mapdata = mapdata;
    this.numofrow = mapdata.length;
    this.numofcolumn = mapdata[0].length;
}
function DrawMap(map, canvasctx, tilesheet) {
    let mapdata = map.mapdata;
    let numofcolumn = map.numofcolumn;
    let numofrow = map.numofrow;
    let tilewidth = map.tilewidth;
    let tileheight = map.tileheight;
    let tileindex = tilesheet.tileIndex;
    console.log(tileindex);
    let tileImg = tilesheet.sprite;
    tileImg.Sprite.onload = function() {
        for (let x = 0; x < numofrow; x++) {
            for (let y = 0; y < numofcolumn; y++) {
                let tileId = mapdata[x][</think_never_used_51bce0c785ca2f68081bfa7d91973934>y];
                console.log(tileId);
                let tileX = x * tilewidth;
                let tileY = y * tileheight;
                let tileData = tileindex[2]; // Get the tile data
                canvasctx.drawImage (
                    tileImg.Sprite, //image
                    tileData[0],  //starting x of image
                    tileData[1],  //y
                    tilewidth, // ending x of the sprite
                    tileheight, // same thing befor just wil y
                    tileX, //where the sprite will be draw on the canvas x
                    tileY, //same thing befor just with y
                    tilewidth, //sprite width
                    tileheight //sprite height
                    );
                
                
            }
        }
    }
}
const Objects = {
  Sprites: {},
  Tilesheets: {},
  Collisions: {},
  Players: {},
  Entities: {},
  Obstacles: {},
  Maps: {},
  Sounds: {},
}
const mySprite = new Sprite("PlayerSprite", 300, 300, "sprite", "Images/Hole.png");
Objects.Sprites[mySprite.name] = mySprite;

const myTilesheet = new Tilesheet("test", mySprite, 100, 100); // Adjust tile width and height
Objects.Tilesheets[myTilesheet.name] = myTilesheet;

const mapCanvas = document.createElement("canvas");
const mapContext = mapCanvas.getContext("2d");
document.body.appendChild(mapCanvas);
mapCanvas.width = myTilesheet.tilewidth * mapData[0].length;
mapCanvas.height = myTilesheet.tileheight * mapData.length;

const myMap = new Map("testMap", mapData, mapContext, mapCanvas);
Objects.Maps[myMap.name] = myMap;
DrawMap(myMap, mapContext, myTilesheet);

核心问题原因

  1. 图片加载时机错误:两段代码都在图片未加载完成时执行了绘制逻辑。第一段中Map构造函数直接运行,此时Sprite的图片还没加载,tileImg.Canvas上没有内容;第二段中Tilesheet初始化时遍历sprite.height,但图片未加载导致height为0,生成的tileIndex是空数组,后续drawImage无有效数据。
  2. 第一段代码额外问题:Map构造函数的嵌套循环中,每次循环都调用clearRect(0,0,canvas.width,canvas.height),会清空之前所有绘制内容,最终无法保留完整地图。
  3. 第二段代码额外问题:Map构造函数未接收并保存tilewidth和tileheight,导致DrawMap中tilewidth、tileheight为undefined,计算出的绘制坐标无效;同时硬编码tileData = tileindex[2],忽略了tileId的作用,且tileindex为空时会导致drawImage参数错误。

内容的提问来源于stack exchange,提问作者Dom C

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 12:57:31