summaryrefslogtreecommitdiff
path: root/client/tmxloader.js
blob: 2b3ff0cf8e5b78c79df21b10838ab8eebd4ff8f8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
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(){
            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);
                tileset = self.map.tilesets[i];
                self.xml2.onload = function(){
                    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.getTileIdAt = function(x, y, layer){
        return self.map.layers[layer].tiles[y][x];
    }

    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++){
                    tileId = parseInt(self.map.layers[i].tilesStr.replace('\n','').split(',')[mapY * self.map.width + mapX]);
                    self.map.layers[i].tiles[mapX][mapY] = {id : tileId,
                    index : mapX * self.map.width + mapY };
                }
            }
            self.map.layers[i].tilesStr = "";
        }
    }

    self.getCollision = function(direction){
        // TODO
    }

    self.drawLayer = function(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.map.layers[layerId].tiles[mapX][mapY].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;
                        }
        
                        tsGid = gid - self.map.tilesets[t].firstGID;
        
                        if(self.map.tilesets[t].img == null && tsGid == 0)
                            continue;
        
                        tilesinrow = self.map.tilesets[t].width / self.map.tilesets[t].tileWidth;
        
                        y= Math.floor(tsGid / tilesinrow);
                        x= tsGid % (tilesinrow);
        
                        ctx.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;
}