@codexo/exojs-tilemap 0.14.0 → 0.15.1

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.
@@ -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;;;;"}
@@ -16,6 +16,7 @@ export declare const ObjectKind: {
16
16
  readonly Polyline: "polyline";
17
17
  readonly Point: "point";
18
18
  readonly Tile: "tile";
19
+ readonly Text: "text";
19
20
  };
20
21
  /** Geometry discriminant for a {@link TileMapObject}. */
21
22
  export type ObjectKind = (typeof ObjectKind)[keyof typeof ObjectKind];
@@ -80,10 +81,40 @@ export interface TileObject<P extends TileProperties = TileProperties> extends T
80
81
  readonly kind: typeof ObjectKind.Tile;
81
82
  readonly tile: ResolvedTile;
82
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
+ }
83
114
  /**
84
115
  * A format-independent map object. The geometry kind is the discriminant;
85
- * narrow on `kind` to read shape-specific fields. Text objects and templates
86
- * are intentionally not represented (data-only release).
116
+ * narrow on `kind` to read shape-specific fields. Template objects are not
117
+ * yet represented.
87
118
  *
88
119
  * The optional property-shape parameter `P` lets typed accessors
89
120
  * (see {@link ObjectLayer.byType}) narrow `properties` to a developer-declared
@@ -91,7 +122,7 @@ export interface TileObject<P extends TileProperties = TileProperties> extends T
91
122
  * `TileMapObject` form is unchanged.
92
123
  * @advanced
93
124
  */
94
- export type TileMapObject<P extends TileProperties = TileProperties> = RectangleObject<P> | EllipseObject<P> | PointObject<P> | PolygonObject<P> | PolylineObject<P> | TileObject<P>;
125
+ export type TileMapObject<P extends TileProperties = TileProperties> = RectangleObject<P> | EllipseObject<P> | PointObject<P> | PolygonObject<P> | PolylineObject<P> | TileObject<P> | TextObject<P>;
95
126
  /**
96
127
  * A developer-declared mapping from object `type`/class strings to the property
97
128
  * shape an object of that type is expected to carry. Supplied as the type
@@ -154,6 +185,12 @@ export interface ObjectLayerOptions {
154
185
  readonly offsetX?: number;
155
186
  /** Layer pixel offset Y. Default `0`. */
156
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';
157
194
  /** The objects in this layer. */
158
195
  readonly objects?: readonly TileMapObject[];
159
196
  /** Layer-level properties (copied and frozen). */
