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