@codexo/exojs-tilemap 0.13.0 → 0.15.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 (59) hide show
  1. package/dist/esm/ImageLayer.d.ts +81 -0
  2. package/dist/esm/ImageLayer.js +67 -0
  3. package/dist/esm/ImageLayer.js.map +1 -0
  4. package/dist/esm/ObjectLayer.d.ts +277 -0
  5. package/dist/esm/ObjectLayer.js +176 -0
  6. package/dist/esm/ObjectLayer.js.map +1 -0
  7. package/dist/esm/TileAnimator.d.ts +62 -0
  8. package/dist/esm/TileAnimator.js +169 -0
  9. package/dist/esm/TileAnimator.js.map +1 -0
  10. package/dist/esm/TileChunk.js.map +1 -1
  11. package/dist/esm/TileChunkNode.d.ts +1 -1
  12. package/dist/esm/TileChunkNode.js +1 -1
  13. package/dist/esm/TileLayer.d.ts +33 -2
  14. package/dist/esm/TileLayer.js +26 -2
  15. package/dist/esm/TileLayer.js.map +1 -1
  16. package/dist/esm/TileLayerNode.d.ts +10 -3
  17. package/dist/esm/TileLayerNode.js +35 -7
  18. package/dist/esm/TileLayerNode.js.map +1 -1
  19. package/dist/esm/TileMap.d.ts +71 -1
  20. package/dist/esm/TileMap.js +100 -1
  21. package/dist/esm/TileMap.js.map +1 -1
  22. package/dist/esm/TileMapBand.d.ts +6 -3
  23. package/dist/esm/TileMapBand.js +7 -6
  24. package/dist/esm/TileMapBand.js.map +1 -1
  25. package/dist/esm/TileMapNode.d.ts +1 -1
  26. package/dist/esm/TileMapView.d.ts +1 -1
  27. package/dist/esm/TileMapView.js.map +1 -1
  28. package/dist/esm/TileSet.d.ts +12 -0
  29. package/dist/esm/TileSet.js +30 -2
  30. package/dist/esm/TileSet.js.map +1 -1
  31. package/dist/esm/WangSet.d.ts +79 -0
  32. package/dist/esm/WangSet.js +81 -0
  33. package/dist/esm/WangSet.js.map +1 -0
  34. package/dist/esm/autoTile.d.ts +83 -0
  35. package/dist/esm/autoTile.js +214 -0
  36. package/dist/esm/autoTile.js.map +1 -0
  37. package/dist/esm/chunkGeometry.js +4 -3
  38. package/dist/esm/chunkGeometry.js.map +1 -1
  39. package/dist/esm/index.js +6 -1
  40. package/dist/esm/index.js.map +1 -1
  41. package/dist/esm/pixelSnap.d.ts +1 -1
  42. package/dist/esm/public.d.ts +11 -2
  43. package/dist/esm/register.js +6 -1
  44. package/dist/esm/register.js.map +1 -1
  45. package/dist/esm/tilemapExtension.d.ts +4 -3
  46. package/dist/esm/tilemapExtension.js +8 -4
  47. package/dist/esm/tilemapExtension.js.map +1 -1
  48. package/dist/esm/tilemapSerializers.d.ts +19 -0
  49. package/dist/esm/tilemapSerializers.js +47 -0
  50. package/dist/esm/tilemapSerializers.js.map +1 -0
  51. package/dist/esm/types.d.ts +86 -4
  52. package/dist/esm/types.js +18 -1
  53. package/dist/esm/types.js.map +1 -1
  54. package/dist/esm/webgl2/WebGl2TileChunkRenderer.d.ts +2 -2
  55. package/dist/esm/webgl2/WebGl2TileChunkRenderer.js +1 -1
  56. package/dist/esm/webgl2/WebGl2TileChunkRenderer.js.map +1 -1
  57. package/dist/esm/webgpu/WebGpuTileChunkRenderer.d.ts +2 -2
  58. package/dist/esm/webgpu/WebGpuTileChunkRenderer.js +1 -1
  59. package/package.json +8 -3