@@ -199,6 +236,8 @@ export declare class ObjectLayer<S extends ObjectSchema = ObjectSchema> {
199
236
  readonly offsetX: number;
200
237
  /** Layer pixel offset Y. */
201
238
  readonly offsetY: number;
239
+ /** Draw order for the objects (Tiled `draworder`). Informational. */
240
+ readonly drawOrder: 'topdown' | 'index';
202
241
  /** Immutable layer-level properties. */
203
242
  readonly properties: TileProperties;
204
243
  /** The objects in this layer (insertion order). */
@@ -1,3 +1,5 @@
1
+ import { TilePropertyKind } from './types.js';
2
+
1
3
  /**
2
4
  * Geometry kinds for a {@link TileMapObject}, as an `as const` value object.
3
5
  *
@@ -15,7 +17,38 @@ const ObjectKind = {
15
17
  Polyline: 'polyline',
16
18
  Point: 'point',
17
19
  Tile: 'tile',
20
+ Text: 'text',
18
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
+ }
19
52
  /**
20
53
  * A data-only layer of {@link TileMapObject}s — spawn points, trigger zones,
21
54
  * collision regions, markers. Object layers are not rendered by the tile
@@ -56,6 +89,8 @@ class ObjectLayer {
56
89
  offsetX;
57
90
  /** Layer pixel offset Y. */
58
91
  offsetY;
92
+ /** Draw order for the objects (Tiled `draworder`). Informational. */
93
+ drawOrder;
59
94
  /** Immutable layer-level properties. */
60
95
  properties;
61
96
  /** The objects in this layer (insertion order). */
@@ -68,6 +103,7 @@ class ObjectLayer {
68
103
  this.opacity = options.opacity ?? 1;
69
104
  this.offsetX = options.offsetX ?? 0;
70
105
  this.offsetY = options.offsetY ?? 0;
106
+ this.drawOrder = options.drawOrder ?? 'topdown';
71
107
  this.properties = options.properties ? Object.freeze({ ...options.properties }) : Object.freeze({});
72
108
  this.objects = options.objects ? Object.freeze([...options.objects]) : Object.freeze([]);
73
109
  }
@@ -84,10 +120,14 @@ class ObjectLayer {
84
120
  return false;
85
121
  }
86
122
  if (filter.property !== undefined) {
87
- if (!(filter.property in object.properties)) {
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) {
88
128
  return false;
89
129
  }
90
- if (filter.value !== undefined && object.properties[filter.property] !== filter.value) {
130
+ if (filter.value !== undefined && !tilePropertyValueEquals(value, filter.value)) {
91
131
  return false;
92
132
  }
93
133
  }
@@ -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","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
+ }
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Drives per-tile animations on one or more {@link TileLayer}s, RPG-Maker style.
3
+ *
4
+ * On construction it scans the given layer(s) once and registers every cell
5
+ * whose tile carries an `animation` (see {@link import('./types').TileDefinition}).
6
+ * Each {@link update} advances a shared clock and rewrites **only** the
7
+ * registered animated cells, and **only** when a cell crosses a frame boundary —
8
+ * static tiles are never touched. Because a tile rewrite goes through
9
+ * `layer.setTileAt`, only the chunks that actually contain animated cells rebuild
10
+ * their geometry, and only on the (infrequent) frames where a boundary is
11
+ * crossed. The large static body of the map never rebuilds.
12
+ *
13
+ * Tick it from your update loop, like `TweenSequencer`:
14
+ *
15
+ * ```ts
16
+ * const animator = new TileAnimator(map.layers);
17
+ * scene.systems.add({ update: (t) => animator.update(t.deltaSeconds) });
18
+ * ```
19
+ *
20
+ * The animator references — but never owns — the layers and their tilesets;
21
+ * {@link destroy} only drops its own cell registry.
22
+ *
23
+ * @advanced
24
+ */
25
+ class TileAnimator {
26
+ _layers;
27
+ _cells = [];
28
+ _elapsedMs = 0;
29
+ /**
30
+ * @param layers One layer, or an array of layers (e.g. `map.layers`), to scan
31
+ * for animated tiles.
32
+ */
33
+ constructor(layers) {
34
+ this._layers = Array.isArray(layers) ? layers : [layers];
35
+ this._scan();
36
+ }
37
+ /** Number of animated cells currently registered across all layers. */
38
+ get animatedCellCount() {
39
+ return this._cells.length;
40
+ }
41
+ /** Total elapsed animation time in milliseconds since construction/reset. */
42
+ get elapsedMs() {
43
+ return this._elapsedMs;
44
+ }
45
+ /**
46
+ * Advance all registered animations by `deltaSeconds` and write the current
47
+ * frame into any cell that crossed a frame boundary. Cells that did not change
48
+ * frame are not touched, so their chunks do not rebuild.
49
+ *
50
+ * @param deltaSeconds Elapsed wall-clock time since the last call, in seconds.
51
+ */
52
+ update(deltaSeconds) {
53
+ if (!Number.isFinite(deltaSeconds) || deltaSeconds <= 0 || this._cells.length === 0) {
54
+ return;
55
+ }
56
+ this._elapsedMs += deltaSeconds * 1000;
57
+ for (const cell of this._cells) {
58
+ const t = this._elapsedMs % cell.totalMs;
59
+ const frameIndex = frameIndexAt(cell.cumulative, t);
60
+ if (frameIndex === cell.currentFrame) {
61
+ continue;
62
+ }
63
+ cell.currentFrame = frameIndex;
64
+ const frame = cell.frames[frameIndex];
65
+ if (frame === undefined) {
66
+ continue;
67
+ }
68
+ cell.layer.setTileAt(cell.tx, cell.ty, {
69
+ tileset: cell.tileset,
70
+ localTileId: frame.localTileId,
71
+ transform: cell.transform,
72
+ });
73
+ }
74
+ }
75
+ /**
76
+ * Restore every animated cell to its first frame and reset the clock.
77
+ * Useful before serialising or pausing.
78
+ */
79
+ reset() {
80
+ this._elapsedMs = 0;
81
+ for (const cell of this._cells) {
82
+ const frame = cell.frames[0];
83
+ if (frame === undefined) {
84
+ continue;
85
+ }
86
+ cell.currentFrame = 0;
87
+ cell.layer.setTileAt(cell.tx, cell.ty, {
88
+ tileset: cell.tileset,
89
+ localTileId: frame.localTileId,
90
+ transform: cell.transform,
91
+ });
92
+ }
93
+ }
94
+ /**
95
+ * Re-scan the layers for animated cells. Call after structural edits that add
96
+ * or remove animated tiles. Resets all currently-tracked cells to frame 0
97
+ * first so the rescan starts from a clean, deterministic state.
98
+ */
99
+ rescan() {
100
+ this.reset();
101
+ this._scan();
102
+ }
103
+ /** Drop the cell registry. Does not modify the layers or tilesets. */
104
+ destroy() {
105
+ this._cells = [];
106
+ this._elapsedMs = 0;
107
+ }
108
+ /** Scan all layers for cells whose tile carries a (multi-frame) animation. */
109
+ _scan() {
110
+ const cells = [];
111
+ for (const layer of this._layers) {
112
+ for (let ty = 0; ty < layer.height; ty++) {
113
+ for (let tx = 0; tx < layer.width; tx++) {
114
+ const tile = layer.getTileAt(tx, ty);
115
+ if (!tile) {
116
+ continue;
117
+ }
118
+ const def = tile.tileset.getTileDefinition(tile.localTileId);
119
+ const frames = def?.animation;
120
+ if (!frames || frames.length < 2) {
121
+ continue;
122
+ }
123
+ // Skip animations referencing out-of-range frames so update() never
124
+ // throws from setTileAt; such data is malformed and silently ignored.
125
+ if (frames.some(f => f.localTileId < 0 || f.localTileId >= tile.tileset.tileCount)) {
126
+ continue;
127
+ }
128
+ const cumulative = [];
129
+ let total = 0;
130
+ for (const frame of frames) {
131
+ total += Math.max(0, frame.duration);
132
+ cumulative.push(total);
133
+ }
134
+ if (total <= 0) {
135
+ continue;
136
+ }
137
+ cells.push({
138
+ layer,
139
+ tx,
140
+ ty,
141
+ tileset: tile.tileset,
142
+ transform: tile.transform,
143
+ frames,
144
+ cumulative,
145
+ totalMs: total,
146
+ currentFrame: -1,
147
+ });
148
+ }
149
+ }
150
+ }
151
+ this._cells = cells;
152
+ }
153
+ }
154
+ /**
155
+ * Find the frame index whose cumulative window contains time `t` (0 ≤ t < total).
156
+ * `cumulative[i]` is the end time of frame `i`; the last entry equals the total.
157
+ */
158
+ function frameIndexAt(cumulative, t) {
159
+ for (let i = 0; i < cumulative.length; i++) {
160
+ const end = cumulative[i];
161
+ if (end !== undefined && t < end) {
162
+ return i;
163
+ }
164
+ }
165
+ return cumulative.length - 1;
166
+ }
167
+
168
+ export { TileAnimator };
169
+ //# sourceMappingURL=TileAnimator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TileAnimator.js","sources":["../../../src/TileAnimator.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -34,6 +34,23 @@ export interface TileLayerOptions {
34
34
  readonly offsetX?: number;
35
35
  /** Layer pixel offset Y. Default 0. */
36
36
  readonly offsetY?: number;
37
+ /**
38
+ * Parallax scroll factor on the X axis. `1.0` = full camera speed (normal),
39
+ * `0.5` = half speed (farther away), `0.0` = stationary. Default 1.
40
+ */
41
+ readonly parallaxX?: number;
42
+ /**
43
+ * Parallax scroll factor on the Y axis. `1.0` = full camera speed (normal),
44
+ * `0.5` = half speed (farther away), `0.0` = stationary. Default 1.
45
+ */
46
+ readonly parallaxY?: number;
47
+ /** Layer class/type string (Tiled `class`). Defaults to `''`. */
48
+ readonly class?: string;
49
+ /**
50
+ * Multiplicative layer tint as a `0xRRGGBB` integer, or `null` for none
51
+ * (Tiled `tintcolor`). Applied to every chunk's render tint. Default `null`.
52
+ */
53
+ readonly tintColor?: number | null;
37
54
  /** Layer properties (copied and frozen). */
38
55
  readonly properties?: TileProperties;
39
56
  }
