@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.
- package/dist/esm/ImageLayer.d.ts +81 -0
- package/dist/esm/ImageLayer.js +67 -0
- package/dist/esm/ImageLayer.js.map +1 -0
- package/dist/esm/ObjectLayer.d.ts +277 -0
- package/dist/esm/ObjectLayer.js +176 -0
- package/dist/esm/ObjectLayer.js.map +1 -0
- package/dist/esm/TileAnimator.d.ts +62 -0
- package/dist/esm/TileAnimator.js +169 -0
- package/dist/esm/TileAnimator.js.map +1 -0
- package/dist/esm/TileChunk.js.map +1 -1
- package/dist/esm/TileChunkNode.d.ts +1 -1
- package/dist/esm/TileChunkNode.js +1 -1
- package/dist/esm/TileLayer.d.ts +33 -2
- package/dist/esm/TileLayer.js +26 -2
- package/dist/esm/TileLayer.js.map +1 -1
- package/dist/esm/TileLayerNode.d.ts +10 -3
- package/dist/esm/TileLayerNode.js +35 -7
- package/dist/esm/TileLayerNode.js.map +1 -1
- package/dist/esm/TileMap.d.ts +71 -1
- package/dist/esm/TileMap.js +100 -1
- package/dist/esm/TileMap.js.map +1 -1
- package/dist/esm/TileMapBand.d.ts +6 -3
- package/dist/esm/TileMapBand.js +7 -6
- package/dist/esm/TileMapBand.js.map +1 -1
- package/dist/esm/TileMapNode.d.ts +1 -1
- package/dist/esm/TileMapView.d.ts +1 -1
- package/dist/esm/TileMapView.js.map +1 -1
- package/dist/esm/TileSet.d.ts +12 -0
- package/dist/esm/TileSet.js +30 -2
- package/dist/esm/TileSet.js.map +1 -1
- package/dist/esm/WangSet.d.ts +79 -0
- package/dist/esm/WangSet.js +81 -0
- package/dist/esm/WangSet.js.map +1 -0
- package/dist/esm/autoTile.d.ts +83 -0
- package/dist/esm/autoTile.js +214 -0
- package/dist/esm/autoTile.js.map +1 -0
- package/dist/esm/chunkGeometry.js +4 -3
- package/dist/esm/chunkGeometry.js.map +1 -1
- package/dist/esm/index.js +6 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/pixelSnap.d.ts +1 -1
- package/dist/esm/public.d.ts +11 -2
- package/dist/esm/register.js +6 -1
- package/dist/esm/register.js.map +1 -1
- package/dist/esm/tilemapExtension.d.ts +4 -3
- package/dist/esm/tilemapExtension.js +8 -4
- package/dist/esm/tilemapExtension.js.map +1 -1
- package/dist/esm/tilemapSerializers.d.ts +19 -0
- package/dist/esm/tilemapSerializers.js +47 -0
- package/dist/esm/tilemapSerializers.js.map +1 -0
- package/dist/esm/types.d.ts +86 -4
- package/dist/esm/types.js +18 -1
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/webgl2/WebGl2TileChunkRenderer.d.ts +2 -2
- package/dist/esm/webgl2/WebGl2TileChunkRenderer.js +1 -1
- package/dist/esm/webgl2/WebGl2TileChunkRenderer.js.map +1 -1
- package/dist/esm/webgpu/WebGpuTileChunkRenderer.d.ts +2 -2
- package/dist/esm/webgpu/WebGpuTileChunkRenderer.js +1 -1
- 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
|
+
}
|