1 |
|
2 |
|
3 | var clone = require("./clone");
|
4 | var path = require("path");
|
5 | var setOrAddComponent = require("./set-or-add-component");
|
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 | module.exports = function importTilemap(file, entities, images) {
|
32 |
|
33 | var imageComponents = tilesetsToImageComponents(file.tilesets, images);
|
34 |
|
35 | for (var z = 0; z < file.layers.length; z++) {
|
36 | var layer = file.layers[z];
|
37 | if (layer.type == "tilelayer") {
|
38 | makeTiles(file, z, entities, imageComponents);
|
39 | } else if (layer.type == "objectgroup") {
|
40 | makeObjects(file, z, entities, imageComponents);
|
41 | }
|
42 | }
|
43 |
|
44 |
|
45 | var container = entities.create();
|
46 | entities.setComponent(container, "name", "container");
|
47 | entities.setComponent(container, "container", true);
|
48 | entities.addComponent(container, "position");
|
49 | var size = entities.addComponent(container, "size");
|
50 | size.width = file.width * file.tilewidth;
|
51 | size.height = file.height * file.tileheight;
|
52 | };
|
53 |
|
54 | function tilesetsToImageComponents(tilesets, images) {
|
55 | var imageComponents = [];
|
56 | for (var i = 0; i < tilesets.length; i++) {
|
57 | if (tilesets[i].image) {
|
58 | tilesetToImage(tilesets[i], imageComponents);
|
59 | } else {
|
60 | collectionOfImagesToImage(tilesets[i], imageComponents, images);
|
61 | }
|
62 | }
|
63 | return imageComponents;
|
64 | }
|
65 |
|
66 | function tilesetToImage(tileset, imageComponents) {
|
67 | var i = tileset.firstgid;
|
68 | var j = 0;
|
69 | for (var y = tileset.margin; y < tileset.imageheight - tileset.margin; y += tileset.tileheight + tileset.spacing) {
|
70 | for (var x = tileset.margin; x < tileset.imagewidth - tileset.margin; x += tileset.tilewidth + tileset.spacing) {
|
71 | var tileProps = (tileset.tileproperties || {})[j];
|
72 | var props = merge(clone(tileset.properties || {}), tileProps);
|
73 | imageComponents[i] = {
|
74 | image: {
|
75 | name: path.basename(tileset.image),
|
76 | sourceX: x,
|
77 | sourceY: y,
|
78 | sourceWidth: tileset.tilewidth,
|
79 | sourceHeight: tileset.tileheight,
|
80 | destinationWidth: tileset.tilewidth,
|
81 | destinationHeight: tileset.tileheight
|
82 | },
|
83 | properties: props
|
84 | };
|
85 | i++;
|
86 | j++;
|
87 | }
|
88 | }
|
89 | }
|
90 |
|
91 | function collectionOfImagesToImage(tileset, imageComponents, images) {
|
92 | var keys = Object.keys(tileset.tiles).map(function(id) { return parseInt(id); });
|
93 | for (var k = 0; k < keys.length; k++) {
|
94 | var key = keys[k];
|
95 | var tileProps = (tileset.tileproperties || {})[key];
|
96 | var props = merge(clone(tileset.properties || {}), tileProps);
|
97 | var name = path.basename(tileset.tiles[key].image);
|
98 | var image = images.get(name);
|
99 | imageComponents[tileset.firstgid + key] = {
|
100 | image: {
|
101 | name: name,
|
102 | sourceX: 0,
|
103 | sourceY: 0,
|
104 | sourceWidth: image.width,
|
105 | sourceHeight: image.height,
|
106 | destinationWidth: image.width,
|
107 | destinationHeight: image.height
|
108 | },
|
109 | properties: props
|
110 | };
|
111 | }
|
112 | }
|
113 |
|
114 | function merge(dest, src) {
|
115 | if (src === undefined) {
|
116 | return dest;
|
117 | }
|
118 | var keys = Object.keys(src);
|
119 | for (var i = 0; i < keys.length; i++) {
|
120 | dest[keys[i]] = src[keys[i]];
|
121 | }
|
122 | return dest;
|
123 | }
|
124 |
|
125 | function makeTiles(file, z, entities, imageComponents) {
|
126 | var layer = file.layers[z];
|
127 | for (var i = 0; i < layer.data.length; i++) {
|
128 | var tile = layer.data[i];
|
129 | if (tile === 0) {
|
130 | continue;
|
131 | }
|
132 | var image = clone(imageComponents[tile].image);
|
133 | var gridX = i % file.width;
|
134 | var gridY = Math.floor(i / file.width);
|
135 | var x = gridX * file.tilewidth;
|
136 | var y = gridY * file.tileheight - image.sourceHeight;
|
137 | var entity = makeTile({ x: x, y: y, z: z }, { x: gridX, y: gridY, z: z }, image, entities);
|
138 | setComponentsFromProperties(entity, imageComponents[tile].properties, entities);
|
139 | setComponentsFromProperties(entity, layer.properties, entities);
|
140 | }
|
141 | }
|
142 |
|
143 | function makeTile(position, grid, image, entities) {
|
144 | var tile = entities.create();
|
145 | entities.setComponent(tile, "name", "tile");
|
146 | entities.setComponent(tile, "tile", true);
|
147 |
|
148 | var pos = entities.addComponent(tile, "position");
|
149 | pos.x = position.x;
|
150 | pos.y = position.y;
|
151 | pos.z = position.z;
|
152 |
|
153 | var g = entities.addComponent(tile, "grid");
|
154 | g.x = grid.x;
|
155 | g.y = grid.y;
|
156 | g.z = grid.z;
|
157 |
|
158 | addImage(entities, tile, image);
|
159 |
|
160 | var size = entities.addComponent(tile, "size");
|
161 | size.width = image.sourceWidth;
|
162 | size.height = image.sourceHeight;
|
163 |
|
164 | return tile;
|
165 | }
|
166 |
|
167 | function addImage(entities, id, image) {
|
168 | var img = entities.addComponent(id, "image");
|
169 | img.name = image.name;
|
170 | img.sourceX = image.sourceX;
|
171 | img.sourceY = image.sourceY;
|
172 | img.sourceWidth = image.sourceWidth;
|
173 | img.sourceHeight = image.sourceHeight;
|
174 | img.destinationWidth = image.destinationWidth;
|
175 | img.destinationHeight = image.destinationHeight;
|
176 | }
|
177 |
|
178 | function makeObjects(file, z, entities, imageComponents) {
|
179 | var layer = file.layers[z];
|
180 | for (var i = 0; i < layer.objects.length; i++) {
|
181 | var object = layer.objects[i];
|
182 | makeObject(layer, object, z, entities, imageComponents);
|
183 | }
|
184 | }
|
185 |
|
186 | function makeObject(layer, object, z, entities, imageComponents) {
|
187 | var entity = entities.create();
|
188 | entities.setComponent(entity, "name", object.name);
|
189 | entities.setComponent(entity, "type", object.type);
|
190 |
|
191 | var position = entities.addComponent(entity, "position");
|
192 | position.x = object.x;
|
193 | position.y = object.y;
|
194 | position.z = z;
|
195 |
|
196 | var size = entities.addComponent(entity, "size");
|
197 | size.width = object.width;
|
198 | size.height = object.height;
|
199 |
|
200 | if (object.gid !== undefined) {
|
201 | addImage(entities, entity, imageComponents[object.gid].image);
|
202 | setComponentsFromProperties(entity, imageComponents[object.gid].properties, entities);
|
203 | }
|
204 | setComponentsFromProperties(entity, layer.properties, entities);
|
205 | setComponentsFromProperties(entity, object.properties, entities);
|
206 | }
|
207 |
|
208 | function setComponentsFromProperties(entity, properties, entities) {
|
209 | if (!properties) {
|
210 | return;
|
211 | }
|
212 | Object.keys(properties).forEach(function(key) {
|
213 | var value = parsePropertyValue(properties[key]);
|
214 | setOrAddComponent(entities, entity, key, value);
|
215 | });
|
216 | }
|
217 |
|
218 | function parsePropertyValue(val) {
|
219 | try {
|
220 | return JSON.parse(val);
|
221 | } catch (e) {
|
222 | if (e instanceof SyntaxError) {
|
223 | return val;
|
224 | } else {
|
225 | throw e;
|
226 | }
|
227 | }
|
228 | }
|