HTML5 中未呈现平铺地图
Tiled Map not rendering in HTML5
过去几周我一直在努力让 this 代码与我的引擎一起工作。
到目前为止我已经加载了地图并且数据都在那里,加载了 tileset 并分成了图块。
我的问题是当我尝试在我的游戏循环中渲染地图时出现类型错误
Uncaught TypeError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type '(CSSImageValue or HTMLImageElement or SVGImageElement or HTMLVideoElement or HTMLCanvasElement or ImageBitmap or OffscreenCanvas)'
我不明白为什么我会收到此错误,因为我正在将每个图块绘制到 canvas 元素并将其制作成图像
这是我的代码
export class TiledMap{
constructor(){
this.tilesets = [];
this.tiles = [];
this.map = null;
}
load(jsonFile){
let self = this;
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
self.parse(xhr.responseText);
}
}
xhr.open("GET",jsonFile,true);
xhr.send();
}
parse(json){
this.map = JSON.parse(json);
this.loadTilesetImages();
}
loadTilesetImages(){
let successCount = 0;
let errorCount = 0;
let self = this;
for(let ts=0; ts<this.map.tilesets.length; ts++){
let image = new Image();
image.addEventListener("load",function(){
successCount++;
if(successCount + errorCount == self.map.tilesets.length){
self.seperateTiles();
}
});
image.addEventListener("error",function(){
errorCount++;
alert("error loading: " + self.map.tilesets[ts].image);
});
image.src = this.map.tilesets[ts].image;
this.tilesets.push(image);
}
}
seperateTiles(){
let successCount = 0;
for(let ts=0; ts<this.tilesets.length; ts++){
let nTilesX = this.tilesets[ts].width / this.map.tilewidth;
let nTilesY = this.tilesets[ts].height / this.map.tileheight;
for(let ty=0; ty<nTilesY; ty++){
for(let tx=0; tx<nTilesX; tx++){
let tileCanvas = document.createElement("canvas");
let tileContext = tileCanvas.getContext("2d");
tileCanvas.width = this.map.tilewidth;
tileCanvas.height = this.map.tileheight;
let x = tx * this.map.tilewidth;
let y = ty * this.map.tileheight;
tileContext.drawImage(this.tilesets[ts],-x,-y);
let tile = new Image();
tile.src = tileCanvas.toDataURL("image/png");
this.tiles.push(tile);
}
}
}
}
drawTiles(){
for(let l=0; l < this.map.layers.length; l++){
let x=0;
let y=0;
if(this.map.layers[l].type === "tilelayer"){
for(let d=0; d < this.map.layers[l].data.length; d++){
if(d % this.map.width == 0 && d != 0){
y += this.map.tileheight;
x = 0;
}
if(this.map.layers[l].data[d] != 0){
engine["ctx"].drawImage(this.tiles[this.map.layers[l].data[d]],x,y);
}
x += this.map.tilewidth;
}
}
}
}
当使用 console.log 查看图块是什么时,它返回未定义,为了解决这个问题,我只在知道图块集已完成加载并已拆分为图块后才渲染地图。这样做之后一切都按预期工作,它还修复了 seperateTiles() 方法中的错误。
过去几周我一直在努力让 this 代码与我的引擎一起工作。
到目前为止我已经加载了地图并且数据都在那里,加载了 tileset 并分成了图块。
我的问题是当我尝试在我的游戏循环中渲染地图时出现类型错误
Uncaught TypeError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type '(CSSImageValue or HTMLImageElement or SVGImageElement or HTMLVideoElement or HTMLCanvasElement or ImageBitmap or OffscreenCanvas)'
我不明白为什么我会收到此错误,因为我正在将每个图块绘制到 canvas 元素并将其制作成图像
这是我的代码
export class TiledMap{
constructor(){
this.tilesets = [];
this.tiles = [];
this.map = null;
}
load(jsonFile){
let self = this;
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
self.parse(xhr.responseText);
}
}
xhr.open("GET",jsonFile,true);
xhr.send();
}
parse(json){
this.map = JSON.parse(json);
this.loadTilesetImages();
}
loadTilesetImages(){
let successCount = 0;
let errorCount = 0;
let self = this;
for(let ts=0; ts<this.map.tilesets.length; ts++){
let image = new Image();
image.addEventListener("load",function(){
successCount++;
if(successCount + errorCount == self.map.tilesets.length){
self.seperateTiles();
}
});
image.addEventListener("error",function(){
errorCount++;
alert("error loading: " + self.map.tilesets[ts].image);
});
image.src = this.map.tilesets[ts].image;
this.tilesets.push(image);
}
}
seperateTiles(){
let successCount = 0;
for(let ts=0; ts<this.tilesets.length; ts++){
let nTilesX = this.tilesets[ts].width / this.map.tilewidth;
let nTilesY = this.tilesets[ts].height / this.map.tileheight;
for(let ty=0; ty<nTilesY; ty++){
for(let tx=0; tx<nTilesX; tx++){
let tileCanvas = document.createElement("canvas");
let tileContext = tileCanvas.getContext("2d");
tileCanvas.width = this.map.tilewidth;
tileCanvas.height = this.map.tileheight;
let x = tx * this.map.tilewidth;
let y = ty * this.map.tileheight;
tileContext.drawImage(this.tilesets[ts],-x,-y);
let tile = new Image();
tile.src = tileCanvas.toDataURL("image/png");
this.tiles.push(tile);
}
}
}
}
drawTiles(){
for(let l=0; l < this.map.layers.length; l++){
let x=0;
let y=0;
if(this.map.layers[l].type === "tilelayer"){
for(let d=0; d < this.map.layers[l].data.length; d++){
if(d % this.map.width == 0 && d != 0){
y += this.map.tileheight;
x = 0;
}
if(this.map.layers[l].data[d] != 0){
engine["ctx"].drawImage(this.tiles[this.map.layers[l].data[d]],x,y);
}
x += this.map.tilewidth;
}
}
}
}
当使用 console.log 查看图块是什么时,它返回未定义,为了解决这个问题,我只在知道图块集已完成加载并已拆分为图块后才渲染地图。这样做之后一切都按预期工作,它还修复了 seperateTiles() 方法中的错误。