@@ -50,8 +67,8 @@ export interface TileLayerOptions {
50
67
  * changes. Direct chunk mutation is not supported — the layer owns chunk
51
68
  * storage and exposes only a {@link ReadonlyTileChunk} view.
52
69
  *
53
- * The layer is NOT a SceneNode — that integration lives in the future
54
- * renderer slice.
70
+ * The layer is NOT a SceneNode — that integration lives in
71
+ * {@link import('./TileLayerNode').TileLayerNode}.
55
72
  *
56
73
  * @advanced
57
74
  */
@@ -84,6 +101,20 @@ export declare class TileLayer {
84
101
  offsetX: number;
85
102
  /** Vertical pixel offset (mutable). */
86
103
  offsetY: number;
104
+ /**
105
+ * Parallax scroll factor on the X axis.
106
+ * `1.0` = full camera speed, `0.5` = half speed, `0.0` = stationary.
107
+ */
108
+ readonly parallaxX: number;
109
+ /**
110
+ * Parallax scroll factor on the Y axis.
111
+ * `1.0` = full camera speed, `0.5` = half speed, `0.0` = stationary.
112
+ */
113
+ readonly parallaxY: number;
114
+ /** Layer class/type string (Tiled `class`; may be empty). */
115
+ readonly class: string;
116
+ /** Multiplicative layer tint as `0xRRGGBB`, or `null` for no tint. */
117
+ readonly tintColor: number | null;
87
118
  /** Immutable layer properties. */
88
119
  readonly properties: TileProperties;
89
120
  /** The tilesets available to this layer (shared array reference). */