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

