@codexo/exojs-tilemap 0.15.3 → 0.16.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.
Files changed (151) hide show
  1. package/README.md +33 -26
  2. package/dist/esm/ChunkSource.d.ts +33 -0
  3. package/dist/esm/ChunkSource.d.ts.map +1 -0
  4. package/dist/esm/ChunkStreamer.d.ts +98 -0
  5. package/dist/esm/ChunkStreamer.d.ts.map +1 -0
  6. package/dist/esm/ChunkStreamer.js +201 -0
  7. package/dist/esm/ChunkStreamer.js.map +1 -0
  8. package/dist/esm/ImageLayer.d.ts +11 -3
  9. package/dist/esm/ImageLayer.d.ts.map +1 -0
  10. package/dist/esm/ImageLayer.js +71 -64
  11. package/dist/esm/ImageLayer.js.map +1 -1
  12. package/dist/esm/ImageLayerNode.d.ts +89 -0
  13. package/dist/esm/ImageLayerNode.d.ts.map +1 -0
  14. package/dist/esm/ImageLayerNode.js +205 -0
  15. package/dist/esm/ImageLayerNode.js.map +1 -0
  16. package/dist/esm/MapObject.d.ts +70 -0
  17. package/dist/esm/MapObject.d.ts.map +1 -0
  18. package/dist/esm/MapObject.js +34 -0
  19. package/dist/esm/MapObject.js.map +1 -0
  20. package/dist/esm/MapObjectSpawner.d.ts +133 -0
  21. package/dist/esm/MapObjectSpawner.d.ts.map +1 -0
  22. package/dist/esm/MapObjectSpawner.js +147 -0
  23. package/dist/esm/MapObjectSpawner.js.map +1 -0
  24. package/dist/esm/MapSpawnSession.d.ts +53 -0
  25. package/dist/esm/MapSpawnSession.d.ts.map +1 -0
  26. package/dist/esm/MapSpawnSession.js +88 -0
  27. package/dist/esm/MapSpawnSession.js.map +1 -0
  28. package/dist/esm/MapWorld.d.ts +134 -0
  29. package/dist/esm/MapWorld.d.ts.map +1 -0
  30. package/dist/esm/MapWorld.js +150 -0
  31. package/dist/esm/MapWorld.js.map +1 -0
  32. package/dist/esm/MapWorldRuntime.d.ts +182 -0
  33. package/dist/esm/MapWorldRuntime.d.ts.map +1 -0
  34. package/dist/esm/MapWorldRuntime.js +261 -0
  35. package/dist/esm/MapWorldRuntime.js.map +1 -0
  36. package/dist/esm/ObjectLayer.d.ts +93 -7
  37. package/dist/esm/ObjectLayer.d.ts.map +1 -0
  38. package/dist/esm/ObjectLayer.js +184 -167
  39. package/dist/esm/ObjectLayer.js.map +1 -1
  40. package/dist/esm/SampledChunkSource.d.ts +43 -0
  41. package/dist/esm/SampledChunkSource.d.ts.map +1 -0
  42. package/dist/esm/SampledChunkSource.js +48 -0
  43. package/dist/esm/SampledChunkSource.js.map +1 -0
  44. package/dist/esm/TileAnimator.d.ts +12 -2
  45. package/dist/esm/TileAnimator.d.ts.map +1 -0
  46. package/dist/esm/TileAnimator.js +154 -165
  47. package/dist/esm/TileAnimator.js.map +1 -1
  48. package/dist/esm/TileChunk.d.ts +30 -5
  49. package/dist/esm/TileChunk.d.ts.map +1 -0
  50. package/dist/esm/TileChunk.js +190 -188
  51. package/dist/esm/TileChunk.js.map +1 -1
  52. package/dist/esm/TileChunkNode.d.ts +18 -3
  53. package/dist/esm/TileChunkNode.d.ts.map +1 -0
  54. package/dist/esm/TileChunkNode.js +104 -85
  55. package/dist/esm/TileChunkNode.js.map +1 -1
  56. package/dist/esm/TileLayer.d.ts +104 -24
  57. package/dist/esm/TileLayer.d.ts.map +1 -0
  58. package/dist/esm/TileLayer.js +511 -469
  59. package/dist/esm/TileLayer.js.map +1 -1
  60. package/dist/esm/TileLayerNode.d.ts +52 -11
  61. package/dist/esm/TileLayerNode.d.ts.map +1 -0
  62. package/dist/esm/TileLayerNode.js +224 -166
  63. package/dist/esm/TileLayerNode.js.map +1 -1
  64. package/dist/esm/TileMap.d.ts +96 -31
  65. package/dist/esm/TileMap.d.ts.map +1 -0
  66. package/dist/esm/TileMap.js +401 -357
  67. package/dist/esm/TileMap.js.map +1 -1
  68. package/dist/esm/TileMapBand.d.ts +42 -29
  69. package/dist/esm/TileMapBand.d.ts.map +1 -0
  70. package/dist/esm/TileMapBand.js +151 -158
  71. package/dist/esm/TileMapBand.js.map +1 -1
  72. package/dist/esm/TileMapNode.d.ts +34 -18
  73. package/dist/esm/TileMapNode.d.ts.map +1 -0
  74. package/dist/esm/TileMapNode.js +122 -109
  75. package/dist/esm/TileMapNode.js.map +1 -1
  76. package/dist/esm/TileMapView.d.ts +108 -47
  77. package/dist/esm/TileMapView.d.ts.map +1 -0
  78. package/dist/esm/TileMapView.js +385 -338
  79. package/dist/esm/TileMapView.js.map +1 -1
  80. package/dist/esm/TileSet.d.ts +15 -6
  81. package/dist/esm/TileSet.d.ts.map +1 -0
  82. package/dist/esm/TileSet.js +161 -181
  83. package/dist/esm/TileSet.js.map +1 -1
  84. package/dist/esm/WangSet.d.ts +5 -4
  85. package/dist/esm/WangSet.d.ts.map +1 -0
  86. package/dist/esm/WangSet.js +70 -78
  87. package/dist/esm/WangSet.js.map +1 -1
  88. package/dist/esm/WorkerSampledChunkSource.d.ts +95 -0
  89. package/dist/esm/WorkerSampledChunkSource.d.ts.map +1 -0
  90. package/dist/esm/WorkerSampledChunkSource.js +117 -0
  91. package/dist/esm/WorkerSampledChunkSource.js.map +1 -0
  92. package/dist/esm/autoTile.d.ts +10 -5
  93. package/dist/esm/autoTile.d.ts.map +1 -0
  94. package/dist/esm/autoTile.js +164 -205
  95. package/dist/esm/autoTile.js.map +1 -1
  96. package/dist/esm/chunkGeometry.d.ts +8 -7
  97. package/dist/esm/chunkGeometry.d.ts.map +1 -0
  98. package/dist/esm/chunkGeometry.js +83 -94
  99. package/dist/esm/chunkGeometry.js.map +1 -1
  100. package/dist/esm/index.d.ts +1 -0
  101. package/dist/esm/index.d.ts.map +1 -0
  102. package/dist/esm/index.js +26 -15
  103. package/dist/esm/nodeBounds.d.ts +20 -0
  104. package/dist/esm/nodeBounds.d.ts.map +1 -0
  105. package/dist/esm/nodeBounds.js +40 -0
  106. package/dist/esm/nodeBounds.js.map +1 -0
  107. package/dist/esm/pixelSnap.d.ts +4 -3
  108. package/dist/esm/pixelSnap.d.ts.map +1 -0
  109. package/dist/esm/pixelSnap.js +18 -16
  110. package/dist/esm/pixelSnap.js.map +1 -1
  111. package/dist/esm/public.d.ts +23 -3
  112. package/dist/esm/public.d.ts.map +1 -0
  113. package/dist/esm/tileCollision.d.ts +190 -0
  114. package/dist/esm/tileCollision.d.ts.map +1 -0
  115. package/dist/esm/tileCollision.js +367 -0
  116. package/dist/esm/tileCollision.js.map +1 -0
  117. package/dist/esm/tileWord.d.ts +12 -0
  118. package/dist/esm/tileWord.d.ts.map +1 -0
  119. package/dist/esm/tileWord.js +16 -0
  120. package/dist/esm/tileWord.js.map +1 -0
  121. package/dist/esm/tilemapExtension.d.ts +4 -3
  122. package/dist/esm/tilemapExtension.d.ts.map +1 -0
  123. package/dist/esm/tilemapExtension.js +47 -47
  124. package/dist/esm/tilemapExtension.js.map +1 -1
  125. package/dist/esm/tilemapSerializers.d.ts +5 -4
  126. package/dist/esm/tilemapSerializers.d.ts.map +1 -0
  127. package/dist/esm/tilemapSerializers.js +48 -41
  128. package/dist/esm/tilemapSerializers.js.map +1 -1
  129. package/dist/esm/types.d.ts +34 -18
  130. package/dist/esm/types.d.ts.map +1 -0
  131. package/dist/esm/types.js +111 -120
  132. package/dist/esm/types.js.map +1 -1
  133. package/dist/esm/webgl2/WebGl2TileChunkRenderer.d.ts +50 -2
  134. package/dist/esm/webgl2/WebGl2TileChunkRenderer.d.ts.map +1 -0
  135. package/dist/esm/webgl2/WebGl2TileChunkRenderer.js +366 -332
  136. package/dist/esm/webgl2/WebGl2TileChunkRenderer.js.map +1 -1
  137. package/dist/esm/webgl2/shaders/tile-chunk.frag.js +6 -0
  138. package/dist/esm/webgl2/shaders/tile-chunk.frag.js.map +1 -0
  139. package/dist/esm/webgl2/shaders/tile-chunk.vert.js +6 -0
  140. package/dist/esm/webgl2/shaders/tile-chunk.vert.js.map +1 -0
  141. package/dist/esm/webgpu/WebGpuTileChunkRenderer.d.ts +70 -4
  142. package/dist/esm/webgpu/WebGpuTileChunkRenderer.d.ts.map +1 -0
  143. package/dist/esm/webgpu/WebGpuTileChunkRenderer.js +496 -383
  144. package/dist/esm/webgpu/WebGpuTileChunkRenderer.js.map +1 -1
  145. package/dist/esm/webgpu/shaders/tile-chunk.wgsl.js +6 -0
  146. package/dist/esm/webgpu/shaders/tile-chunk.wgsl.js.map +1 -0
  147. package/package.json +8 -15
  148. package/dist/esm/index.js.map +0 -1
  149. package/dist/esm/register.d.ts +0 -1
  150. package/dist/esm/register.js +0 -25
  151. package/dist/esm/register.js.map +0 -1
