parse-tmx 3.0.0 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/index.d.ts +35 -40
- package/dist/index.js +77 -91
- package/package.json +7 -10
package/README.md
CHANGED
|
@@ -67,7 +67,8 @@ const loadMap = async () => {
|
|
|
67
67
|
id: 1,
|
|
68
68
|
name: "layer name",
|
|
69
69
|
type: "layer",
|
|
70
|
-
|
|
70
|
+
// Only written when the layer is hidden in Tiled
|
|
71
|
+
visible: 0,
|
|
71
72
|
data: [0, 1, 1, 10, 10, 10, 1, 1, 0, 0, 0, 0, …],
|
|
72
73
|
// When the translateFlips parameter is enabled
|
|
73
74
|
flips: [
|
|
@@ -87,7 +88,6 @@ const loadMap = async () => {
|
|
|
87
88
|
id: 2,
|
|
88
89
|
name: "objects",
|
|
89
90
|
type: "objectgroup",
|
|
90
|
-
visible: 1,
|
|
91
91
|
objects: [{…}, {…}, {…}],
|
|
92
92
|
properties: [
|
|
93
93
|
{name: 'property1', value: 'value'},
|
package/dist/index.d.ts
CHANGED
|
@@ -215,7 +215,7 @@ export declare enum Flipped {
|
|
|
215
215
|
}
|
|
216
216
|
export declare const Flippeds: readonly Flipped[];
|
|
217
217
|
//#endregion
|
|
218
|
-
//#region src/
|
|
218
|
+
//#region src/services/checkIsExternalTileset.d.ts
|
|
219
219
|
export declare const checkIsExternalTileset: (tileset: TMXEmbeddedTilesetShared | TMXExternalTilesetShared) => tileset is TMXExternalTilesetShared;
|
|
220
220
|
//#endregion
|
|
221
221
|
//#region src/models/tmx/node/TMXNodeType.d.ts
|
|
@@ -265,6 +265,11 @@ export interface TMXPropertyNode extends TMXNode<{
|
|
|
265
265
|
_: string;
|
|
266
266
|
}
|
|
267
267
|
//#endregion
|
|
268
|
+
//#region src/models/tmx/node/TMXPropertiesElement.d.ts
|
|
269
|
+
export interface TMXPropertiesElement {
|
|
270
|
+
property: TMXPropertyNode[];
|
|
271
|
+
}
|
|
272
|
+
//#endregion
|
|
268
273
|
//#region src/models/tmx/node/TMXPropertiesNode.d.ts
|
|
269
274
|
export interface TMXPropertiesNode extends TMXNode<Record<string, never>, TMXPropertyNode> {}
|
|
270
275
|
//#endregion
|
|
@@ -278,9 +283,7 @@ export interface TMXObjectNode extends TMXNode<TMXObjectShared, TMXDataNode | TM
|
|
|
278
283
|
polygon?: TMXNode<{
|
|
279
284
|
points: string;
|
|
280
285
|
}>[];
|
|
281
|
-
properties?:
|
|
282
|
-
property: TMXPropertyNode[];
|
|
283
|
-
}[];
|
|
286
|
+
properties?: TMXPropertiesElement[];
|
|
284
287
|
text?: TMXTextNode[];
|
|
285
288
|
}
|
|
286
289
|
//#endregion
|
|
@@ -288,9 +291,7 @@ export interface TMXObjectNode extends TMXNode<TMXObjectShared, TMXDataNode | TM
|
|
|
288
291
|
export interface TMXTileNode extends TMXNode<TMXTileShared, TMXPropertiesNode> {
|
|
289
292
|
animation?: Record<string, TMXNode<number>[]>[];
|
|
290
293
|
objectgroup?: Record<string, TMXObjectNode[]>[];
|
|
291
|
-
properties?:
|
|
292
|
-
property: TMXPropertyNode[];
|
|
293
|
-
}[];
|
|
294
|
+
properties?: TMXPropertiesElement[];
|
|
294
295
|
}
|
|
295
296
|
//#endregion
|
|
296
297
|
//#region src/models/tmx/node/TMXEmbeddedTilesetNode.d.ts
|
|
@@ -298,16 +299,19 @@ export interface TMXEmbeddedTilesetNode extends TMXNode<TMXEmbeddedTilesetShared
|
|
|
298
299
|
tile?: TMXTileNode[];
|
|
299
300
|
}
|
|
300
301
|
//#endregion
|
|
301
|
-
//#region src/
|
|
302
|
+
//#region src/services/checkIsTMXEmbeddedTilesetNode.d.ts
|
|
302
303
|
export declare const checkIsTMXEmbeddedTilesetNode: (node: TMXDataNode | TMXEmbeddedTilesetNode) => node is TMXEmbeddedTilesetNode;
|
|
303
304
|
//#endregion
|
|
304
|
-
//#region src/
|
|
305
|
+
//#region src/services/cloneNodeWithType.d.ts
|
|
305
306
|
export declare const cloneNodeWithType: <TParsed>(node: BaseTMXNode<unknown>) => TParsed;
|
|
306
307
|
//#endregion
|
|
307
|
-
//#region src/
|
|
308
|
+
//#region src/services/decodeTileData.d.ts
|
|
309
|
+
export declare const decodeTileData: (nodeData: TMXDataNode | TMXEmbeddedTilesetNode) => Promise<number[]>;
|
|
310
|
+
//#endregion
|
|
311
|
+
//#region src/services/getDecompressedBytes.d.ts
|
|
308
312
|
export declare const getDecompressedBytes: (bytes: Uint8Array<ArrayBuffer>, compression: Compression.Gzip | Compression.Zlib) => Promise<Uint8Array<ArrayBuffer>>;
|
|
309
313
|
//#endregion
|
|
310
|
-
//#region src/
|
|
314
|
+
//#region src/services/parseFlips.d.ts
|
|
311
315
|
export declare const parseFlips: (gid: number) => TMXFlipsParsed;
|
|
312
316
|
//#endregion
|
|
313
317
|
//#region src/models/tmx/node/TMXLayerNode.d.ts
|
|
@@ -315,46 +319,37 @@ export interface TMXLayerNode extends TMXNode<TMXLayerShared, TMXDataNode | TMXE
|
|
|
315
319
|
data?: TMXDataNode[] | TMXEmbeddedTilesetNode[];
|
|
316
320
|
image?: TMXImageNode[];
|
|
317
321
|
object?: TMXObjectNode[];
|
|
318
|
-
properties?:
|
|
319
|
-
property: TMXPropertyNode[];
|
|
320
|
-
}[];
|
|
322
|
+
properties?: TMXPropertiesElement[];
|
|
321
323
|
}
|
|
322
324
|
//#endregion
|
|
325
|
+
//#region src/services/parseLayer.d.ts
|
|
326
|
+
export declare const parseLayer: (node: TMXLayerNode) => TMXLayerParsed;
|
|
327
|
+
//#endregion
|
|
323
328
|
//#region src/models/tmx/node/TMXGroupLayerNode.d.ts
|
|
324
329
|
export interface TMXGroupLayerNode extends TMXNode<TMXGroupLayerShared, TMXLayerNode> {
|
|
325
|
-
properties?:
|
|
326
|
-
property: TMXPropertyNode[];
|
|
327
|
-
}[];
|
|
330
|
+
properties?: TMXPropertiesElement[];
|
|
328
331
|
}
|
|
329
332
|
//#endregion
|
|
330
|
-
//#region src/
|
|
331
|
-
export declare const
|
|
332
|
-
//#endregion
|
|
333
|
-
//#region src/util/parseLayer.d.ts
|
|
334
|
-
export declare const parseLayer: (node: TMXLayerNode) => TMXLayerParsed;
|
|
333
|
+
//#region src/services/parseNode.d.ts
|
|
334
|
+
export declare const parseNode: <TNode extends TMXGroupLayerNode | TMXLayerNode, TParsedNode = TNode extends TMXLayerNode ? TMXLayerParsed : TMXGroupLayerParsed>(node: TNode, tileCount: number, translateFlips: boolean) => Promise<TParsedNode>;
|
|
335
335
|
//#endregion
|
|
336
|
-
//#region src/
|
|
337
|
-
export declare const parseNode: <TNode extends TMXGroupLayerNode | TMXLayerNode, TParsedNode = TNode extends TMXLayerNode ? TMXLayerParsed : TMXGroupLayerParsed>(node: TNode, expectedCount: number, translateFlips: boolean) => Promise<TParsedNode>;
|
|
338
|
-
//#endregion
|
|
339
|
-
//#region src/util/parseObject.d.ts
|
|
336
|
+
//#region src/services/parseObject.d.ts
|
|
340
337
|
export declare const parseObject: (node: TMXObjectNode) => TMXObjectParsed;
|
|
341
338
|
//#endregion
|
|
342
|
-
//#region src/
|
|
339
|
+
//#region src/services/parseObjectShape.d.ts
|
|
343
340
|
export declare const parseObjectShape: (node: TMXObjectNode) => Shape;
|
|
344
341
|
//#endregion
|
|
345
|
-
//#region src/
|
|
346
|
-
export declare const parseProperties: (properties:
|
|
347
|
-
property: TMXPropertyNode[];
|
|
348
|
-
}[]) => TMXPropertiesParsed;
|
|
342
|
+
//#region src/services/parseProperties.d.ts
|
|
343
|
+
export declare const parseProperties: (properties: TMXPropertiesElement[]) => TMXPropertiesParsed;
|
|
349
344
|
//#endregion
|
|
350
|
-
//#region src/
|
|
345
|
+
//#region src/services/parseTile.d.ts
|
|
351
346
|
export declare const parseTile: (node: TMXTileNode) => TMXTileParsed;
|
|
352
347
|
//#endregion
|
|
353
|
-
//#region src/
|
|
348
|
+
//#region src/services/parseTileId.d.ts
|
|
354
349
|
export declare const parseTileId: (gid: number) => number;
|
|
355
350
|
//#endregion
|
|
356
|
-
//#region src/
|
|
357
|
-
export declare const parseTileLayer: (node: TMXLayerNode,
|
|
351
|
+
//#region src/services/parseTileLayer.d.ts
|
|
352
|
+
export declare const parseTileLayer: (node: TMXLayerNode, tileCount: number, translateFlips: boolean) => Promise<TMXLayerParsed>;
|
|
358
353
|
//#endregion
|
|
359
354
|
//#region src/models/tmx/node/TMXExternalTilesetNode.d.ts
|
|
360
355
|
export interface TMXExternalTilesetNode extends TMXNode<TMXExternalTilesetShared> {}
|
|
@@ -362,17 +357,17 @@ export interface TMXExternalTilesetNode extends TMXNode<TMXExternalTilesetShared
|
|
|
362
357
|
//#region src/models/tmx/node/TMXTilesetNode.d.ts
|
|
363
358
|
export type TMXTilesetNode = TMXEmbeddedTilesetNode | TMXExternalTilesetNode;
|
|
364
359
|
//#endregion
|
|
365
|
-
//#region src/
|
|
360
|
+
//#region src/services/parseTileset.d.ts
|
|
366
361
|
export declare const parseTileset: (node: TMXTilesetNode) => TMXTilesetParsed;
|
|
367
362
|
//#endregion
|
|
368
|
-
//#region src/
|
|
363
|
+
//#region src/services/parseXmlString.d.ts
|
|
369
364
|
export declare const parseXmlString: <T extends object>(xmlString: string) => Promise<T>;
|
|
370
365
|
//#endregion
|
|
371
|
-
//#region src/
|
|
366
|
+
//#region src/services/parseXmlValue.d.ts
|
|
372
367
|
export declare const parseXmlValue: (value: string) => boolean | number | string;
|
|
373
368
|
//#endregion
|
|
374
|
-
//#region src/
|
|
375
|
-
export declare const unpackTileBytes: (bytes: Uint8Array
|
|
369
|
+
//#region src/services/unpackTileBytes.d.ts
|
|
370
|
+
export declare const unpackTileBytes: (bytes: Uint8Array) => number[];
|
|
376
371
|
//#endregion
|
|
377
372
|
//#region src/models/tmx/node/TMXExportNode.d.ts
|
|
378
373
|
export interface TMXExportNode extends TMXNode<TMXExportShared> {}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { InvalidOperationError, Operation, exhaustiveGuard, normalizeString, takeOne } from "@esposter/shared";
|
|
2
2
|
import { parseStringPromise } from "@esposter/xml2js";
|
|
3
|
-
import parseDataUrl from "data-urls";
|
|
4
3
|
//#region src/models/tmx/node/TMXNodeType.ts
|
|
5
4
|
let TMXNodeType = /* @__PURE__ */ function(TMXNodeType) {
|
|
6
5
|
TMXNodeType["Data"] = "data";
|
|
@@ -53,19 +52,11 @@ var TMXParsed = class {
|
|
|
53
52
|
}
|
|
54
53
|
};
|
|
55
54
|
//#endregion
|
|
56
|
-
//#region src/
|
|
55
|
+
//#region src/services/cloneNodeWithType.ts
|
|
57
56
|
const cloneNodeWithType = (node) => {
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
return
|
|
61
|
-
};
|
|
62
|
-
//#endregion
|
|
63
|
-
//#region src/util/parseGroup.ts
|
|
64
|
-
const parseGroup = async (node, expectedCount, translateFlips) => {
|
|
65
|
-
const { $$ } = node;
|
|
66
|
-
const group = cloneNodeWithType(node);
|
|
67
|
-
group.layers = await Promise.all($$.map((l) => parseNode(l, expectedCount, translateFlips)));
|
|
68
|
-
return group;
|
|
57
|
+
const attributes = structuredClone(node.$);
|
|
58
|
+
attributes.type = node["#name"];
|
|
59
|
+
return attributes;
|
|
69
60
|
};
|
|
70
61
|
//#endregion
|
|
71
62
|
//#region src/models/Flipped.ts
|
|
@@ -77,7 +68,7 @@ let Flipped = /* @__PURE__ */ function(Flipped) {
|
|
|
77
68
|
}({});
|
|
78
69
|
const Flippeds = Object.values(Flipped).filter((value) => typeof value === "number");
|
|
79
70
|
//#endregion
|
|
80
|
-
//#region src/
|
|
71
|
+
//#region src/services/parseFlips.ts
|
|
81
72
|
const parseFlips = (gid) => ({
|
|
82
73
|
Diagonal: Boolean(gid & 536870912),
|
|
83
74
|
Horizontal: Boolean(gid & 2147483648),
|
|
@@ -93,7 +84,7 @@ let Shape = /* @__PURE__ */ function(Shape) {
|
|
|
93
84
|
return Shape;
|
|
94
85
|
}({});
|
|
95
86
|
//#endregion
|
|
96
|
-
//#region src/
|
|
87
|
+
//#region src/services/parseObjectShape.ts
|
|
97
88
|
const parseObjectShape = (node) => {
|
|
98
89
|
if ("point" in node) return "point";
|
|
99
90
|
else if ("ellipse" in node) return "ellipse";
|
|
@@ -101,17 +92,17 @@ const parseObjectShape = (node) => {
|
|
|
101
92
|
else return "rectangle";
|
|
102
93
|
};
|
|
103
94
|
//#endregion
|
|
104
|
-
//#region src/
|
|
95
|
+
//#region src/services/parseProperties.ts
|
|
105
96
|
const parseProperties = (properties) => properties.flatMap(({ property }) => property.map(({ $: { name, value }, _ }) => ({
|
|
106
97
|
name,
|
|
107
98
|
value: value ?? _
|
|
108
99
|
})));
|
|
109
100
|
//#endregion
|
|
110
|
-
//#region src/
|
|
101
|
+
//#region src/services/parseTileId.ts
|
|
111
102
|
const FLIPPED_MASK = ~Flippeds.reduce((accumulator, flipped) => accumulator | flipped, 0);
|
|
112
103
|
const parseTileId = (gid) => gid & FLIPPED_MASK;
|
|
113
104
|
//#endregion
|
|
114
|
-
//#region src/
|
|
105
|
+
//#region src/services/parseObject.ts
|
|
115
106
|
const parseObject = (node) => {
|
|
116
107
|
const { $, polygon, properties, text } = node;
|
|
117
108
|
const object = structuredClone($);
|
|
@@ -138,13 +129,12 @@ const parseObject = (node) => {
|
|
|
138
129
|
return object;
|
|
139
130
|
};
|
|
140
131
|
//#endregion
|
|
141
|
-
//#region src/
|
|
132
|
+
//#region src/services/parseLayer.ts
|
|
142
133
|
const parseLayer = (node) => {
|
|
143
134
|
const { image, object, properties } = node;
|
|
144
135
|
const layer = cloneNodeWithType(node);
|
|
145
|
-
layer.visible = 1;
|
|
146
136
|
if (image) layer.image = structuredClone(takeOne(image).$);
|
|
147
|
-
if (object) layer.objects = object.map((
|
|
137
|
+
if (object) layer.objects = object.map((objectNode) => parseObject(objectNode));
|
|
148
138
|
if (properties) layer.properties = parseProperties(properties);
|
|
149
139
|
return layer;
|
|
150
140
|
};
|
|
@@ -163,109 +153,108 @@ let Encoding = /* @__PURE__ */ function(Encoding) {
|
|
|
163
153
|
return Encoding;
|
|
164
154
|
}({});
|
|
165
155
|
//#endregion
|
|
166
|
-
//#region src/
|
|
156
|
+
//#region src/services/checkIsTMXEmbeddedTilesetNode.ts
|
|
167
157
|
const checkIsTMXEmbeddedTilesetNode = (node) => "tile" in node;
|
|
168
158
|
//#endregion
|
|
169
|
-
//#region src/
|
|
159
|
+
//#region src/services/getDecompressedBytes.ts
|
|
170
160
|
const getDecompressedBytes = async (bytes, compression) => {
|
|
171
161
|
const format = compression === "gzip" ? "gzip" : "deflate";
|
|
172
162
|
const decompressedTileStream = new Blob([bytes]).stream().pipeThrough(new DecompressionStream(format));
|
|
173
163
|
return new Uint8Array(await new Response(decompressedTileStream).arrayBuffer());
|
|
174
164
|
};
|
|
175
165
|
//#endregion
|
|
176
|
-
//#region src/
|
|
177
|
-
const unpackTileBytes = (bytes
|
|
178
|
-
if (bytes.byteLength !==
|
|
166
|
+
//#region src/services/unpackTileBytes.ts
|
|
167
|
+
const unpackTileBytes = (bytes) => {
|
|
168
|
+
if (bytes.byteLength % Uint32Array.BYTES_PER_ELEMENT !== 0) throw new InvalidOperationError(Operation.Read, "TMXLayer", `expected whole ${Uint32Array.BYTES_PER_ELEMENT}-byte tiles, received ${bytes.byteLength} bytes`);
|
|
179
169
|
const unpackedTiles = [];
|
|
180
170
|
const dataView = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
181
|
-
for (let
|
|
171
|
+
for (let byteIndex = 0; byteIndex < bytes.byteLength; byteIndex += Uint32Array.BYTES_PER_ELEMENT) unpackedTiles.push(dataView.getUint32(byteIndex, true));
|
|
182
172
|
return unpackedTiles;
|
|
183
173
|
};
|
|
184
174
|
//#endregion
|
|
185
|
-
//#region src/
|
|
186
|
-
const
|
|
175
|
+
//#region src/services/decodeTileData.ts
|
|
176
|
+
const decodeTileData = async (nodeData) => {
|
|
177
|
+
if (checkIsTMXEmbeddedTilesetNode(nodeData)) return nodeData.tile?.map(({ $ }) => $.gid ?? 0) ?? [];
|
|
178
|
+
const { $, _ } = nodeData;
|
|
179
|
+
const { compression, encoding } = $;
|
|
180
|
+
const layerData = normalizeString(_);
|
|
181
|
+
switch (encoding) {
|
|
182
|
+
case "base64": {
|
|
183
|
+
const bytes = Uint8Array.fromBase64(layerData);
|
|
184
|
+
switch (compression) {
|
|
185
|
+
case "gzip":
|
|
186
|
+
case "zlib": return unpackTileBytes(await getDecompressedBytes(bytes, compression));
|
|
187
|
+
case void 0: return unpackTileBytes(bytes);
|
|
188
|
+
default: return exhaustiveGuard(compression);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
case "csv": return layerData.split(",").map(Number);
|
|
192
|
+
default: return exhaustiveGuard(encoding);
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
//#endregion
|
|
196
|
+
//#region src/services/parseTileLayer.ts
|
|
197
|
+
const parseTileLayer = async (node, tileCount, translateFlips) => {
|
|
187
198
|
const { data, properties } = node;
|
|
188
199
|
if (!data) throw new InvalidOperationError(Operation.Read, "TMXLayer", "data is missing");
|
|
189
200
|
const layer = cloneNodeWithType(node);
|
|
190
201
|
if (properties) layer.properties = parseProperties(properties);
|
|
191
202
|
const nodeData = takeOne(data);
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
const { $, _ } = nodeData;
|
|
195
|
-
const { compression, encoding } = $;
|
|
196
|
-
const layerData = normalizeString(_);
|
|
197
|
-
switch (encoding) {
|
|
198
|
-
case "base64": {
|
|
199
|
-
const bytes = Uint8Array.fromBase64(layerData);
|
|
200
|
-
switch (compression) {
|
|
201
|
-
case "gzip":
|
|
202
|
-
case "zlib":
|
|
203
|
-
layer.data = unpackTileBytes(await getDecompressedBytes(bytes, compression), expectedCount);
|
|
204
|
-
break;
|
|
205
|
-
case void 0:
|
|
206
|
-
layer.data = unpackTileBytes(bytes, expectedCount);
|
|
207
|
-
break;
|
|
208
|
-
default: exhaustiveGuard(compression);
|
|
209
|
-
}
|
|
210
|
-
break;
|
|
211
|
-
}
|
|
212
|
-
case "csv":
|
|
213
|
-
layer.data = layerData.split(",").map(Number);
|
|
214
|
-
break;
|
|
215
|
-
default: exhaustiveGuard(encoding);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
203
|
+
const tiles = await decodeTileData(nodeData);
|
|
204
|
+
if (tiles.length !== tileCount) throw new InvalidOperationError(Operation.Read, "TMXLayer", `expected ${tileCount} tiles, received ${tiles.length}`);
|
|
218
205
|
if (translateFlips) {
|
|
219
|
-
layer.data
|
|
220
|
-
layer.flips =
|
|
221
|
-
|
|
222
|
-
}
|
|
206
|
+
layer.data = tiles.map((gid) => parseTileId(gid));
|
|
207
|
+
layer.flips = tiles.map((gid) => parseFlips(gid));
|
|
208
|
+
} else layer.data = tiles;
|
|
223
209
|
return layer;
|
|
224
210
|
};
|
|
225
211
|
//#endregion
|
|
226
|
-
//#region src/
|
|
227
|
-
const
|
|
212
|
+
//#region src/services/parseNode.ts
|
|
213
|
+
const parseGroup = async (node, tileCount, translateFlips) => {
|
|
214
|
+
const group = cloneNodeWithType(node);
|
|
215
|
+
group.layers = await Promise.all(node.$$.map((layerNode) => parseNode(layerNode, tileCount, translateFlips)));
|
|
216
|
+
return group;
|
|
217
|
+
};
|
|
218
|
+
const parseNode = (node, tileCount, translateFlips) => {
|
|
228
219
|
const tmxNodeType = node["#name"];
|
|
229
220
|
switch (tmxNodeType) {
|
|
230
|
-
case "group": return parseGroup(node,
|
|
221
|
+
case "group": return parseGroup(node, tileCount, translateFlips);
|
|
231
222
|
case "imagelayer":
|
|
232
223
|
case "objectgroup": return Promise.resolve(parseLayer(node));
|
|
233
|
-
case "layer": return parseTileLayer(node,
|
|
224
|
+
case "layer": return parseTileLayer(node, tileCount, translateFlips);
|
|
234
225
|
default: throw new InvalidOperationError(Operation.Read, parseNode.name, tmxNodeType);
|
|
235
226
|
}
|
|
236
227
|
};
|
|
237
228
|
//#endregion
|
|
238
|
-
//#region src/
|
|
229
|
+
//#region src/services/checkIsExternalTileset.ts
|
|
239
230
|
const checkIsExternalTileset = (tileset) => "source" in tileset;
|
|
240
231
|
//#endregion
|
|
241
|
-
//#region src/
|
|
232
|
+
//#region src/services/parseTile.ts
|
|
242
233
|
const parseTile = (node) => {
|
|
243
234
|
const { $, animation, objectgroup, properties } = node;
|
|
244
235
|
const tile = structuredClone($);
|
|
245
236
|
if (animation) tile.animation = { frames: takeOne(takeOne(animation), "frame").map(({ $: frameData }) => structuredClone(frameData)) };
|
|
246
|
-
if (objectgroup) tile.objects = takeOne(takeOne(objectgroup), "object").map((
|
|
237
|
+
if (objectgroup) tile.objects = takeOne(takeOne(objectgroup), "object").map((objectNode) => parseObject(objectNode));
|
|
247
238
|
if (properties) tile.properties = parseProperties(properties);
|
|
248
239
|
return tile;
|
|
249
240
|
};
|
|
250
241
|
//#endregion
|
|
251
|
-
//#region src/
|
|
242
|
+
//#region src/services/parseTileset.ts
|
|
252
243
|
const parseTileset = (node) => {
|
|
253
244
|
if (checkIsExternalTileset(node.$)) return structuredClone(node.$);
|
|
254
245
|
const { $, $$, tile } = node;
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
}
|
|
265
|
-
throw new InvalidOperationError(Operation.Read, parseTileset.name, $.name);
|
|
246
|
+
const imageNode = $$.find((childNode) => childNode["#name"] === "image");
|
|
247
|
+
if (!imageNode) throw new InvalidOperationError(Operation.Read, parseTileset.name, $.name);
|
|
248
|
+
const image = structuredClone(imageNode.$);
|
|
249
|
+
const tiles = tile?.map((tileNode) => parseTile(tileNode)) ?? [];
|
|
250
|
+
return {
|
|
251
|
+
...$,
|
|
252
|
+
image,
|
|
253
|
+
tiles
|
|
254
|
+
};
|
|
266
255
|
};
|
|
267
256
|
//#endregion
|
|
268
|
-
//#region src/
|
|
257
|
+
//#region src/services/parseXmlValue.ts
|
|
269
258
|
const NUMBER_REGEX = /^[+-]?\d+(?<decimal>\.\d+)?$/u;
|
|
270
259
|
const parseXmlValue = (value) => {
|
|
271
260
|
if (value === "true") return true;
|
|
@@ -274,21 +263,18 @@ const parseXmlValue = (value) => {
|
|
|
274
263
|
else return value;
|
|
275
264
|
};
|
|
276
265
|
//#endregion
|
|
277
|
-
//#region src/
|
|
278
|
-
const parseXmlString = (xmlString) => {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
preserveChildrenOrder: true
|
|
284
|
-
});
|
|
285
|
-
};
|
|
266
|
+
//#region src/services/parseXmlString.ts
|
|
267
|
+
const parseXmlString = (xmlString) => parseStringPromise(xmlString, {
|
|
268
|
+
attrValueProcessors: [(value) => parseXmlValue(value)],
|
|
269
|
+
explicitChildren: true,
|
|
270
|
+
preserveChildrenOrder: true
|
|
271
|
+
});
|
|
286
272
|
//#endregion
|
|
287
273
|
//#region src/parseTmx.ts
|
|
288
274
|
const parseTmx = async (xmlString, translateFlips = false) => {
|
|
289
275
|
const { map: { $, $$ } } = await parseXmlString(xmlString);
|
|
290
276
|
const map = new TMXMapParsed($);
|
|
291
|
-
const
|
|
277
|
+
const tileCount = map.width * map.height;
|
|
292
278
|
for (const node of $$) {
|
|
293
279
|
const tmxNodeType = node["#name"];
|
|
294
280
|
switch (tmxNodeType) {
|
|
@@ -305,7 +291,7 @@ const parseTmx = async (xmlString, translateFlips = false) => {
|
|
|
305
291
|
case "imagelayer":
|
|
306
292
|
case "layer":
|
|
307
293
|
case "objectgroup": {
|
|
308
|
-
const layer = await parseNode(node,
|
|
294
|
+
const layer = await parseNode(node, tileCount, translateFlips);
|
|
309
295
|
map.layers.push(layer);
|
|
310
296
|
break;
|
|
311
297
|
}
|
|
@@ -328,4 +314,4 @@ var BaseTMXNode = class {
|
|
|
328
314
|
$;
|
|
329
315
|
};
|
|
330
316
|
//#endregion
|
|
331
|
-
export { BaseTMXNode, Compression, Encoding, Flipped, Flippeds, Shape, TMXMapParsed, TMXMapShared, TMXNodeType, TMXParsed, checkIsExternalTileset, checkIsTMXEmbeddedTilesetNode, cloneNodeWithType, getDecompressedBytes, parseFlips,
|
|
317
|
+
export { BaseTMXNode, Compression, Encoding, Flipped, Flippeds, Shape, TMXMapParsed, TMXMapShared, TMXNodeType, TMXParsed, checkIsExternalTileset, checkIsTMXEmbeddedTilesetNode, cloneNodeWithType, decodeTileData, getDecompressedBytes, parseFlips, parseLayer, parseNode, parseObject, parseObjectShape, parseProperties, parseTile, parseTileId, parseTileLayer, parseTileset, parseTmx, parseXmlString, parseXmlValue, unpackTileBytes };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "parse-tmx",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.0",
|
|
4
4
|
"description": "A parser for tmx.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"game-development",
|
|
@@ -52,19 +52,16 @@
|
|
|
52
52
|
"typecheck": "tsc"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@esposter/shared": "3.
|
|
56
|
-
"@esposter/xml2js": "3.
|
|
57
|
-
"data-urls": "^7.0.0"
|
|
55
|
+
"@esposter/shared": "3.3.0",
|
|
56
|
+
"@esposter/xml2js": "3.3.0"
|
|
58
57
|
},
|
|
59
58
|
"devDependencies": {
|
|
60
59
|
"@arethetypeswrong/core": "^0.18.5",
|
|
61
|
-
"@esposter/configuration": "3.
|
|
62
|
-
"@types/data-urls": "^3.0.5",
|
|
63
|
-
"@types/xml2js": "^0.4.14",
|
|
60
|
+
"@esposter/configuration": "3.3.0",
|
|
64
61
|
"publint": "^0.3.24",
|
|
65
62
|
"tsdown": "^0.23.0",
|
|
66
|
-
"type-fest": "^5.
|
|
67
|
-
"vitest": "^5.0.
|
|
63
|
+
"type-fest": "^5.10.0",
|
|
64
|
+
"vitest": "^5.0.2"
|
|
68
65
|
},
|
|
69
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "5854a00717502d8de96adc8b44d3621ab85f9b57"
|
|
70
67
|
}
|