首页 > 解决方案 > 平铺地图未在 HTML5 中呈现

问题描述

在过去的几周里,我一直试图让这段代码与我的引擎一起工作。

到目前为止,我已经加载了地图并且数据都在那里,瓦片集被加载并分离成瓦片。

我的问题是,当我尝试在我的游戏循环中渲染地图时,我得到了一个类型错误

未捕获的类型错误:无法在“CanvasRenderingContext2D”上执行“drawImage”:提供的值不是类型“(CSSImageValue 或 HTMLImageElement 或 SVGImageElement 或 HTMLVideoElement 或 HTMLCanvasElement 或 ImageBitmap 或 OffscreenCanvas)”

我不明白为什么会出现此错误,因为我将每个图块绘制到画布元素并将其制成图像

这是我的代码

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

标签: javascripthtmlhtml5-canvastiletiled

解决方案


当使用 console.log 查看瓦片是什么时,它返回未定义,为了解决这个问题,我只在知道瓦片集已完成加载并已拆分为瓦片后才渲染地图。在这样做之后,一切都按预期工作,并且它还修复了 seperateTiles() 方法中的一个错误。


推荐阅读