@@ -35,6 +35,15 @@ export interface ObjectPoint {
35
35
  interface TileMapObjectBase<P extends TileProperties = TileProperties> {
36
36
  /** Source-unique object id. */
37
37
  readonly id: number;
38
+ /**
39
+ * Stable string identity assigned by the authoring format, when it has one.
40
+ *
41
+ * LDtk sets it to the entity `iid`, which is globally unique and survives
42
+ * re-ordering, re-export and level moves - the identity to persist in a
43
+ * savegame. Tiled has no such field and leaves this unset; there, {@link id}
44
+ * is the identity and it is unique only within its map.
45
+ */
46
+ readonly sourceId?: string;
38
47
  /** Object name (may be empty; not unique). */
39
48
  readonly name: string;
40
49
  /** Object class/type string (Tiled `type`/`class`; may be empty). */
@@ -47,12 +56,25 @@ interface TileMapObjectBase<P extends TileProperties = TileProperties> {
47
56
  readonly width: number;
48
57
  /** Bounding height in px (0 for points). */
49
58
  readonly height: number;
50
- /** Rotation in degrees, clockwise, about the object origin. */
59
+ /**
60
+ * Rotation in degrees, clockwise, about `(x, y)` - except on a
61
+ * {@link TileObject}, whose pivot stays at the source format's own anchor and
62
+ * is generally not `(x, y)`. See {@link TileObject} for why.
63
+ */
51
64
  readonly rotation: number;
52
65
  /** Whether the object is marked visible. */
53
66
  readonly visible: boolean;
54
67
  /** Immutable custom properties. */
55
68
  readonly properties: P;
69
+ /**
70
+ * The raw source-format record this object was parsed from, for the rare
71
+ * case that needs a field this model does not carry. Adapters that keep
72
+ * their parsed document alive set it (`LdtkEntityInstance` for LDtk,
73
+ * `TiledObject` for Tiled); a procedurally built object has none.
74
+ *
75
+ * Reading it ties the code to one source format - prefer the typed fields.
76
+ */
77
+ readonly source?: unknown;
56
78
  }
57
79
  /** An axis-aligned rectangle object spanning `[x, y, width, height]`. */
58
80
  export interface RectangleObject<P extends TileProperties = TileProperties> extends TileMapObjectBase<P> {
@@ -76,7 +98,23 @@ export interface PolylineObject<P extends TileProperties = TileProperties> exten
76
98
  readonly kind: typeof ObjectKind.Polyline;
77
99
  readonly points: readonly ObjectPoint[];
78
100
  }
79
- /** A tile (GID) object carrying a resolved tile reference. */
101
+ /**
102
+ * A tile (GID) object carrying a resolved tile reference.
103
+ *
104
+ * `x`/`y` are the top-left corner of the bounding box, the same convention as
105
+ * every other object kind. Source formats that anchor a tile object elsewhere
106
+ * normalise to the corner on import: Tiled stores the position at the
107
+ * tileset's `objectalignment` point (bottom-left by default on an orthogonal
108
+ * map, bottom-centre on an isometric one) and rotates the tile image about
109
+ * that point, so a non-zero {@link TileMapObjectBase.rotation} on a tile
110
+ * object still pivots about the source anchor rather than about `(x, y)`.
111
+ *
112
+ * The owning tileset's drawing offset (Tiled `tileoffset`, reachable as
113
+ * `tile.tileset.offsetX`/`offsetY`) is likewise **not** folded into `x`/`y`.
114
+ * Object layers are data-only, so nothing in this package draws a tile object;
115
+ * code that does has to add that offset itself to match how a tile layer
116
+ * places the same tile.
117
+ */
80
118
  export interface TileObject<P extends TileProperties = TileProperties> extends TileMapObjectBase<P> {
81
119
  readonly kind: typeof ObjectKind.Tile;
82
120
  readonly tile: ResolvedTile;
@@ -131,7 +169,7 @@ export type TileMapObject<P extends TileProperties = TileProperties> = Rectangle
131
169
  *
132
170
  * @remarks
133
171
  * A schema is a **developer promise, not a runtime guarantee.** Tiled data is
134
- * untyped at runtime and ExoJS performs no validation against the schema
172
+ * untyped at runtime and ExoJS performs no validation against the schema -
135
173
  * the property objects are returned exactly as parsed. The schema only refines
136
174
  * the static type of `properties` for ergonomic, typo-safe field access. If the
137
175
  * source data does not match the declared shape, reads still succeed but the
@@ -185,6 +223,23 @@ export interface ObjectLayerOptions {
185
223
  readonly offsetX?: number;
186
224
  /** Layer pixel offset Y. Default `0`. */
187
225
  readonly offsetY?: number;
226
+ /**
227
+ * Parallax scroll factor on the X axis. `1` = full camera speed (normal),
228
+ * `0.5` = half speed (farther away), `0` = stationary. Default `1`.
229
+ */
230
+ readonly parallaxX?: number;
231
+ /**
232
+ * Parallax scroll factor on the Y axis. `1` = full camera speed (normal),
233
+ * `0.5` = half speed (farther away), `0` = stationary. Default `1`.
234
+ */
235
+ readonly parallaxY?: number;
236
+ /** Uniform parallax scale around the layer origin. Default `1`. */
237
+ readonly parallaxScale?: number;
238
+ /**
239
+ * Multiplicative layer tint as a `0xRRGGBB` integer, or `null` for no tint
240
+ * (Tiled `tintcolor`). Default `null`.
241
+ */
242
+ readonly tintColor?: number | null;
188
243
  /**
189
244
  * Draw order for the objects (Tiled `draworder`): `'topdown'` (sorted by `y`)
190
245
  * or `'index'` (source order). Informational; objects are stored as given.
@@ -197,20 +252,29 @@ export interface ObjectLayerOptions {
197
252
  readonly properties?: TileProperties;
198
253
  }
199
254
  /**
200
- * A data-only layer of {@link TileMapObject}s spawn points, trigger zones,
255
+ * A data-only layer of {@link TileMapObject}s - spawn points, trigger zones,
201
256
  * collision regions, markers. Object layers are not rendered by the tile
202
257
  * renderer; they are parsed and exposed for gameplay use (e.g. building physics
203
258
  * colliders, placing entities).
204
259
  *
260
+ * The presentation fields the source format attaches to a layer -
261
+ * {@link visible}, {@link opacity}, {@link offsetX}/{@link offsetY},
262
+ * {@link parallaxX}/{@link parallaxY}, {@link parallaxScale}, and
263
+ * {@link tintColor} - are carried
264
+ * through in full, with any enclosing group layers' contribution already
265
+ * folded in, so an object layer describes the same placement and shading its
266
+ * neighbouring tile and image layers do. Nothing here acts on them: code that
267
+ * draws these objects itself is what applies them.
268
+ *
205
269
  * Query with {@link query} (untyped, fully back-compatible) or, when an
206
270
  * {@link ObjectSchema} type argument `S` is supplied, with the typed accessors
207
- * {@link byType}, {@link byKind}, and {@link where} these narrow `properties`
271
+ * {@link byType}, {@link byKind}, and {@link where} - these narrow `properties`
208
272
  * to the developer-declared shape. The schema is **opt-in**: the default type
209
273
  * parameter reproduces the original untyped behaviour, so
210
274
  * `new ObjectLayer(options)` and `map.getObjectLayer('x')` are unchanged.
211
275
  *
212
276
  * @remarks
213
- * A schema is a developer promise, not a runtime guarantee Tiled data is
277
+ * A schema is a developer promise, not a runtime guarantee - Tiled data is
214
278
  * untyped at runtime and ExoJS performs no validation. See {@link ObjectSchema}.
215
279
  *
216
280
  * @typeParam S - Optional {@link ObjectSchema} mapping object `type` strings to
@@ -236,6 +300,27 @@ export declare class ObjectLayer<S extends ObjectSchema = ObjectSchema> {
236
300
  readonly offsetX: number;
237
301
  /** Layer pixel offset Y. */
238
302
  readonly offsetY: number;
303
+ /**
304
+ * Parallax scroll factor on the X axis - the same quantity
305
+ * {@link import('./TileLayer').TileLayer.parallaxX} carries, so an object
306
+ * layer authored beside a tile layer in the same parallax group reports the
307
+ * same factor. `1` = full camera speed, `0.5` = half speed, `0` =
308
+ * stationary. Nothing in this package applies it: object layers are
309
+ * data-only, so placing an object relative to the camera is the consumer's
310
+ * job (see {@link ObjectLayer}).
311
+ */
312
+ readonly parallaxX: number;
313
+ /** Parallax scroll factor on the Y axis. See {@link ObjectLayer.parallaxX}. */
314
+ readonly parallaxY: number;
315
+ /** Uniform scale applied around the layer origin by consumers that render this data-only layer. */
316
+ readonly parallaxScale: number;
317
+ /**
318
+ * Multiplicative layer tint as `0xRRGGBB`, or `null` for no tint. Carried
319
+ * from the source map (including the accumulated tint of any enclosing group
320
+ * layers) for code that draws these objects itself; like
321
+ * {@link ObjectLayer.parallaxX}, nothing in this package applies it.
322
+ */
323
+ readonly tintColor: number | null;
239
324
  /** Draw order for the objects (Tiled `draworder`). Informational. */
240
325
  readonly drawOrder: 'topdown' | 'index';
241
326
  /** Immutable layer-level properties. */
@@ -249,7 +334,7 @@ export declare class ObjectLayer<S extends ObjectSchema = ObjectSchema> {
249
334
  * Objects whose `type` equals `type`, with `properties` narrowed to the
250
335
  * schema shape `S[T]`. Returns a fresh array (insertion order).
251
336
  *
252
- * The narrowing is a static convenience only no runtime validation is
337
+ * The narrowing is a static convenience only - no runtime validation is
253
338
  * performed (see {@link ObjectSchema}). On an unschematised layer this
254
339
  * behaves like `query({ type })` with `TileProperties` properties.
255
340
  */
@@ -275,3 +360,4 @@ export declare class ObjectLayer<S extends ObjectSchema = ObjectSchema> {
275
360
  getObjectByName(name: string): TileMapObject | undefined;
276
361
  }
277
362
  export {};
363
+ //# sourceMappingURL=ObjectLayer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ObjectLayer.d.ts","sourceRoot":"","sources":["../../src/ObjectLayer.ts"],"names":[],"mappings":"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"}
@@ -1,176 +1,193 @@
1
- import { TilePropertyKind } from './types.js';
1
+ import { TilePropertyKind } from "./types.js";
2
2
 
3
+ //#region src/ObjectLayer.ts
3
4
  /**
4
- * Geometry kinds for a {@link TileMapObject}, as an `as const` value object.
5
- *
6
- * Modelled as a frozen string map (not a TS `enum`) so the values stay
7
- * wire-compatible with the Tiled string serialisation, survive
8
- * `verbatimModuleSyntax` (no emitted runtime helper), and follow the package
9
- * convention for enum-like constants. Use the members for ergonomic, typo-safe
10
- * call sites: `layer.byKind(ObjectKind.Polygon)`.
11
- * @stable
12
- */
5
+ * Geometry kinds for a {@link TileMapObject}, as an `as const` value object.
6
+ *
7
+ * Modelled as a frozen string map (not a TS `enum`) so the values stay
8
+ * wire-compatible with the Tiled string serialisation, survive
9
+ * `verbatimModuleSyntax` (no emitted runtime helper), and follow the package
10
+ * convention for enum-like constants. Use the members for ergonomic, typo-safe
11
+ * call sites: `layer.byKind(ObjectKind.Polygon)`.
12
+ * @stable
13
+ */
13
14
  const ObjectKind = {
14
- Rectangle: 'rectangle',
15
- Ellipse: 'ellipse',
16
- Polygon: 'polygon',
17
- Polyline: 'polyline',
18
- Point: 'point',
19
- Tile: 'tile',
20
- Text: 'text',
15
+ Rectangle: "rectangle",
16
+ Ellipse: "ellipse",
17
+ Polygon: "polygon",
18
+ Polyline: "polyline",
19
+ Point: "point",
20
+ Tile: "tile",
21
+ Text: "text"
21
22
  };
22
23
  /**
23
- * Type guard for the {@link TilePropertyObjectRef} variant of
24
- * {@link TilePropertyValue}.
25
- * @internal
26
- */
27
- function isTilePropertyObjectRef(value) {
28
- return (typeof value === 'object' &&
29
- value !== null &&
30
- !Array.isArray(value) &&
31
- value.kind === TilePropertyKind.ObjectRef);
32
- }
24
+ * Type guard for the {@link TilePropertyObjectRef} variant of
25
+ * {@link TilePropertyValue}.
26
+ * @internal
27
+ */
28
+ const isTilePropertyObjectRef = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && value.kind === TilePropertyKind.ObjectRef;
33
29
  /**
34
- * Equality used by {@link ObjectLayer.query}'s `value` filter.
35
- *
36
- * Scalars and `null` compare with `===`. `objectRef` values compare by `id`
37
- * alone the one genuinely common "find all objects referencing X" query
38
- * need regardless of differing LDtk navigation fields. Every other
39
- * structured shape (`point`, `tileRef`, arrays, nested property bags) has no
40
- * obvious value-equality semantics (exact float coordinates? array order?)
41
- * and only matches when reference-identical; use `query({ property })`
42
- * (presence-only) for those.
43
- * @internal
44
- */
45
- function tilePropertyValueEquals(a, b) {
46
- if (a === b)
47
- return true;
48
- if (isTilePropertyObjectRef(a) && isTilePropertyObjectRef(b))
49
- return a.id === b.id;
50
- return false;
51
- }
30
+ * Equality used by {@link ObjectLayer.query}'s `value` filter.
31
+ *
32
+ * Scalars and `null` compare with `===`. `objectRef` values compare by `id`
33
+ * alone - the one genuinely common "find all objects referencing X" query
34
+ * need - regardless of differing LDtk navigation fields. Every other
35
+ * structured shape (`point`, `tileRef`, arrays, nested property bags) has no
36
+ * obvious value-equality semantics (exact float coordinates? array order?)
37
+ * and only matches when reference-identical; use `query({ property })`
38
+ * (presence-only) for those.
39
+ * @internal
40
+ */
41
+ const tilePropertyValueEquals = (a, b) => {
42
+ if (a === b) return true;
43
+ if (isTilePropertyObjectRef(a) && isTilePropertyObjectRef(b)) return a.id === b.id;
44
+ return false;
45
+ };
52
46
  /**
53
- * A data-only layer of {@link TileMapObject}s spawn points, trigger zones,
54
- * collision regions, markers. Object layers are not rendered by the tile
55
- * renderer; they are parsed and exposed for gameplay use (e.g. building physics
56
- * colliders, placing entities).
57
- *
58
- * Query with {@link query} (untyped, fully back-compatible) or, when an
59
- * {@link ObjectSchema} type argument `S` is supplied, with the typed accessors
60
- * {@link byType}, {@link byKind}, and {@link where} — these narrow `properties`
61
- * to the developer-declared shape. The schema is **opt-in**: the default type
62
- * parameter reproduces the original untyped behaviour, so
63
- * `new ObjectLayer(options)` and `map.getObjectLayer('x')` are unchanged.
64
- *
65
- * @remarks
66
- * A schema is a developer promise, not a runtime guarantee — Tiled data is
67
- * untyped at runtime and ExoJS performs no validation. See {@link ObjectSchema}.
68
- *
69
- * @typeParam S - Optional {@link ObjectSchema} mapping object `type` strings to
70
- * their property shapes. Defaults to a generic schema (every type maps to the
71
- * loose {@link TileProperties} bag).
72
- *
73
- * @advanced
74
- */
75
- class ObjectLayer {
76
- /** Layer-kind discriminant (distinguishes object layers from tile layers). */
77
- kind = 'object';
78
- /** Layer id (unique within the map). */
79
- id;
80
- /** Layer name. */
81
- name;
82
- /** Layer class string. */
83
- class;
84
- /** Whether the layer is visible. */
85
- visible;
86
- /** Layer opacity in `[0, 1]`. */
87
- opacity;
88
- /** Layer pixel offset X. */
89
- offsetX;
90
- /** Layer pixel offset Y. */
91
- offsetY;
92
- /** Draw order for the objects (Tiled `draworder`). Informational. */
93
- drawOrder;
94
- /** Immutable layer-level properties. */
95
- properties;
96
- /** The objects in this layer (insertion order). */
97
- objects;
98
- constructor(options) {
99
- this.id = options.id;
100
- this.name = options.name ?? '';
101
- this.class = options.class ?? '';
102
- this.visible = options.visible ?? true;
103
- this.opacity = options.opacity ?? 1;
104
- this.offsetX = options.offsetX ?? 0;
105
- this.offsetY = options.offsetY ?? 0;
106
- this.drawOrder = options.drawOrder ?? 'topdown';
107
- this.properties = options.properties ? Object.freeze({ ...options.properties }) : Object.freeze({});
108
- this.objects = options.objects ? Object.freeze([...options.objects]) : Object.freeze([]);
109
- }
110
- /** Objects matching every specified criterion of `filter`. Returns a fresh array. */
111
- query(filter = {}) {
112
- return this.objects.filter(object => {
113
- if (filter.name !== undefined && object.name !== filter.name) {
114
- return false;
115
- }
116
- if (filter.type !== undefined && object.type !== filter.type) {
117
- return false;
118
- }
119
- if (filter.kind !== undefined && object.kind !== filter.kind) {
120
- return false;
121
- }
122
- if (filter.property !== undefined) {
123
- // TilePropertyValue never includes `undefined`, so an `undefined`
124
- // read is a reliable "key absent" signal (equivalent to, but avoids
125
- // re-indexing after, an `in` check).
126
- const value = object.properties[filter.property];
127
- if (value === undefined) {
128
- return false;
129
- }
130
- if (filter.value !== undefined && !tilePropertyValueEquals(value, filter.value)) {
131
- return false;
132
- }
133
- }
134
- return true;
135
- });
136
- }
137
- /**
138
- * Objects whose `type` equals `type`, with `properties` narrowed to the
139
- * schema shape `S[T]`. Returns a fresh array (insertion order).
140
- *
141
- * The narrowing is a static convenience only — no runtime validation is
142
- * performed (see {@link ObjectSchema}). On an unschematised layer this
143
- * behaves like `query({ type })` with `TileProperties` properties.
144
- */
145
- byType(type) {
146
- return this.objects.filter(object => object.type === type);
147
- }
148
- /**
149
- * Objects of the given geometry {@link ObjectKind}, narrowed to that
150
- * geometry's member type (e.g. `byKind(ObjectKind.Polygon)` yields
151
- * {@link PolygonObject}s with their `points`). Returns a fresh array.
152
- */
153
- byKind(kind) {
154
- return this.objects.filter(object => object.kind === kind);
155
- }
156
- /**
157
- * Objects of `type` (typed as in {@link byType}) that also satisfy
158
- * `predicate`. A convenience combination of {@link byType} and `Array.filter`
159
- * that keeps the narrowed `properties` type inside the predicate. Returns a
160
- * fresh array.
161
- */
162
- where(type, predicate) {
163
- return this.byType(type).filter(object => predicate(object));
164
- }
165
- /** First object with the given id, or undefined. */
166
- getObjectById(id) {
167
- return this.objects.find(object => object.id === id);
168
- }
169
- /** First object with the given name, or undefined. */
170
- getObjectByName(name) {
171
- return this.objects.find(object => object.name === name);
172
- }
173
- }
47
+ * A data-only layer of {@link TileMapObject}s - spawn points, trigger zones,
48
+ * collision regions, markers. Object layers are not rendered by the tile
49
+ * renderer; they are parsed and exposed for gameplay use (e.g. building physics
50
+ * colliders, placing entities).
51
+ *
52
+ * The presentation fields the source format attaches to a layer -
53
+ * {@link visible}, {@link opacity}, {@link offsetX}/{@link offsetY},
54
+ * {@link parallaxX}/{@link parallaxY}, {@link parallaxScale}, and
55
+ * {@link tintColor} - are carried
56
+ * through in full, with any enclosing group layers' contribution already
57
+ * folded in, so an object layer describes the same placement and shading its
58
+ * neighbouring tile and image layers do. Nothing here acts on them: code that
59
+ * draws these objects itself is what applies them.
60
+ *
61
+ * Query with {@link query} (untyped, fully back-compatible) or, when an
62
+ * {@link ObjectSchema} type argument `S` is supplied, with the typed accessors
63
+ * {@link byType}, {@link byKind}, and {@link where} - these narrow `properties`
64
+ * to the developer-declared shape. The schema is **opt-in**: the default type
65
+ * parameter reproduces the original untyped behaviour, so
66
+ * `new ObjectLayer(options)` and `map.getObjectLayer('x')` are unchanged.
67
+ *
68
+ * @remarks
69
+ * A schema is a developer promise, not a runtime guarantee - Tiled data is
70
+ * untyped at runtime and ExoJS performs no validation. See {@link ObjectSchema}.
71
+ *
72
+ * @typeParam S - Optional {@link ObjectSchema} mapping object `type` strings to
73
+ * their property shapes. Defaults to a generic schema (every type maps to the
74
+ * loose {@link TileProperties} bag).
75
+ *
76
+ * @advanced
77
+ */
78
+ var ObjectLayer = class {
79
+ /** Layer-kind discriminant (distinguishes object layers from tile layers). */
80
+ kind = "object";
81
+ /** Layer id (unique within the map). */
82
+ id;
83
+ /** Layer name. */
84
+ name;
85
+ /** Layer class string. */
86
+ class;
87
+ /** Whether the layer is visible. */
88
+ visible;
89
+ /** Layer opacity in `[0, 1]`. */
90
+ opacity;
91
+ /** Layer pixel offset X. */
92
+ offsetX;
93
+ /** Layer pixel offset Y. */
94
+ offsetY;
95
+ /**
96
+ * Parallax scroll factor on the X axis - the same quantity
97
+ * {@link import('./TileLayer').TileLayer.parallaxX} carries, so an object
98
+ * layer authored beside a tile layer in the same parallax group reports the
99
+ * same factor. `1` = full camera speed, `0.5` = half speed, `0` =
100
+ * stationary. Nothing in this package applies it: object layers are
101
+ * data-only, so placing an object relative to the camera is the consumer's
102
+ * job (see {@link ObjectLayer}).
103
+ */
104
+ parallaxX;
105
+ /** Parallax scroll factor on the Y axis. See {@link ObjectLayer.parallaxX}. */
106
+ parallaxY;
107
+ /** Uniform scale applied around the layer origin by consumers that render this data-only layer. */
108
+ parallaxScale;
109
+ /**
110
+ * Multiplicative layer tint as `0xRRGGBB`, or `null` for no tint. Carried
111
+ * from the source map (including the accumulated tint of any enclosing group
112
+ * layers) for code that draws these objects itself; like
113
+ * {@link ObjectLayer.parallaxX}, nothing in this package applies it.
114
+ */
115
+ tintColor;
116
+ /** Draw order for the objects (Tiled `draworder`). Informational. */
117
+ drawOrder;
118
+ /** Immutable layer-level properties. */
119
+ properties;
120
+ /** The objects in this layer (insertion order). */
121
+ objects;
122
+ constructor(options) {
123
+ this.id = options.id;
124
+ this.name = options.name ?? "";
125
+ this.class = options.class ?? "";
126
+ this.visible = options.visible ?? true;
127
+ this.opacity = options.opacity ?? 1;
128
+ this.offsetX = options.offsetX ?? 0;
129
+ this.offsetY = options.offsetY ?? 0;
130
+ this.parallaxX = options.parallaxX ?? 1;
131
+ this.parallaxY = options.parallaxY ?? 1;
132
+ this.parallaxScale = options.parallaxScale ?? 1;
133
+ if (!Number.isFinite(this.parallaxScale) || this.parallaxScale <= 0) throw new Error("ObjectLayer parallaxScale must be a positive finite number.");
134
+ this.tintColor = options.tintColor ?? null;
135
+ this.drawOrder = options.drawOrder ?? "topdown";
136
+ this.properties = options.properties ? Object.freeze({ ...options.properties }) : Object.freeze({});
137
+ this.objects = options.objects ? Object.freeze([...options.objects]) : Object.freeze([]);
138
+ }
139
+ /** Objects matching every specified criterion of `filter`. Returns a fresh array. */
140
+ query(filter = {}) {
141
+ return this.objects.filter((object) => {
142
+ if (filter.name !== void 0 && object.name !== filter.name) return false;
143
+ if (filter.type !== void 0 && object.type !== filter.type) return false;
144
+ if (filter.kind !== void 0 && object.kind !== filter.kind) return false;
145
+ if (filter.property !== void 0) {
146
+ const value = object.properties[filter.property];
147
+ if (value === void 0) return false;
148
+ if (filter.value !== void 0 && !tilePropertyValueEquals(value, filter.value)) return false;
149
+ }
150
+ return true;
151
+ });
152
+ }
153
+ /**
154
+ * Objects whose `type` equals `type`, with `properties` narrowed to the
155
+ * schema shape `S[T]`. Returns a fresh array (insertion order).
156
+ *
157
+ * The narrowing is a static convenience only - no runtime validation is
158
+ * performed (see {@link ObjectSchema}). On an unschematised layer this
159
+ * behaves like `query({ type })` with `TileProperties` properties.
160
+ */
161
+ byType(type) {
162
+ return this.objects.filter((object) => object.type === type);
163
+ }
164
+ /**
165
+ * Objects of the given geometry {@link ObjectKind}, narrowed to that
166
+ * geometry's member type (e.g. `byKind(ObjectKind.Polygon)` yields
167
+ * {@link PolygonObject}s with their `points`). Returns a fresh array.
168
+ */
169
+ byKind(kind) {
170
+ return this.objects.filter((object) => object.kind === kind);
171
+ }
172
+ /**
173
+ * Objects of `type` (typed as in {@link byType}) that also satisfy
174
+ * `predicate`. A convenience combination of {@link byType} and `Array.filter`
175
+ * that keeps the narrowed `properties` type inside the predicate. Returns a
176
+ * fresh array.
177
+ */
178
+ where(type, predicate) {
179
+ return this.byType(type).filter((object) => predicate(object));
180
+ }
181
+ /** First object with the given id, or undefined. */
182
+ getObjectById(id) {
183
+ return this.objects.find((object) => object.id === id);
184
+ }
185
+ /** First object with the given name, or undefined. */
186
+ getObjectByName(name) {
187
+ return this.objects.find((object) => object.name === name);
188
+ }
189
+ };
174
190
 
191
+ //#endregion
175
192
  export { ObjectKind, ObjectLayer };
176
- //# sourceMappingURL=ObjectLayer.js.map
193
+ //# sourceMappingURL=ObjectLayer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ObjectLayer.js","sources":["../../../src/ObjectLayer.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ObjectLayer.js","names":[],"sources":["../../src/ObjectLayer.ts"],"sourcesContent":["import type { ResolvedTile, TileProperties, TilePropertyObjectRef, TilePropertyValue } from './types';\nimport { TilePropertyKind } from './types';\n\n/**\n * Geometry kinds for a {@link TileMapObject}, as an `as const` value object.\n *\n * Modelled as a frozen string map (not a TS `enum`) so the values stay\n * wire-compatible with the Tiled string serialisation, survive\n * `verbatimModuleSyntax` (no emitted runtime helper), and follow the package\n * convention for enum-like constants. Use the members for ergonomic, typo-safe\n * call sites: `layer.byKind(ObjectKind.Polygon)`.\n * @stable\n */\nexport const ObjectKind = {\n Rectangle: 'rectangle',\n Ellipse: 'ellipse',\n Polygon: 'polygon',\n Polyline: 'polyline',\n Point: 'point',\n Tile: 'tile',\n Text: 'text',\n} as const;\n\n/** Geometry discriminant for a {@link TileMapObject}. */\nexport type ObjectKind = (typeof ObjectKind)[keyof typeof ObjectKind];\n\n/**\n * Geometry discriminant for a {@link TileMapObject}.\n * Structural alias of {@link ObjectKind}; retained so existing code keeps\n * compiling. New code may prefer {@link ObjectKind}.\n */\nexport type TileMapObjectKind = ObjectKind;\n\n/** A point in object-layer space (pixels, relative to the object). */\nexport interface ObjectPoint {\n readonly x: number;\n readonly y: number;\n}\n\n/** Fields shared by every {@link TileMapObject} kind. */\ninterface TileMapObjectBase<P extends TileProperties = TileProperties> {\n /** Source-unique object id. */\n readonly id: number;\n /**\n * Stable string identity assigned by the authoring format, when it has one.\n *\n * LDtk sets it to the entity `iid`, which is globally unique and survives\n * re-ordering, re-export and level moves - the identity to persist in a\n * savegame. Tiled has no such field and leaves this unset; there, {@link id}\n * is the identity and it is unique only within its map.\n */\n readonly sourceId?: string;\n /** Object name (may be empty; not unique). */\n readonly name: string;\n /** Object class/type string (Tiled `type`/`class`; may be empty). */\n readonly type: string;\n /** X of the object origin in object-layer pixel space. */\n readonly x: number;\n /** Y of the object origin in object-layer pixel space. */\n readonly y: number;\n /** Bounding width in px (0 for points). */\n readonly width: number;\n /** Bounding height in px (0 for points). */\n readonly height: number;\n /**\n * Rotation in degrees, clockwise, about `(x, y)` - except on a\n * {@link TileObject}, whose pivot stays at the source format's own anchor and\n * is generally not `(x, y)`. See {@link TileObject} for why.\n */\n readonly rotation: number;\n /** Whether the object is marked visible. */\n readonly visible: boolean;\n /** Immutable custom properties. */\n readonly properties: P;\n /**\n * The raw source-format record this object was parsed from, for the rare\n * case that needs a field this model does not carry. Adapters that keep\n * their parsed document alive set it (`LdtkEntityInstance` for LDtk,\n * `TiledObject` for Tiled); a procedurally built object has none.\n *\n * Reading it ties the code to one source format - prefer the typed fields.\n */\n readonly source?: unknown;\n}\n\n/** An axis-aligned rectangle object spanning `[x, y, width, height]`. */\nexport interface RectangleObject<P extends TileProperties = TileProperties> extends TileMapObjectBase<P> {\n readonly kind: typeof ObjectKind.Rectangle;\n}\n\n/** An ellipse inscribed in `[x, y, width, height]`. */\nexport interface EllipseObject<P extends TileProperties = TileProperties> extends TileMapObjectBase<P> {\n readonly kind: typeof ObjectKind.Ellipse;\n}\n\n/** A single point at `(x, y)`. */\nexport interface PointObject<P extends TileProperties = TileProperties> extends TileMapObjectBase<P> {\n readonly kind: typeof ObjectKind.Point;\n}\n\n/** A closed polygon; `points` are relative to the object origin. */\nexport interface PolygonObject<P extends TileProperties = TileProperties> extends TileMapObjectBase<P> {\n readonly kind: typeof ObjectKind.Polygon;\n readonly points: readonly ObjectPoint[];\n}\n\n/** An open polyline; `points` are relative to the object origin. */\nexport interface PolylineObject<P extends TileProperties = TileProperties> extends TileMapObjectBase<P> {\n readonly kind: typeof ObjectKind.Polyline;\n readonly points: readonly ObjectPoint[];\n}\n\n/**\n * A tile (GID) object carrying a resolved tile reference.\n *\n * `x`/`y` are the top-left corner of the bounding box, the same convention as\n * every other object kind. Source formats that anchor a tile object elsewhere\n * normalise to the corner on import: Tiled stores the position at the\n * tileset's `objectalignment` point (bottom-left by default on an orthogonal\n * map, bottom-centre on an isometric one) and rotates the tile image about\n * that point, so a non-zero {@link TileMapObjectBase.rotation} on a tile\n * object still pivots about the source anchor rather than about `(x, y)`.\n *\n * The owning tileset's drawing offset (Tiled `tileoffset`, reachable as\n * `tile.tileset.offsetX`/`offsetY`) is likewise **not** folded into `x`/`y`.\n * Object layers are data-only, so nothing in this package draws a tile object;\n * code that does has to add that offset itself to match how a tile layer\n * places the same tile.\n */\nexport interface TileObject<P extends TileProperties = TileProperties> extends TileMapObjectBase<P> {\n readonly kind: typeof ObjectKind.Tile;\n readonly tile: ResolvedTile;\n}\n\n/** Text styling options carried by a {@link TextObject}. */\nexport interface TextStyle {\n /** The text content. */\n readonly text: string;\n /** Text colour as 0xRRGGBB, or `null` if default. */\n readonly color?: number | null;\n /** Font family name. */\n readonly fontFamily?: string;\n /** Font size in pixels. */\n readonly pixelSize?: number;\n /** Bold text. */\n readonly bold?: boolean;\n /** Italic text. */\n readonly italic?: boolean;\n /** Underline text. */\n readonly underline?: boolean;\n /** Strikeout text. */\n readonly strikeout?: boolean;\n /** Wrap text within the object bounds. */\n readonly wrap?: boolean;\n /** Horizontal alignment. */\n readonly halign?: 'left' | 'center' | 'right' | 'justify';\n /** Vertical alignment. */\n readonly valign?: 'top' | 'center' | 'bottom';\n}\n\n/** A text object carrying styled text content within `[x, y, width, height]`. */\nexport interface TextObject<P extends TileProperties = TileProperties> extends TileMapObjectBase<P> {\n readonly kind: typeof ObjectKind.Text;\n readonly text: TextStyle;\n}\n\n/**\n * A format-independent map object. The geometry kind is the discriminant;\n * narrow on `kind` to read shape-specific fields. Template objects are not\n * yet represented.\n *\n * The optional property-shape parameter `P` lets typed accessors\n * (see {@link ObjectLayer.byType}) narrow `properties` to a developer-declared\n * schema. It defaults to the generic {@link TileProperties} bag, so the plain\n * `TileMapObject` form is unchanged.\n * @advanced\n */\nexport type TileMapObject<P extends TileProperties = TileProperties> =\n RectangleObject<P> | EllipseObject<P> | PointObject<P> | PolygonObject<P> | PolylineObject<P> | TileObject<P> | TextObject<P>;\n\n/**\n * A developer-declared mapping from object `type`/class strings to the property\n * shape an object of that type is expected to carry. Supplied as the type\n * parameter to {@link ObjectLayer} to unlock the typed accessors\n * ({@link ObjectLayer.byType}, {@link ObjectLayer.where}).\n *\n * @remarks\n * A schema is a **developer promise, not a runtime guarantee.** Tiled data is\n * untyped at runtime and ExoJS performs no validation against the schema -\n * the property objects are returned exactly as parsed. The schema only refines\n * the static type of `properties` for ergonomic, typo-safe field access. If the\n * source data does not match the declared shape, reads still succeed but the\n * static type is a fiction. Validate at the boundary if you need certainty.\n *\n * @example\n * ```ts\n * const EntityType = { Spawn: 'spawn', Pickup: 'pickup' } as const;\n * interface LevelObjects {\n * [EntityType.Spawn]: { team: 'red' | 'blue' };\n * [EntityType.Pickup]: { item: 'coin' | 'gem'; amount: number };\n * }\n * const entities = map.getObjectLayer<LevelObjects>('Entities');\n * entities.byType(EntityType.Spawn)[0].properties.team; // 'red' | 'blue'\n * ```\n * @stable\n */\nexport type ObjectSchema = Record<string, TileProperties>;\n\n/**\n * A {@link TileMapObject} whose `properties` are narrowed to the schema shape\n * declared for the object `type` `T` in schema `S`.\n * @advanced\n */\nexport type TypedObject<S extends ObjectSchema, T extends keyof S & string> = TileMapObject<S[T]>;\n\n/** Filter for {@link ObjectLayer.query}. Unspecified fields match everything. */\nexport interface ObjectQuery {\n /** Match objects whose `name` equals this. */\n readonly name?: string;\n /** Match objects whose `type`/class equals this. */\n readonly type?: string;\n /** Match objects of this geometry kind. */\n readonly kind?: TileMapObjectKind;\n /** Match objects that carry this property key. */\n readonly property?: string;\n /** When combined with `property`, also require the property value to equal this. */\n readonly value?: TilePropertyValue;\n}\n\n/**\n * Type guard for the {@link TilePropertyObjectRef} variant of\n * {@link TilePropertyValue}.\n * @internal\n */\nconst isTilePropertyObjectRef = (value: TilePropertyValue): value is TilePropertyObjectRef =>\n typeof value === 'object' && value !== null && !Array.isArray(value) && (value as { kind?: unknown }).kind === TilePropertyKind.ObjectRef;\n\n/**\n * Equality used by {@link ObjectLayer.query}'s `value` filter.\n *\n * Scalars and `null` compare with `===`. `objectRef` values compare by `id`\n * alone - the one genuinely common \"find all objects referencing X\" query\n * need - regardless of differing LDtk navigation fields. Every other\n * structured shape (`point`, `tileRef`, arrays, nested property bags) has no\n * obvious value-equality semantics (exact float coordinates? array order?)\n * and only matches when reference-identical; use `query({ property })`\n * (presence-only) for those.\n * @internal\n */\nconst tilePropertyValueEquals = (a: TilePropertyValue, b: TilePropertyValue): boolean => {\n if (a === b) return true;\n if (isTilePropertyObjectRef(a) && isTilePropertyObjectRef(b)) return a.id === b.id;\n return false;\n};\n\n/** Construction options for an {@link ObjectLayer}. */\nexport interface ObjectLayerOptions {\n /** Layer id (unique within the map). */\n readonly id: number;\n /** Layer name. */\n readonly name?: string;\n /** Layer class string. */\n readonly class?: string;\n /** Whether the layer is visible. Default `true`. */\n readonly visible?: boolean;\n /** Layer opacity in `[0, 1]`. Default `1`. */\n readonly opacity?: number;\n /** Layer pixel offset X. Default `0`. */\n readonly offsetX?: number;\n /** Layer pixel offset Y. Default `0`. */\n readonly offsetY?: number;\n /**\n * Parallax scroll factor on the X axis. `1` = full camera speed (normal),\n * `0.5` = half speed (farther away), `0` = stationary. Default `1`.\n */\n readonly parallaxX?: number;\n /**\n * Parallax scroll factor on the Y axis. `1` = full camera speed (normal),\n * `0.5` = half speed (farther away), `0` = stationary. Default `1`.\n */\n readonly parallaxY?: number;\n /** Uniform parallax scale around the layer origin. Default `1`. */\n readonly parallaxScale?: number;\n /**\n * Multiplicative layer tint as a `0xRRGGBB` integer, or `null` for no tint\n * (Tiled `tintcolor`). Default `null`.\n */\n readonly tintColor?: number | null;\n /**\n * Draw order for the objects (Tiled `draworder`): `'topdown'` (sorted by `y`)\n * or `'index'` (source order). Informational; objects are stored as given.\n * Default `'topdown'`.\n */\n readonly drawOrder?: 'topdown' | 'index';\n /** The objects in this layer. */\n readonly objects?: readonly TileMapObject[];\n /** Layer-level properties (copied and frozen). */\n readonly properties?: TileProperties;\n}\n\n/**\n * A data-only layer of {@link TileMapObject}s - spawn points, trigger zones,\n * collision regions, markers. Object layers are not rendered by the tile\n * renderer; they are parsed and exposed for gameplay use (e.g. building physics\n * colliders, placing entities).\n *\n * The presentation fields the source format attaches to a layer -\n * {@link visible}, {@link opacity}, {@link offsetX}/{@link offsetY},\n * {@link parallaxX}/{@link parallaxY}, {@link parallaxScale}, and\n * {@link tintColor} - are carried\n * through in full, with any enclosing group layers' contribution already\n * folded in, so an object layer describes the same placement and shading its\n * neighbouring tile and image layers do. Nothing here acts on them: code that\n * draws these objects itself is what applies them.\n *\n * Query with {@link query} (untyped, fully back-compatible) or, when an\n * {@link ObjectSchema} type argument `S` is supplied, with the typed accessors\n * {@link byType}, {@link byKind}, and {@link where} - these narrow `properties`\n * to the developer-declared shape. The schema is **opt-in**: the default type\n * parameter reproduces the original untyped behaviour, so\n * `new ObjectLayer(options)` and `map.getObjectLayer('x')` are unchanged.\n *\n * @remarks\n * A schema is a developer promise, not a runtime guarantee - Tiled data is\n * untyped at runtime and ExoJS performs no validation. See {@link ObjectSchema}.\n *\n * @typeParam S - Optional {@link ObjectSchema} mapping object `type` strings to\n * their property shapes. Defaults to a generic schema (every type maps to the\n * loose {@link TileProperties} bag).\n *\n * @advanced\n */\nexport class ObjectLayer<S extends ObjectSchema = ObjectSchema> {\n /** Layer-kind discriminant (distinguishes object layers from tile layers). */\n public readonly kind = 'object' as const;\n\n /** Layer id (unique within the map). */\n public readonly id: number;\n /** Layer name. */\n public readonly name: string;\n /** Layer class string. */\n public readonly class: string;\n /** Whether the layer is visible. */\n public readonly visible: boolean;\n /** Layer opacity in `[0, 1]`. */\n public readonly opacity: number;\n /** Layer pixel offset X. */\n public readonly offsetX: number;\n /** Layer pixel offset Y. */\n public readonly offsetY: number;\n /**\n * Parallax scroll factor on the X axis - the same quantity\n * {@link import('./TileLayer').TileLayer.parallaxX} carries, so an object\n * layer authored beside a tile layer in the same parallax group reports the\n * same factor. `1` = full camera speed, `0.5` = half speed, `0` =\n * stationary. Nothing in this package applies it: object layers are\n * data-only, so placing an object relative to the camera is the consumer's\n * job (see {@link ObjectLayer}).\n */\n public readonly parallaxX: number;\n /** Parallax scroll factor on the Y axis. See {@link ObjectLayer.parallaxX}. */\n public readonly parallaxY: number;\n /** Uniform scale applied around the layer origin by consumers that render this data-only layer. */\n public readonly parallaxScale: number;\n /**\n * Multiplicative layer tint as `0xRRGGBB`, or `null` for no tint. Carried\n * from the source map (including the accumulated tint of any enclosing group\n * layers) for code that draws these objects itself; like\n * {@link ObjectLayer.parallaxX}, nothing in this package applies it.\n */\n public readonly tintColor: number | null;\n /** Draw order for the objects (Tiled `draworder`). Informational. */\n public readonly drawOrder: 'topdown' | 'index';\n /** Immutable layer-level properties. */\n public readonly properties: TileProperties;\n /** The objects in this layer (insertion order). */\n public readonly objects: readonly TileMapObject[];\n\n public constructor(options: ObjectLayerOptions) {\n this.id = options.id;\n this.name = options.name ?? '';\n this.class = options.class ?? '';\n this.visible = options.visible ?? true;\n this.opacity = options.opacity ?? 1;\n this.offsetX = options.offsetX ?? 0;\n this.offsetY = options.offsetY ?? 0;\n this.parallaxX = options.parallaxX ?? 1;\n this.parallaxY = options.parallaxY ?? 1;\n this.parallaxScale = options.parallaxScale ?? 1;\n if (!Number.isFinite(this.parallaxScale) || this.parallaxScale <= 0) {\n throw new Error('ObjectLayer parallaxScale must be a positive finite number.');\n }\n this.tintColor = options.tintColor ?? null;\n this.drawOrder = options.drawOrder ?? 'topdown';\n this.properties = options.properties ? Object.freeze({ ...options.properties }) : Object.freeze({});\n this.objects = options.objects ? Object.freeze([...options.objects]) : Object.freeze([]);\n }\n\n /** Objects matching every specified criterion of `filter`. Returns a fresh array. */\n public query(filter: ObjectQuery = {}): TileMapObject[] {\n return this.objects.filter(object => {\n if (filter.name !== undefined && object.name !== filter.name) {\n return false;\n }\n\n if (filter.type !== undefined && object.type !== filter.type) {\n return false;\n }\n\n if (filter.kind !== undefined && object.kind !== filter.kind) {\n return false;\n }\n\n if (filter.property !== undefined) {\n // TilePropertyValue never includes `undefined`, so an `undefined`\n // read is a reliable \"key absent\" signal (equivalent to, but avoids\n // re-indexing after, an `in` check).\n const value = object.properties[filter.property];\n if (value === undefined) {\n return false;\n }\n\n if (filter.value !== undefined && !tilePropertyValueEquals(value, filter.value)) {\n return false;\n }\n }\n\n return true;\n });\n }\n\n /**\n * Objects whose `type` equals `type`, with `properties` narrowed to the\n * schema shape `S[T]`. Returns a fresh array (insertion order).\n *\n * The narrowing is a static convenience only - no runtime validation is\n * performed (see {@link ObjectSchema}). On an unschematised layer this\n * behaves like `query({ type })` with `TileProperties` properties.\n */\n public byType<T extends keyof S & string>(type: T): Array<TypedObject<S, T>> {\n return this.objects.filter(object => object.type === type) as unknown as Array<TypedObject<S, T>>;\n }\n\n /**\n * Objects of the given geometry {@link ObjectKind}, narrowed to that\n * geometry's member type (e.g. `byKind(ObjectKind.Polygon)` yields\n * {@link PolygonObject}s with their `points`). Returns a fresh array.\n */\n public byKind<K extends ObjectKind>(kind: K): Array<Extract<TileMapObject, { kind: K }>> {\n return this.objects.filter(object => object.kind === kind) as Array<Extract<TileMapObject, { kind: K }>>;\n }\n\n /**\n * Objects of `type` (typed as in {@link byType}) that also satisfy\n * `predicate`. A convenience combination of {@link byType} and `Array.filter`\n * that keeps the narrowed `properties` type inside the predicate. Returns a\n * fresh array.\n */\n public where<T extends keyof S & string>(type: T, predicate: (object: TypedObject<S, T>) => boolean): Array<TypedObject<S, T>> {\n return this.byType(type).filter(object => predicate(object));\n }\n\n /** First object with the given id, or undefined. */\n public getObjectById(id: number): TileMapObject | undefined {\n return this.objects.find(object => object.id === id);\n }\n\n /** First object with the given name, or undefined. */\n public getObjectByName(name: string): TileMapObject | undefined {\n return this.objects.find(object => object.name === name);\n }\n}\n"],"mappings":"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"}