javascript - HTML5 Tiled Map 将所有图 block 保存为图 block 集中的最后一个图 block

标签 javascript html html5-canvas loading tiled

我一直在研究 HTML5 游戏引擎,并且我有一个平铺 map 加载器可以完美运行几个月。从那以后,我重写了我的引擎,除了平铺 map 加载器之外,一切都按预期工作。 map 加载,然后加载瓦片集,然后将瓦片集拆分为瓦片集中的瓦片,并将它们保存到列表中。

map 现在是这样渲染的:

map rendering test

它应该是一片草地,但它是图 block 集中的最后一个图 block 。我检查了 map 数据以确保它是正确的,然后检查了列表中的每个图 block ,发现所有 256 个图 block 都是上面显示的图 block 。我试过多次重写它并返回到我的旧 map 系统,它总是有相同的结果。

这是我加载 json 数据的代码:

static loadJSON(url, success){
    var request = new XMLHttpRequest();
    request.overrideMimeType("application/json");
    request.onreadystatechange = function(){
        if(request.readyState == 4 && request.status == 200){
            success(request.responseText);
        }
    };
    request.open("GET", url, true);
    request.send();
}

这是我的平铺 map 加载代码:

export class TiledMap{

constructor(){
    this.tilesets = [];
    this.tiles = [];
    this.tiles.push(null);
    this.data = null;
    this.image = null;
    this.x = 0;
    this.y = 0;
    this.loadSuccess = null;
    this.totalTiles = 0;
    this.folder = null;
}

//load the tiled map in json format
load(url,success){
    var self = this;
    this.loadSuccess = success;
    FILE.loadJSON(url,function(response){
        self.data = JSON.parse(response);
        self.folder = url.substring(0,url.lastIndexOf("/"));
        self.loadTilesets();
    });
}

//load the tilesets for the tiled map
loadTilesets(){
    var self = this;
    var successCount = 0;
    var errorCount = 0;
    for(let ts=0; ts<this.data.tilesets.length; ts++){
        var image = new Image();
        image.addEventListener("load",function(){
            successCount++
            if(successCount + errorCount == self.data.tilesets.length){
                self.seperateTiles();
            }
        }, {once:true});
        image.addEventListener("error",function(){
            errorCount++;
            console.error("Failed to load: " + self.data.tilesets[ts].image);
        }, {once:true});

        if(this.folder.length >= 1){
            this.folder += "/";
        }
        image.src = this.folder + this.data.tilesets[ts].image;
        this.tilesets.push(image);
    }
}

//seperate the tiles in the tileset
seperateTiles(){
    var self = this;
    for(let ts=0; ts<this.tilesets.length; ts++){
        var nTilesX = this.tilesets[ts].width / this.data.tilewidth;
        var nTilesY = this.tilesets[ts].height / this.data.tileheight;
        this.totalTiles = nTilesX * nTilesY;

        for(let ty=0; ty<nTilesY; ty++){
            for(let tx=0; tx<nTilesX; tx++){
                var tileCanvas = document.createElement("canvas");
                var tileContext = tileCanvas.getContext("2d");

                tileCanvas.width = this.data.tilewidth;
                tileCanvas.height = this.data.tileheight;

                var x = tx * this.data.tilewidth;
                var y = ty * this.data.tileheight;
                tileContext.drawImage(this.tilesets[ts],-x,-y);

                var tile = new Image();
                tile.addEventListener("load",function(){
                    self.tiles.push(tile);
                    if(self.totalTiles == (self.tiles.length-1)){
                        self.preDrawMap();
                    }
                },{once:true});
                tile.addEventListener("error",function(){
                    console.error("Failed to seperate tiles on tileset: " + self.tilesets[ts]);
                }, {once: true});
                tile.src = tileCanvas.toDataURL("image/png");
            }
        }
    }
}

//draw the tiled map on to a canvas
preDrawMap(){
    var mapCanvas = document.createElement("canvas");
    mapCanvas.width = this.data.width * this.data.tilewidth;
    mapCanvas.height = this.data.height * this.data.tileheight;

    var mapContext = mapCanvas.getContext("2d");
    for(let l=0; l<this.data.layers.length; l++){
        var x = 0;
        var y = 0;

        if(this.data.layers[l].type == "tilelayer"){
            for(let d=0; d<this.data.layers[l].data.length; d++){
               if(d % this.data.width == 0 && d != 0){
                   y += this.data.tileheight;
                   x = 0;
               }

               if(this.data.layers[l].data[d] != 0){
                   var tile = this.tiles[this.data.layers[l].data[d]];
                   mapContext.drawImage(tile,x,y);
               }
               x += this.data.tilewidth;
            }
        }
    }
    var self = this;
    this.image = new Image();
    this.image.addEventListener("load",function(){
        self.loadSuccess();
    }, {once:true});
    this.image.addEventListener("error",function(){
        console.error("Failed to convert map canvas to image");
    }, {once:true});
    this.image.src = mapCanvas.toDataURL("image/png");
}

//render the tiled map
render(){
    core.ctx.drawImage(this.image,this.x,this.y);
}

//set the position of the map
setPosition(x,y){
    this.x = x;
    this.y = y;
}


}

我似乎找不到它只保存最后一个图 block 的原因,是不是我遗漏了什么?

最佳答案

再玩了几个小时后,我发现更改我的代码的部分使用的是 var 而不是 let,我不确定那是怎么回事导致我的问题但在更改之后

var x = tx * this.data.tilewidth;
var y = ty * this.data.tileheight;
tileContext.drawImage(this.tilesets[ts],-x,-y);

var tile = new Image();

进入

let x = tx * this.data.tilewidth;
let y = ty * this.data.tileheight;
tileContext.drawImage(this.tilesets[ts],-x,-y);

let tile = new Image();

一切都很完美,这是在 for 循环中运行的,所以这些变量的范围是否有冲突?

关于javascript - HTML5 Tiled Map 将所有图 block 保存为图 block 集中的最后一个图 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52693095/

相关文章:

javascript - jQuery li 颜色变化

javascript - 如何获取select2 :unselect的值

javascript - Nodemailer Node Express POST 问题 Github 页面 Gmail

javascript - 返回到 Ionic 2 中的其他页面时,菜单切换被禁用

javascript - 让 Canvas 上的球慢慢向鼠标移动

javascript - 选择单选按钮并显示正确

javascript - 在sugar.js中,如何通过过滤(不完全匹配)找到数组的 "last index of"?

javascript - 如何使用 span 元素将多行插入网页?

html - HTML 5 中的视频捕获

javascript - 在下面的代码中,在 Fabric.js 中单击鼠标时 Canvas 层消失,并且 Firefox 在创建 Canvas 到图像时停止响应?