var TMXLoader = function (mapName) { var self = {}; self.mapName = mapName; self.tileset = { firstGID: 0, isTsx: false, tsxSource: "", source: "", tileWidth: 0, tileHeight: 0, tileCount: 0, width: 0, height: 0, img: null, }; self.tile = { id: 0, index: 0, }; self.tiles = [self.tile]; self.layer = { id: 0, name: "", tiles: [], tilesStr: "" }; self.layers = { layer: [self.layer] }; self.map = { width: 0, height: 0, layers: [self.layer], tilesets: [self.tileset], }; self.xml = new XMLHttpRequest(); self.xml2 = new XMLHttpRequest(); self.parser = new DOMParser(); self.loadMap = function () { self.xml.open('GET', "/client/assets/maps/" + mapName + ".tmx"); self.xml.onload = function () { var dom = self.parser.parseFromString(self.xml.response, "text/xml"); self.map.width = dom.documentElement.getAttribute('width'); self.map.height = dom.documentElement.getAttribute('height'); // tilesets for (var i = 0; i < dom.documentElement.getElementsByTagName('tileset').length; i++) { var tileset = {}; tileset.firstGID = parseInt(dom.documentElement.getElementsByTagName('tileset').item(i).getAttribute('firstgid')); if (!dom.documentElement.getElementsByTagName('tileset').item(i).hasAttribute('source')) { tileset.source = dom.documentElement.getElementsByTagName('tileset').item(i).getElementsByTagName('image')[0].getAttribute('source').replace("../", "/client/assets/"); tileset.width = parseInt(dom.documentElement.getElementsByTagName('tileset').item(i).getElementsByTagName('image')[0].getAttribute('width')); tileset.height = parseInt(dom.documentElement.getElementsByTagName('tileset').item(i).getElementsByTagName('image')[0].getAttribute('height')); tileset.tileWidth = parseInt(dom.documentElement.getElementsByTagName('tileset').item(i).getAttribute('tilewidth')); tileset.tileHeight = parseInt(dom.documentElement.getElementsByTagName('tileset').item(i).getAttribute('tileheight')); tileset.tileCount = parseInt(dom.documentElement.getElementsByTagName('tileset').item(i).getAttribute('tilecount')); tileset.img = self.addImg(tileset.source); self.map.tilesets[i] = tileset; } else { tileset.isTsx = true; tileset.tsxSource = dom.documentElement.getElementsByTagName('tileset').item(i).getAttribute('source').replace("../", "/client/assets/"); self.map.tilesets[i] = tileset; self.loadTSX(); } } // layers for (var i = 0; i < dom.documentElement.getElementsByTagName('layer').length; i++) { var layer = {}; layer.name = dom.documentElement.getElementsByTagName('layer').item(i).getAttribute('name'); layer.tilesStr = dom.documentElement.getElementsByTagName('layer').item(i).getElementsByTagName('data')[0].innerHTML; layer.id = parseInt(dom.documentElement.getElementsByTagName('layer').item(i).getAttribute('id')); layer.tiles = []; self.map.layers[i] = layer; } self.parseLayer(); } self.xml.send(); } self.addImg = function (source) { var TSet = {}; TSet.new = new Image(); TSet.new.src = source; return TSet.new; } self.loadTSX = function () { for (var i = 0; i < self.map.tilesets.length; i++) { if (self.map.tilesets[i].isTsx && self.map.tilesets[i].tsxSource != null) { self.xml2.open('GET', self.map.tilesets[i].tsxSource); var tileset = self.map.tilesets[i]; self.xml2.onload = function () { var dom2 = self.parser.parseFromString(self.xml2.response, "text/xml"); tileset.source = "/client/assets/tilesets/" + dom2.documentElement.getElementsByTagName('image')[0].getAttribute('source') tileset.width = parseInt(dom2.documentElement.getElementsByTagName('image')[0].getAttribute('width')); tileset.height = parseInt(dom2.documentElement.getElementsByTagName('image')[0].getAttribute('height')); tileset.tileWidth = parseInt(dom2.documentElement.getAttribute('tilewidth')); tileset.tileHeight = parseInt(dom2.documentElement.getAttribute('tileheight')); tileset.tileCount = parseInt(dom2.documentElement.getAttribute('tilecount')); tileset.img = self.addImg(tileset.source); tileset.isTsx = false; // prevents from reloading } self.xml2.send(); } } } self.getTileAt = function (x, y, layer) { return self.map.layers[layer].tiles[x][y]; } self.setTileAt = function (x, y, layer, id, index) { self.map.layers[layer].tiles[x][y] = { id: id, index: index }; } self.parseLayer = function () { for (var i = 0; i < self.map.layers.length; i++) { for (var mapX = 0; mapX < self.map.height; mapX++) { self.map.layers[i].tiles[mapX] = []; for (var mapY = 0; mapY < self.map.width; mapY++) { var tileId = parseInt(self.map.layers[i].tilesStr.replace('\n', '').split(',')[mapY * self.map.width + mapX]); self.setTileAt(mapX, mapY, i, tileId, mapX * self.map.width + mapY) } } self.map.layers[i].tilesStr = ""; } } self.getCollision = function (direction) { // TODO } self.drawLayer = function (canvas, layerName, xOffset, yOffset) { for (var layerId = 0; layerId < self.map.layers.length; layerId++) { var t = 0; if (self.map.layers[layerId].name.toLowerCase().includes(layerName)) { for (var mapY = 0; mapY < self.map.height; mapY++) { for (var mapX = 0; mapX < self.map.width; mapX++) { var gid = self.getTileAt(mapX, mapY, layerId).id; for (var sets = 0; sets < self.map.tilesets.length; sets++) { if (gid <= (self.map.tilesets[sets].firstGID + self.map.tilesets[sets].tileCount) && gid >= self.map.tilesets[sets].firstGID) t = sets; } var tsGid = gid - self.map.tilesets[t].firstGID; if (self.map.tilesets[t].img == null && tsGid == 0) continue; var tilesinrow = self.map.tilesets[t].width / self.map.tilesets[t].tileWidth; var y = Math.floor(tsGid / tilesinrow); var x = tsGid % (tilesinrow); canvas.drawImage(self.map.tilesets[t].img, x * self.map.tilesets[t].tileWidth, y * self.map.tilesets[t].tileHeight, self.map.tilesets[t].tileWidth, self.map.tilesets[t].tileHeight, mapX * self.map.tilesets[t].tileWidth + xOffset, mapY * self.map.tilesets[t].tileWidth + yOffset, self.map.tilesets[t].tileWidth, self.map.tilesets[t].tileHeight) } } } } } self.loadMap(); return self; }