@@ -0,0 +1,81 @@
1
+ import type { Texture } from '@codexo/exojs';
2
+ import type { TileProperties } from './types';
3
+ /** Construction options for an {@link ImageLayer}. */
4
+ export interface ImageLayerOptions {
5
+ /** Layer id (unique within the map). */
6
+ readonly id: number;
7
+ /** Layer name. */
8
+ readonly name?: string;
9
+ /** Layer class string. */
10
+ readonly class?: string;
11
+ /** Resolved image URL. */
12
+ readonly image: string;
13
+ /** Loaded texture for the image, or `null` if unavailable. */
14
+ readonly texture?: Texture | null;
15
+ /** Whether the layer is visible. Default `true`. */
16
+ readonly visible?: boolean;
17
+ /** Layer opacity in `[0, 1]`. Default `1`. */
18
+ readonly opacity?: number;
19
+ /** Layer pixel offset X. Default `0`. */
20
+ readonly offsetX?: number;
21
+ /** Layer pixel offset Y. Default `0`. */
22
+ readonly offsetY?: number;
23
+ /** Horizontal parallax factor. Default `1`. */
24
+ readonly parallaxX?: number;
25
+ /** Vertical parallax factor. Default `1`. */
26
+ readonly parallaxY?: number;
27
+ /** Tint colour as `0xRRGGBB`, or `null`. Default `null`. */
28
+ readonly tintColor?: number | null;
29
+ /** Whether the image repeats horizontally. Default `false`. */
30
+ readonly repeatX?: boolean;
31
+ /** Whether the image repeats vertically. Default `false`. */
32
+ readonly repeatY?: boolean;
33
+ /** Layer properties (copied and frozen). */
34
+ readonly properties?: TileProperties;
35
+ }
36
+ /**
37
+ * A data-only image layer: a single image (texture + resolved URL) placed as a
38
+ * background or foreground layer. Image layers are not rendered by the tile
39
+ * renderer — they are exposed as data for a renderer or follow-up scene node to
40
+ * consume.
41
+ *
42
+ * Parallax, opacity, tint, offset, and repeat flags are carried from the
43
+ * source Tiled map.
44
+ *
45
+ * @advanced
46
+ */
47
+ export declare class ImageLayer {
48
+ /** Layer-kind discriminant. */
49
+ readonly kind: "image";
50
+ /** Layer id (unique within the map). */
51
+ readonly id: number;
52
+ /** Layer name. */
53
+ readonly name: string;
54
+ /** Layer class string. */
55
+ readonly class: string;
56
+ /** Resolved URL of the layer image. */
57
+ readonly image: string;
58
+ /** Loaded texture for the image, or `null` if unavailable. */
59
+ readonly texture: Texture | null;
60
+ /** Whether the layer is visible. */
61
+ readonly visible: boolean;
62
+ /** Layer opacity in `[0, 1]`. */
63
+ readonly opacity: number;
64
+ /** Layer pixel offset X. */
65
+ readonly offsetX: number;
66
+ /** Layer pixel offset Y. */
67
+ readonly offsetY: number;
68
+ /** Horizontal parallax factor. */
69
+ readonly parallaxX: number;
70
+ /** Vertical parallax factor. */
71
+ readonly parallaxY: number;
72
+ /** Tint colour as `0xRRGGBB`, or `null`. */
73
+ readonly tintColor: number | null;
74
+ /** Whether the image repeats horizontally. */
75
+ readonly repeatX: boolean;
76
+ /** Whether the image repeats vertically. */
77
+ readonly repeatY: boolean;
78
+ /** Immutable layer properties. */
79
+ readonly properties: TileProperties;
80
+ constructor(options: ImageLayerOptions);
81
+ }
@@ -0,0 +1,67 @@
1
+ /**
2
+ * A data-only image layer: a single image (texture + resolved URL) placed as a
3
+ * background or foreground layer. Image layers are not rendered by the tile
4
+ * renderer — they are exposed as data for a renderer or follow-up scene node to
5
+ * consume.
6
+ *
7
+ * Parallax, opacity, tint, offset, and repeat flags are carried from the
8
+ * source Tiled map.
9
+ *
10
+ * @advanced
11
+ */
12
+ class ImageLayer {
13
+ /** Layer-kind discriminant. */
14
+ kind = 'image';
15
+ /** Layer id (unique within the map). */
16
+ id;
17
+ /** Layer name. */
18
+ name;
19
+ /** Layer class string. */
20
+ class;
21
+ /** Resolved URL of the layer image. */
22
+ image;
23
+ /** Loaded texture for the image, or `null` if unavailable. */
24
+ texture;
25
+ /** Whether the layer is visible. */
26
+ visible;
27
+ /** Layer opacity in `[0, 1]`. */
28
+ opacity;
29
+ /** Layer pixel offset X. */
30
+ offsetX;
31
+ /** Layer pixel offset Y. */
32
+ offsetY;
33
+ /** Horizontal parallax factor. */
34
+ parallaxX;
35
+ /** Vertical parallax factor. */
36
+ parallaxY;
37
+ /** Tint colour as `0xRRGGBB`, or `null`. */
38
+ tintColor;
39
+ /** Whether the image repeats horizontally. */
40
+ repeatX;
41
+ /** Whether the image repeats vertically. */
42
+ repeatY;
43
+ /** Immutable layer properties. */
44
+ properties;
45
+ constructor(options) {
46
+ this.id = options.id;
47
+ this.name = options.name ?? '';
48
+ this.class = options.class ?? '';
49
+ this.image = options.image;
50
+ this.texture = options.texture ?? null;
51
+ this.visible = options.visible ?? true;
52
+ this.opacity = options.opacity ?? 1;
53
+ this.offsetX = options.offsetX ?? 0;
54
+ this.offsetY = options.offsetY ?? 0;
55
+ this.parallaxX = options.parallaxX ?? 1;
56
+ this.parallaxY = options.parallaxY ?? 1;
57
+ this.tintColor = options.tintColor ?? null;
58
+ this.repeatX = options.repeatX ?? false;
59
+ this.repeatY = options.repeatY ?? false;
60
+ this.properties = options.properties
61
+ ? Object.freeze({ ...options.properties })
62
+ : Object.freeze({});
63
+ }
64
+ }
65
+
66
+ export { ImageLayer };
67
+ //# sourceMappingURL=ImageLayer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImageLayer.js","sources":["../../../src/ImageLayer.ts"],"sourcesContent":[null],"names":[],"mappings":"AAsCA;;;;;;;;;;AAUG;MACU,UAAU,CAAA;;IAEL,IAAI,GAAG,OAAgB;;AAGvB,IAAA,EAAE;;AAEF,IAAA,IAAI;;AAEJ,IAAA,KAAK;;AAEL,IAAA,KAAK;;AAEL,IAAA,OAAO;;AAEP,IAAA,OAAO;;AAEP,IAAA,OAAO;;AAEP,IAAA,OAAO;;AAEP,IAAA,OAAO;;AAEP,IAAA,SAAS;;AAET,IAAA,SAAS;;AAET,IAAA,SAAS;;AAET,IAAA,OAAO;;AAEP,IAAA,OAAO;;AAEP,IAAA,UAAU;AAE1B,IAAA,WAAA,CAAmB,OAA0B,EAAA;AAC3C,QAAA,IAAI,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE;QACpB,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,EAAE;QAC9B,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE;AAChC,QAAA,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK;QAC1B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,IAAI;QACtC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,IAAI;QACtC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,CAAC;QACnC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,CAAC;QACnC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,CAAC;QACnC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,CAAC;QACvC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,CAAC;QACvC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI;QAC1C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,KAAK;QACvC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,KAAK;AACvC,QAAA,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC;cACtB,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE;AACzC,cAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;IACvB;AACD;;;;"}
@@ -0,0 +1,277 @@
1
+ import type { ResolvedTile, TileProperties, TilePropertyValue } from './types';
2
+ /**
3
+ * Geometry kinds for a {@link TileMapObject}, as an `as const` value object.
4
+ *
5
+ * Modelled as a frozen string map (not a TS `enum`) so the values stay
6
+ * wire-compatible with the Tiled string serialisation, survive
7
+ * `verbatimModuleSyntax` (no emitted runtime helper), and follow the package
8
+ * convention for enum-like constants. Use the members for ergonomic, typo-safe
9
+ * call sites: `layer.byKind(ObjectKind.Polygon)`.
10
+ * @stable
11
+ */
12
+ export declare const ObjectKind: {
13
+ readonly Rectangle: "rectangle";
14
+ readonly Ellipse: "ellipse";
15
+ readonly Polygon: "polygon";
16
+ readonly Polyline: "polyline";
17
+ readonly Point: "point";
18
+ readonly Tile: "tile";
19
+ readonly Text: "text";
20
+ };
21
+ /** Geometry discriminant for a {@link TileMapObject}. */
22
+ export type ObjectKind = (typeof ObjectKind)[keyof typeof ObjectKind];
23
+ /**
24
+ * Geometry discriminant for a {@link TileMapObject}.
25
+ * Structural alias of {@link ObjectKind}; retained so existing code keeps
26
+ * compiling. New code may prefer {@link ObjectKind}.
27
+ */
28
+ export type TileMapObjectKind = ObjectKind;
29
+ /** A point in object-layer space (pixels, relative to the object). */
30
+ export interface ObjectPoint {
31
+ readonly x: number;
32
+ readonly y: number;
33
+ }
34
+ /** Fields shared by every {@link TileMapObject} kind. */
35
+ interface TileMapObjectBase<P extends TileProperties = TileProperties> {
36
+ /** Source-unique object id. */
37
+ readonly id: number;
38
+ /** Object name (may be empty; not unique). */
39
+ readonly name: string;
40
+ /** Object class/type string (Tiled `type`/`class`; may be empty). */
41
+ readonly type: string;
42
+ /** X of the object origin in object-layer pixel space. */
43
+ readonly x: number;
44
+ /** Y of the object origin in object-layer pixel space. */
45
+ readonly y: number;
46
+ /** Bounding width in px (0 for points). */
47
+ readonly width: number;
48
+ /** Bounding height in px (0 for points). */
49
+ readonly height: number;
50
+ /** Rotation in degrees, clockwise, about the object origin. */
51
+ readonly rotation: number;
52
+ /** Whether the object is marked visible. */
53
+ readonly visible: boolean;
54
+ /** Immutable custom properties. */
55
+ readonly properties: P;
56
+ }
57
+ /** An axis-aligned rectangle object spanning `[x, y, width, height]`. */
58
+ export interface RectangleObject<P extends TileProperties = TileProperties> extends TileMapObjectBase<P> {
59
+ readonly kind: typeof ObjectKind.Rectangle;
60
+ }
61
+ /** An ellipse inscribed in `[x, y, width, height]`. */
62
+ export interface EllipseObject<P extends TileProperties = TileProperties> extends TileMapObjectBase<P> {
63
+ readonly kind: typeof ObjectKind.Ellipse;
64
+ }
65
+ /** A single point at `(x, y)`. */
66
+ export interface PointObject<P extends TileProperties = TileProperties> extends TileMapObjectBase<P> {
67
+ readonly kind: typeof ObjectKind.Point;
68
+ }
69
+ /** A closed polygon; `points` are relative to the object origin. */
70
+ export interface PolygonObject<P extends TileProperties = TileProperties> extends TileMapObjectBase<P> {
71
+ readonly kind: typeof ObjectKind.Polygon;
72
+ readonly points: readonly ObjectPoint[];
73
+ }
74
+ /** An open polyline; `points` are relative to the object origin. */
75
+ export interface PolylineObject<P extends TileProperties = TileProperties> extends TileMapObjectBase<P> {
76
+ readonly kind: typeof ObjectKind.Polyline;
77
+ readonly points: readonly ObjectPoint[];
78
+ }
79
+ /** A tile (GID) object carrying a resolved tile reference. */
80
+ export interface TileObject<P extends TileProperties = TileProperties> extends TileMapObjectBase<P> {
81
+ readonly kind: typeof ObjectKind.Tile;
82
+ readonly tile: ResolvedTile;
83
+ }
84
+ /** Text styling options carried by a {@link TextObject}. */
85
+ export interface TextStyle {
86
+ /** The text content. */
87
+ readonly text: string;
88
+ /** Text colour as 0xRRGGBB, or `null` if default. */
89
+ readonly color?: number | null;
90
+ /** Font family name. */
91
+ readonly fontFamily?: string;
92
+ /** Font size in pixels. */
93
+ readonly pixelSize?: number;
94
+ /** Bold text. */
95
+ readonly bold?: boolean;
96
+ /** Italic text. */
97
+ readonly italic?: boolean;
98
+ /** Underline text. */
99
+ readonly underline?: boolean;
100
+ /** Strikeout text. */
101
+ readonly strikeout?: boolean;
102
+ /** Wrap text within the object bounds. */
103
+ readonly wrap?: boolean;
104
+ /** Horizontal alignment. */
105
+ readonly halign?: 'left' | 'center' | 'right' | 'justify';
106
+ /** Vertical alignment. */
107
+ readonly valign?: 'top' | 'center' | 'bottom';
108
+ }
109
+ /** A text object carrying styled text content within `[x, y, width, height]`. */
110
+ export interface TextObject<P extends TileProperties = TileProperties> extends TileMapObjectBase<P> {
111
+ readonly kind: typeof ObjectKind.Text;
112
+ readonly text: TextStyle;
113
+ }
114
+ /**
115
+ * A format-independent map object. The geometry kind is the discriminant;
116
+ * narrow on `kind` to read shape-specific fields. Template objects are not
117
+ * yet represented.
118
+ *
119
+ * The optional property-shape parameter `P` lets typed accessors
120
+ * (see {@link ObjectLayer.byType}) narrow `properties` to a developer-declared
121
+ * schema. It defaults to the generic {@link TileProperties} bag, so the plain
122
+ * `TileMapObject` form is unchanged.
123
+ * @advanced
124
+ */
125
+ export type TileMapObject<P extends TileProperties = TileProperties> = RectangleObject<P> | EllipseObject<P> | PointObject<P> | PolygonObject<P> | PolylineObject<P> | TileObject<P> | TextObject<P>;
126
+ /**
127
+ * A developer-declared mapping from object `type`/class strings to the property
128
+ * shape an object of that type is expected to carry. Supplied as the type
129
+ * parameter to {@link ObjectLayer} to unlock the typed accessors
130
+ * ({@link ObjectLayer.byType}, {@link ObjectLayer.where}).
131
+ *
132
+ * @remarks
133
+ * 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 —
135
+ * the property objects are returned exactly as parsed. The schema only refines
136
+ * the static type of `properties` for ergonomic, typo-safe field access. If the
137
+ * source data does not match the declared shape, reads still succeed but the
138
+ * static type is a fiction. Validate at the boundary if you need certainty.
139
+ *
140
+ * @example
141
+ * ```ts
142
+ * const EntityType = { Spawn: 'spawn', Pickup: 'pickup' } as const;
143
+ * interface LevelObjects {
144
+ * [EntityType.Spawn]: { team: 'red' | 'blue' };
145
+ * [EntityType.Pickup]: { item: 'coin' | 'gem'; amount: number };
146
+ * }
147
+ * const entities = map.getObjectLayer<LevelObjects>('Entities');
148
+ * entities.byType(EntityType.Spawn)[0].properties.team; // 'red' | 'blue'
149
+ * ```
150
+ * @stable
151
+ */
152
+ export type ObjectSchema = Record<string, TileProperties>;
153
+ /**
154
+ * A {@link TileMapObject} whose `properties` are narrowed to the schema shape
155
+ * declared for the object `type` `T` in schema `S`.
156
+ * @advanced
157
+ */
158
+ export type TypedObject<S extends ObjectSchema, T extends keyof S & string> = TileMapObject<S[T]>;
159
+ /** Filter for {@link ObjectLayer.query}. Unspecified fields match everything. */
160
+ export interface ObjectQuery {
161
+ /** Match objects whose `name` equals this. */
162
+ readonly name?: string;
163
+ /** Match objects whose `type`/class equals this. */
164
+ readonly type?: string;
165
+ /** Match objects of this geometry kind. */
166
+ readonly kind?: TileMapObjectKind;
167
+ /** Match objects that carry this property key. */
168
+ readonly property?: string;
169
+ /** When combined with `property`, also require the property value to equal this. */
170
+ readonly value?: TilePropertyValue;
171
+ }
172
+ /** Construction options for an {@link ObjectLayer}. */
173
+ export interface ObjectLayerOptions {
174
+ /** Layer id (unique within the map). */
175
+ readonly id: number;
176
+ /** Layer name. */
177
+ readonly name?: string;
178
+ /** Layer class string. */
179
+ readonly class?: string;
180
+ /** Whether the layer is visible. Default `true`. */
181
+ readonly visible?: boolean;
182
+ /** Layer opacity in `[0, 1]`. Default `1`. */
183
+ readonly opacity?: number;
184
+ /** Layer pixel offset X. Default `0`. */
185
+ readonly offsetX?: number;
186
+ /** Layer pixel offset Y. Default `0`. */
187
+ readonly offsetY?: number;
188
+ /**
189
+ * Draw order for the objects (Tiled `draworder`): `'topdown'` (sorted by `y`)
190
+ * or `'index'` (source order). Informational; objects are stored as given.
191
+ * Default `'topdown'`.
192
+ */
193
+ readonly drawOrder?: 'topdown' | 'index';
194
+ /** The objects in this layer. */
195
+ readonly objects?: readonly TileMapObject[];
196
+ /** Layer-level properties (copied and frozen). */
197
+ readonly properties?: TileProperties;
198
+ }
199
+ /**
200
+ * A data-only layer of {@link TileMapObject}s — spawn points, trigger zones,
201
+ * collision regions, markers. Object layers are not rendered by the tile
202
+ * renderer; they are parsed and exposed for gameplay use (e.g. building physics
203
+ * colliders, placing entities).
204
+ *
205
+ * Query with {@link query} (untyped, fully back-compatible) or, when an
206
+ * {@link ObjectSchema} type argument `S` is supplied, with the typed accessors
207
+ * {@link byType}, {@link byKind}, and {@link where} — these narrow `properties`
208
+ * to the developer-declared shape. The schema is **opt-in**: the default type
209
+ * parameter reproduces the original untyped behaviour, so
210
+ * `new ObjectLayer(options)` and `map.getObjectLayer('x')` are unchanged.
211
+ *
212
+ * @remarks
213
+ * A schema is a developer promise, not a runtime guarantee — Tiled data is
214
+ * untyped at runtime and ExoJS performs no validation. See {@link ObjectSchema}.
215
+ *
216
+ * @typeParam S - Optional {@link ObjectSchema} mapping object `type` strings to
217
+ * their property shapes. Defaults to a generic schema (every type maps to the
218
+ * loose {@link TileProperties} bag).
219
+ *
220
+ * @advanced
221
+ */
222
+ export declare class ObjectLayer<S extends ObjectSchema = ObjectSchema> {
223
+ /** Layer-kind discriminant (distinguishes object layers from tile layers). */
224
+ readonly kind: "object";
225
+ /** Layer id (unique within the map). */
226
+ readonly id: number;
227
+ /** Layer name. */
228
+ readonly name: string;
229
+ /** Layer class string. */
230
+ readonly class: string;
231
+ /** Whether the layer is visible. */
232
+ readonly visible: boolean;
233
+ /** Layer opacity in `[0, 1]`. */
234
+ readonly opacity: number;
235
+ /** Layer pixel offset X. */
236
+ readonly offsetX: number;
237
+ /** Layer pixel offset Y. */
238
+ readonly offsetY: number;
239
+ /** Draw order for the objects (Tiled `draworder`). Informational. */
240
+ readonly drawOrder: 'topdown' | 'index';
241
+ /** Immutable layer-level properties. */
242
+ readonly properties: TileProperties;
243
+ /** The objects in this layer (insertion order). */
244
+ readonly objects: readonly TileMapObject[];
245
+ constructor(options: ObjectLayerOptions);
246
+ /** Objects matching every specified criterion of `filter`. Returns a fresh array. */
247
+ query(filter?: ObjectQuery): TileMapObject[];
248
+ /**
249
+ * Objects whose `type` equals `type`, with `properties` narrowed to the
250
+ * schema shape `S[T]`. Returns a fresh array (insertion order).
251
+ *
252
+ * The narrowing is a static convenience only — no runtime validation is
253
+ * performed (see {@link ObjectSchema}). On an unschematised layer this
254
+ * behaves like `query({ type })` with `TileProperties` properties.
255
+ */
256
+ byType<T extends keyof S & string>(type: T): Array<TypedObject<S, T>>;
257
+ /**
258
+ * Objects of the given geometry {@link ObjectKind}, narrowed to that
259
+ * geometry's member type (e.g. `byKind(ObjectKind.Polygon)` yields
260
+ * {@link PolygonObject}s with their `points`). Returns a fresh array.
261
+ */
262
+ byKind<K extends ObjectKind>(kind: K): Array<Extract<TileMapObject, {
263
+ kind: K;
264
+ }>>;
265
+ /**
266
+ * Objects of `type` (typed as in {@link byType}) that also satisfy
267
+ * `predicate`. A convenience combination of {@link byType} and `Array.filter`
268
+ * that keeps the narrowed `properties` type inside the predicate. Returns a
269
+ * fresh array.
270
+ */
271
+ where<T extends keyof S & string>(type: T, predicate: (object: TypedObject<S, T>) => boolean): Array<TypedObject<S, T>>;
272
+ /** First object with the given id, or undefined. */
273
+ getObjectById(id: number): TileMapObject | undefined;
274
+ /** First object with the given name, or undefined. */
275
+ getObjectByName(name: string): TileMapObject | undefined;
276
+ }
277
+ export {};
@@ -0,0 +1,176 @@
1
+ import { TilePropertyKind } from './types.js';
2
+
3
+ /**
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
+ */
13
+ const ObjectKind = {
14
+ Rectangle: 'rectangle',
15
+ Ellipse: 'ellipse',
16
+ Polygon: 'polygon',
17
+ Polyline: 'polyline',
18
+ Point: 'point',
19
+ Tile: 'tile',
20
+ Text: 'text',
21
+ };
22
+ /**
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
+ }
33
+ /**
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
+ }
52
+ /**
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
+ }
174
+
175
+ export { ObjectKind, ObjectLayer };
176
+ //# sourceMappingURL=ObjectLayer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ObjectLayer.js","sources":["../../../src/ObjectLayer.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ import type { TileLayer } from './TileLayer';
2
+ /**
3
+ * Drives per-tile animations on one or more {@link TileLayer}s, RPG-Maker style.
4
+ *
5
+ * On construction it scans the given layer(s) once and registers every cell
6
+ * whose tile carries an `animation` (see {@link import('./types').TileDefinition}).
7
+ * Each {@link update} advances a shared clock and rewrites **only** the
8
+ * registered animated cells, and **only** when a cell crosses a frame boundary —
9
+ * static tiles are never touched. Because a tile rewrite goes through
10
+ * `layer.setTileAt`, only the chunks that actually contain animated cells rebuild
11
+ * their geometry, and only on the (infrequent) frames where a boundary is
12
+ * crossed. The large static body of the map never rebuilds.
13
+ *
14
+ * Tick it from your update loop, like `TweenSequencer`:
15
+ *
16
+ * ```ts
17
+ * const animator = new TileAnimator(map.layers);
18
+ * scene.systems.add({ update: (t) => animator.update(t.deltaSeconds) });
19
+ * ```
20
+ *
21
+ * The animator references — but never owns — the layers and their tilesets;
22
+ * {@link destroy} only drops its own cell registry.
23
+ *
24
+ * @advanced
25
+ */
26
+ export declare class TileAnimator {
27
+ private readonly _layers;
28
+ private _cells;
29
+ private _elapsedMs;
30
+ /**
31
+ * @param layers One layer, or an array of layers (e.g. `map.layers`), to scan
32
+ * for animated tiles.
33
+ */
34
+ constructor(layers: TileLayer | readonly TileLayer[]);
35
+ /** Number of animated cells currently registered across all layers. */
36
+ get animatedCellCount(): number;
37
+ /** Total elapsed animation time in milliseconds since construction/reset. */
38
+ get elapsedMs(): number;
39
+ /**
40
+ * Advance all registered animations by `deltaSeconds` and write the current
41
+ * frame into any cell that crossed a frame boundary. Cells that did not change
42
+ * frame are not touched, so their chunks do not rebuild.
43
+ *
44
+ * @param deltaSeconds Elapsed wall-clock time since the last call, in seconds.
45
+ */
46
+ update(deltaSeconds: number): void;
47
+ /**
48
+ * Restore every animated cell to its first frame and reset the clock.
49
+ * Useful before serialising or pausing.
50
+ */
51
+ reset(): void;
52
+ /**
53
+ * Re-scan the layers for animated cells. Call after structural edits that add
54
+ * or remove animated tiles. Resets all currently-tracked cells to frame 0
55
+ * first so the rescan starts from a clean, deterministic state.
56
+ */
57
+ rescan(): void;
58
+ /** Drop the cell registry. Does not modify the layers or tilesets. */
59
+ destroy(): void;
60
+ /** Scan all layers for cells whose tile carries a (multi-frame) animation. */
61
+ private _scan;
62
+ }