简体   繁体   中英

Tiled Map not rendering in HTML5

The past few weeks I have been trying to get this code to work with my engine.

so far I have the map loading and the data is all there, the tileset is loaded and seperated into tiles.

my problem is though is that when I try to render the map in my game loop i get the a type error

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

I dont understand why im getting this error because i am drawing each tile to canvas element and making it into an image

here is my code

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

When using console.log to see what the tile was, it returned undefined, to fix this I only rendered the map after I knew the tile set has finished loading, and has been split into tiles. after doing that everything worked just as expected, and it also fixed a bug in the seperateTiles() method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM