@codexo/exojs-tiled 0.12.0 → 0.14.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 (45) hide show
  1. package/README.md +134 -71
  2. package/dist/esm/TiledLayer.d.ts +72 -0
  3. package/dist/esm/TiledLayer.js +117 -0
  4. package/dist/esm/TiledLayer.js.map +1 -0
  5. package/dist/esm/TiledMap.d.ts +57 -72
  6. package/dist/esm/TiledMap.js +362 -23
  7. package/dist/esm/TiledMap.js.map +1 -1
  8. package/dist/esm/TiledObject.d.ts +32 -0
  9. package/dist/esm/TiledObject.js +54 -0
  10. package/dist/esm/TiledObject.js.map +1 -0
  11. package/dist/esm/TiledTileset.d.ts +59 -0
  12. package/dist/esm/TiledTileset.js +70 -0
  13. package/dist/esm/TiledTileset.js.map +1 -0
  14. package/dist/esm/data.d.ts +217 -0
  15. package/dist/esm/gid.d.ts +13 -0
  16. package/dist/esm/gid.js +28 -0
  17. package/dist/esm/gid.js.map +1 -0
  18. package/dist/esm/index.js +8 -1
  19. package/dist/esm/index.js.map +1 -1
  20. package/dist/esm/loadTiledMap.d.ts +9 -0
  21. package/dist/esm/loadTiledMap.js +68 -0
  22. package/dist/esm/loadTiledMap.js.map +1 -0
  23. package/dist/esm/public.d.ts +42 -3
  24. package/dist/esm/register.js +7 -0
  25. package/dist/esm/register.js.map +1 -1
  26. package/dist/esm/tiledBuildInfo.js +2 -2
  27. package/dist/esm/tiledExtension.d.ts +10 -0
  28. package/dist/esm/tiledExtension.js +19 -48
  29. package/dist/esm/tiledExtension.js.map +1 -1
  30. package/dist/esm/tiledMapBinding.d.ts +19 -0
  31. package/dist/esm/tiledMapBinding.js +31 -0
  32. package/dist/esm/tiledMapBinding.js.map +1 -0
  33. package/dist/esm/tiledOptions.d.ts +31 -0
  34. package/dist/esm/tiledOptions.js +16 -0
  35. package/dist/esm/tiledOptions.js.map +1 -0
  36. package/dist/esm/tiledRuntimeMapBinding.d.ts +29 -0
  37. package/dist/esm/tiledRuntimeMapBinding.js +42 -0
  38. package/dist/esm/tiledRuntimeMapBinding.js.map +1 -0
  39. package/dist/esm/url.d.ts +18 -0
  40. package/dist/esm/url.js +41 -0
  41. package/dist/esm/url.js.map +1 -0
  42. package/dist/esm/validate.d.ts +49 -0
  43. package/dist/esm/validate.js +511 -0
  44. package/dist/esm/validate.js.map +1 -0
  45. package/package.json +11 -3
package/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # @codexo/exojs-tiled
2
2
 
3
- Official ExoJS extension for loading [Tiled](https://mapeditor.org) maps (`.tmj` JSON format).
3
+ Official ExoJS extension for loading [Tiled](https://mapeditor.org) maps (`.tmj` JSON format)
4
+ into a generic runtime `TileMap` or a typed parsed source model.
4
5
 
5
6
  ## Installation
6
7
 
@@ -8,120 +9,182 @@ Official ExoJS extension for loading [Tiled](https://mapeditor.org) maps (`.tmj`
8
9
  npm install @codexo/exojs @codexo/exojs-tiled
9
10
  ```
10
11
 
11
- This package requires `@codexo/exojs` as a peer dependency. Both must be the same version.
12
+ `@codexo/exojs` is a peer dependency. `@codexo/exojs-tilemap` is a regular dependency and is
13
+ installed transitively by `@codexo/exojs-tiled` — you do not need to install it manually.
12
14
 
13
- ## Core compatibility
15
+ If you want the generic tilemap runtime without the Tiled adapter:
14
16
 
15
- | `@codexo/exojs-tiled` | `@codexo/exojs` |
16
- |---|---|
17
- | 0.12.x | 0.12.x |
18
-
19
- ## Supported Tiled scope
17
+ ```sh
18
+ npm install @codexo/exojs @codexo/exojs-tilemap
19
+ ```
20
20
 
21
- - Tiled JSON map format (`.tmj`)
22
- - Orthogonal tile layers
23
- - Object layers (basic)
24
- - External tilesets (`.tsj`) referenced from `.tmj`
25
- - Multiple tile layers per map
21
+ ## What this package provides
26
22
 
27
- ## Not supported in 0.12.x
23
+ - `TileMap` (re-exported from `@codexo/exojs-tilemap`) — generic runtime tilemap; the common-case result of `loader.load(TileMap, url)`
24
+ - `TileMapNode` / `TileLayerNode` (re-exported from `@codexo/exojs-tilemap`) — scene nodes that render a loaded `TileMap` on WebGL2/WebGPU
25
+ - `TileMapView` / `TileMapBand` (re-exported from `@codexo/exojs-tilemap`) — group a map's layers into independently placeable bands for interleaving actors between tile layers; same class identity, so `instanceof` holds across both import paths (the canonical view/band docs live in the [`@codexo/exojs-tilemap` README](https://www.npmjs.com/package/@codexo/exojs-tilemap))
26
+ - `TiledMap` — parsed Tiled source model; advanced/diagnostic use via `loader.load(TiledMap, url)`
27
+ - `TiledTileset` — parsed tileset (atlas-image or collection-of-images); holds resolved textures
28
+ - `TiledLayer` hierarchy — `TiledTileLayer`, `TiledObjectLayer`, `TiledImageLayer`, `TiledGroupLayer`
29
+ - `TiledObject` — parsed object (point, ellipse, polygon, polyline, text, tile-ref, rectangle)
30
+ - `TiledFormatError` — typed error thrown on any structural problem in `.tmj`/`.tsj` data
31
+ - `tiledExtension` — extension descriptor; depends on `tilemapExtension` automatically
28
32
 
29
- - TMX (XML) format use `.tmj` export from Tiled
30
- - Isometric and hexagonal maps
31
- - Image layers
32
- - Wangsets
33
- - Custom class / enum properties
33
+ ## Usagecommon case
34
34
 
35
- ## Usage side-effect-free root entry
35
+ Register the extension, load a `.tmj` map into a generic runtime `TileMap`, and render it. One
36
+ extension enables **both** loading and rendering — `tiledExtension` depends on `tilemapExtension`,
37
+ so the tile chunk renderer bindings are materialised automatically (no manual `tilemapExtension`
38
+ registration):
36
39
 
37
40
  ```ts
38
41
  import { Application } from '@codexo/exojs';
39
- import { TiledMap, tiledExtension } from '@codexo/exojs-tiled';
42
+ import { TileMap, TileMapNode, tiledExtension } from '@codexo/exojs-tiled';
40
43
 
41
- const app = new Application({
42
- extensions: [tiledExtension],
43
- });
44
- ```
44
+ const app = new Application({ extensions: [tiledExtension] });
45
45
 
46
- Importing from the root entry does **not** register the extension globally.
46
+ const map = await app.loader.load(TileMap, 'maps/world.tmj');
47
+ // map is a @codexo/exojs-tilemap TileMap
47
48
 
48
- ## Extension descriptor
49
+ app.scene.root.addChild(new TileMapNode(map));
50
+ ```
49
51
 
50
- `tiledExtension` is the default descriptor. It registers the `TiledMap` asset type with the following bindings:
52
+ `TileMapNode` and `TileLayerNode` are the same classes exported by `@codexo/exojs-tilemap` (see its
53
+ [README](https://www.npmjs.com/package/@codexo/exojs-tilemap) for the rendering/culling model and
54
+ actor interleaving). `instanceof TileMap` holds across both import paths.
51
55
 
52
- - Constructor load: `loader.load(TiledMap, url)`
53
- - Extension routing: `.tmj` files auto-route to `TiledMap`
54
- - Type-name load: `loader.load('tiledMap', url)`
56
+ ## Usage advanced parsed-source case
55
57
 
56
- ## Loading a Tiled map
58
+ Load the fully resolved Tiled source model and convert it manually:
57
59
 
58
60
  ```ts
59
61
  import { TiledMap } from '@codexo/exojs-tiled';
60
62
 
61
- // Inside a Scene:
62
- override async load(loader) {
63
- // By constructor (explicit)
64
- await loader.load(TiledMap, { myMap: '/maps/level1.tmj' });
65
-
66
- // By file extension (auto-routed)
67
- await loader.load('/maps/level1.tmj');
68
-
69
- // By type name
70
- await loader.load('tiledMap', { myMap: '/maps/level1.tmj' });
71
- }
72
-
73
- override create(loader) {
74
- const map = loader.get(TiledMap, 'myMap');
75
- this.addChild(map);
76
- }
63
+ const source = await app.loader.load(TiledMap, 'maps/world.tmj');
64
+ const map = source.toTileMap();
77
65
  ```
78
66
 
67
+ Both paths are semantically equivalent. The runtime binding (`TileMap`) uses the Loader-managed
68
+ source-model sub-load internally, so concurrent or duplicate loads are deduplicated.
69
+
79
70
  ## `/register` convenience entry
80
71
 
81
- Importing `/register` registers the default `tiledExtension` descriptor in the global `ExtensionRegistry`. Subsequently created Applications that use global defaults will automatically receive the Tiled extension.
72
+ Importing `/register` registers `tiledExtension` (and its `tilemapExtension` dependency) in the
73
+ global `ExtensionRegistry`. Subsequently created Applications that use global defaults will
74
+ receive both extensions automatically.
82
75
 
83
76
  ```ts
84
77
  // Side effect: registers tiledExtension in the global ExtensionRegistry.
85
78
  import '@codexo/exojs-tiled/register';
86
79
 
87
- // All named exports are re-exported from /register:
88
- import { TiledMap, tiledExtension } from '@codexo/exojs-tiled/register';
80
+ // All named exports are also re-exported from /register:
81
+ import { TileMap, TiledMap, tiledExtension } from '@codexo/exojs-tiled/register';
89
82
  ```
90
83
 
91
- **Note:** `/register` does not use automatic discovery. It explicitly calls `ExtensionRegistry.register(tiledExtension)` at module evaluation time.
84
+ ## Extension dependency
85
+
86
+ `tiledExtension.dependencies` includes `tilemapExtension` from `@codexo/exojs-tilemap`.
87
+ Registering `tiledExtension` is sufficient — `buildSnapshot` and `ExtensionRegistry.register`
88
+ traverse the dependency graph automatically.
92
89
 
93
- ## Texture and sub-asset ownership
90
+ ## Asset loading
94
91
 
95
- Tilesets referenced from a Tiled map are loaded as sub-assets and stored in the Loader cache. The `TiledMap` does **not** own or destroy tileset textures — the Loader cache owns them. Do not call `tileset.destroy()` from your code; let the Loader handle cleanup when the scene is destroyed.
92
+ `loader.load(TileMap, url)` (common path) and `loader.load(TiledMap, url)` (advanced path) both:
96
93
 
97
- ## Minimal working example
94
+ 1. Fetch and validate the `.tmj` file.
95
+ 2. Resolve each tileset entry (fetches external `.tsj` files via the Loader cache).
96
+ 3. Load atlas images (`tileset.image`) and per-tile images (collection-of-images tilesets)
97
+ via `loader.load(Texture, …)` — the Loader deduplicates identical URLs.
98
+ 4. Validate GID ranges (no duplicates, no overlaps, all layer GIDs covered) — throws
99
+ `TiledFormatError` on any inconsistency.
100
+
101
+ The runtime binding additionally calls `TiledMap.toTileMap()` to produce the generic `TileMap`.
102
+
103
+ ### Load options
98
104
 
99
105
  ```ts
100
- import { Application, Scene } from '@codexo/exojs';
101
- import { TiledMap, tiledExtension } from '@codexo/exojs-tiled';
106
+ // `.tmj`/`.tsj` are recognised by extension; a format hint is only needed for
107
+ // Tiled data served from a generic `.json` path:
108
+ await loader.load(TileMap, 'maps/world.json', { format: 'tiled' });
109
+ ```
102
110
 
103
- const app = new Application({ extensions: [tiledExtension] });
104
- document.body.append(app.canvas);
111
+ | Option | Type | Default | Description |
112
+ |---|---|---|---|
113
+ | `format` | `'tiled'` | `'tiled'` | Format hint for ambiguous `.json` paths. `.tmj`/`.tsj` are recognised by extension. `'tiled'` is the only accepted value (a foreign format is a compile error). Participates in the asset identity key. |
105
114
 
106
- class GameScene extends Scene {
107
- map!: TiledMap;
115
+ Options are optional. Parsing is always strict: `validateTiledMapData` throws a `TiledFormatError` on any malformed *known* field, and silently preserves *unknown* fields (so real-world Tiled files using features ExoJS does not model still load).
108
116
 
109
- override async load(loader) {
110
- await loader.load(TiledMap, { level1: '/maps/level1.tmj' });
111
- }
117
+ ## Parsed API overview
112
118
 
113
- override create(loader) {
114
- this.map = loader.get(TiledMap, 'level1');
115
- this.addChild(this.map);
116
- }
117
- }
119
+ ### `TiledMap`
118
120
 
119
- app.scenes.start(GameScene);
121
+ ```ts
122
+ map.source // resolved URL this map was loaded from
123
+ map.width // map width in tiles
124
+ map.height // map height in tiles
125
+ map.tileWidth // tile grid cell width in pixels
126
+ map.tileHeight // tile grid cell height in pixels
127
+ map.orientation // 'orthogonal' | 'isometric' | 'staggered' | 'hexagonal'
128
+ map.renderOrder // 'right-down' | 'right-up' | 'left-down' | 'left-up' | undefined
129
+ map.infinite // true for infinite maps (layers use chunks, not flat data)
130
+ map.backgroundColor // optional CSS color string
131
+ map.layers // TiledLayer[] — parsed layer hierarchy
132
+ map.tilesets // TiledTileset[] — sorted by firstGid ascending
133
+ map.properties // TiledPropertyData[] — custom properties
134
+ map.findTilesetForGid(gid) // → TiledTileset | undefined (masks flip bits automatically)
135
+ map.getProperty(name) // → TiledPropertyData | undefined
136
+ map.toTileMap() // → TileMap — synchronous runtime conversion
137
+ map.destroy() // no-op; textures are Loader-owned
138
+ ```
139
+
140
+ ### `TiledTileset`
141
+
142
+ ```ts
143
+ tileset.firstGid // first GID in this tileset's range (inclusive)
144
+ tileset.lastGid // last GID in this tileset's range (inclusive)
145
+ tileset.name
146
+ tileset.tileWidth / tileHeight
147
+ tileset.tileCount / columns / spacing / margin
148
+ tileset.source // resolved .tsj URL (undefined for embedded tilesets)
149
+ tileset.imageUrl // resolved atlas image URL (undefined for collection-of-images)
150
+ tileset.texture // Texture loaded for imageUrl (Loader-owned)
151
+ tileset.tileTextures // Map<localId, Texture> for collection-of-images tilesets (Loader-owned)
152
+ tileset.tiles // TiledTileData[] — per-tile animation/property/collision data
153
+ tileset.getTile(localId) // → TiledTileData | undefined
154
+ tileset.getProperty(name) // → TiledPropertyData | undefined
120
155
  ```
121
156
 
157
+ ### `TiledLayer` subclasses
158
+
159
+ All layers extend `TiledLayer` (base: `id`, `name`, `class`, `visible`, `opacity`, `x`, `y`,
160
+ `offsetX/Y`, `parallaxX/Y`, `tintColor`, `properties`, `getProperty(name)`).
161
+
162
+ | Subclass | `type` | Extra fields |
163
+ |---|---|---|
164
+ | `TiledTileLayer` | `'tilelayer'` | `width`, `height`, `data?: number[]` (finite), `chunks?` (infinite) |
165
+ | `TiledObjectLayer` | `'objectgroup'` | `drawOrder`, `objects: TiledObject[]` |
166
+ | `TiledImageLayer` | `'imagelayer'` | `image`, `repeatX`, `repeatY` |
167
+ | `TiledGroupLayer` | `'group'` | `layers: TiledLayer[]` |
168
+
169
+ ### `TiledObject`
170
+
171
+ Shape discriminants: `point` (boolean), `ellipse` (boolean), `polygon`, `polyline`, `text`,
172
+ `gid` (tile object). If none are set, the object is a plain rectangle.
173
+
174
+ ## Texture ownership
175
+
176
+ Textures for tileset images are loaded via the Loader and remain in the Loader cache.
177
+ `TiledMap.destroy()` releases the parsed source model's reference but does **not** unload textures.
178
+ The Loader handles texture lifecycle (including deduplication across maps that share tilesets).
179
+
180
+ ## Core compatibility
181
+
182
+ | `@codexo/exojs-tiled` | `@codexo/exojs` |
183
+ |---|---|
184
+ | 0.13.x | 0.13.x |
185
+
122
186
  ## Links
123
187
 
124
- - [Official ExoJS Tiled guide](https://exojs.dev/guides/extensions/tiled)
125
188
  - [API reference](https://exojs.dev/api/exojs-tiled)
126
189
  - [Tiled map editor](https://mapeditor.org)
127
190
 
@@ -0,0 +1,72 @@
1
+ import type { TiledChunkData, TiledGroupLayerData, TiledImageLayerData, TiledLayerData, TiledLayerDataBase, TiledObjectLayerData, TiledPropertyData, TiledTileLayerData } from './data';
2
+ import { TiledObject } from './TiledObject';
3
+ /** Discriminant shared by every {@link TiledLayer} subclass, mirroring {@link TiledLayerData}'s `type`. */
4
+ export type TiledLayerType = TiledLayerData['type'];
5
+ /**
6
+ * Base class for the four parsed Tiled layer types. Holds the fields shared
7
+ * by every layer (`tilelayer`, `objectgroup`, `imagelayer`, `group`).
8
+ *
9
+ * Use {@link TiledLayer.type} (or `instanceof`) to discriminate between
10
+ * {@link TiledTileLayer}, {@link TiledObjectLayer}, {@link TiledImageLayer},
11
+ * and {@link TiledGroupLayer}.
12
+ */
13
+ export declare abstract class TiledLayer {
14
+ abstract readonly type: TiledLayerType;
15
+ readonly id: number;
16
+ readonly name: string;
17
+ readonly class: string;
18
+ readonly visible: boolean;
19
+ readonly opacity: number;
20
+ readonly x: number;
21
+ readonly y: number;
22
+ readonly offsetX: number;
23
+ readonly offsetY: number;
24
+ readonly parallaxX: number;
25
+ readonly parallaxY: number;
26
+ readonly tintColor?: string | undefined;
27
+ readonly properties: readonly TiledPropertyData[];
28
+ protected constructor(data: TiledLayerDataBase);
29
+ /** Looks up a custom property by name. */
30
+ getProperty(name: string): TiledPropertyData | undefined;
31
+ }
32
+ /**
33
+ * A tile layer. On a finite map, {@link data} holds the flat row-major array
34
+ * of GIDs (`width * height` entries). On an infinite map, {@link chunks}
35
+ * holds the sparse list of tile chunks instead; exactly one of the two is
36
+ * defined, matching the owning {@link TiledMap}'s `infinite` flag.
37
+ */
38
+ export declare class TiledTileLayer extends TiledLayer {
39
+ readonly type: "tilelayer";
40
+ readonly width: number;
41
+ readonly height: number;
42
+ readonly data?: readonly number[] | undefined;
43
+ readonly chunks?: readonly TiledChunkData[] | undefined;
44
+ constructor(data: TiledTileLayerData);
45
+ }
46
+ /** An object layer: a flat list of {@link TiledObject}s. */
47
+ export declare class TiledObjectLayer extends TiledLayer {
48
+ readonly type: "objectgroup";
49
+ readonly drawOrder: NonNullable<TiledObjectLayerData['draworder']>;
50
+ readonly objects: readonly TiledObject[];
51
+ constructor(data: TiledObjectLayerData);
52
+ }
53
+ /**
54
+ * An image layer. {@link image} is the path to the layer's image exactly as
55
+ * written in the Tiled JSON (relative to the map's location); resolving it
56
+ * against the owning {@link TiledMap}'s `source` is left to the consumer.
57
+ */
58
+ export declare class TiledImageLayer extends TiledLayer {
59
+ readonly type: "imagelayer";
60
+ readonly image: string;
61
+ readonly repeatX: boolean;
62
+ readonly repeatY: boolean;
63
+ constructor(data: TiledImageLayerData);
64
+ }
65
+ /** A group layer, recursively containing further parsed layers. */
66
+ export declare class TiledGroupLayer extends TiledLayer {
67
+ readonly type: "group";
68
+ readonly layers: readonly TiledLayer[];
69
+ constructor(data: TiledGroupLayerData);
70
+ }
71
+ /** Constructs the appropriate {@link TiledLayer} subclass for `data.type`. */
72
+ export declare function createTiledLayer(data: TiledLayerData): TiledLayer;
@@ -0,0 +1,117 @@
1
+ import { TiledObject } from './TiledObject.js';
2
+
3
+ /**
4
+ * Base class for the four parsed Tiled layer types. Holds the fields shared
5
+ * by every layer (`tilelayer`, `objectgroup`, `imagelayer`, `group`).
6
+ *
7
+ * Use {@link TiledLayer.type} (or `instanceof`) to discriminate between
8
+ * {@link TiledTileLayer}, {@link TiledObjectLayer}, {@link TiledImageLayer},
9
+ * and {@link TiledGroupLayer}.
10
+ */
11
+ class TiledLayer {
12
+ id;
13
+ name;
14
+ class;
15
+ visible;
16
+ opacity;
17
+ x;
18
+ y;
19
+ offsetX;
20
+ offsetY;
21
+ parallaxX;
22
+ parallaxY;
23
+ tintColor;
24
+ properties;
25
+ constructor(data) {
26
+ this.id = data.id;
27
+ this.name = data.name;
28
+ this.class = data.class ?? '';
29
+ this.visible = data.visible;
30
+ this.opacity = data.opacity;
31
+ this.x = data.x;
32
+ this.y = data.y;
33
+ this.offsetX = data.offsetx ?? 0;
34
+ this.offsetY = data.offsety ?? 0;
35
+ this.parallaxX = data.parallaxx ?? 1;
36
+ this.parallaxY = data.parallaxy ?? 1;
37
+ this.tintColor = data.tintcolor;
38
+ this.properties = data.properties ?? [];
39
+ }
40
+ /** Looks up a custom property by name. */
41
+ getProperty(name) {
42
+ return this.properties.find(property => property.name === name);
43
+ }
44
+ }
45
+ /**
46
+ * A tile layer. On a finite map, {@link data} holds the flat row-major array
47
+ * of GIDs (`width * height` entries). On an infinite map, {@link chunks}
48
+ * holds the sparse list of tile chunks instead; exactly one of the two is
49
+ * defined, matching the owning {@link TiledMap}'s `infinite` flag.
50
+ */
51
+ class TiledTileLayer extends TiledLayer {
52
+ type = 'tilelayer';
53
+ width;
54
+ height;
55
+ data;
56
+ chunks;
57
+ constructor(data) {
58
+ super(data);
59
+ this.width = data.width;
60
+ this.height = data.height;
61
+ this.data = data.data;
62
+ this.chunks = data.chunks;
63
+ }
64
+ }
65
+ /** An object layer: a flat list of {@link TiledObject}s. */
66
+ class TiledObjectLayer extends TiledLayer {
67
+ type = 'objectgroup';
68
+ drawOrder;
69
+ objects;
70
+ constructor(data) {
71
+ super(data);
72
+ this.drawOrder = data.draworder ?? 'topdown';
73
+ this.objects = data.objects.map(object => new TiledObject(object));
74
+ }
75
+ }
76
+ /**
77
+ * An image layer. {@link image} is the path to the layer's image exactly as
78
+ * written in the Tiled JSON (relative to the map's location); resolving it
79
+ * against the owning {@link TiledMap}'s `source` is left to the consumer.
80
+ */
81
+ class TiledImageLayer extends TiledLayer {
82
+ type = 'imagelayer';
83
+ image;
84
+ repeatX;
85
+ repeatY;
86
+ constructor(data) {
87
+ super(data);
88
+ this.image = data.image;
89
+ this.repeatX = data.repeatx ?? false;
90
+ this.repeatY = data.repeaty ?? false;
91
+ }
92
+ }
93
+ /** A group layer, recursively containing further parsed layers. */
94
+ class TiledGroupLayer extends TiledLayer {
95
+ type = 'group';
96
+ layers;
97
+ constructor(data) {
98
+ super(data);
99
+ this.layers = data.layers.map(createTiledLayer);
100
+ }
101
+ }
102
+ /** Constructs the appropriate {@link TiledLayer} subclass for `data.type`. */
103
+ function createTiledLayer(data) {
104
+ switch (data.type) {
105
+ case 'tilelayer':
106
+ return new TiledTileLayer(data);
107
+ case 'objectgroup':
108
+ return new TiledObjectLayer(data);
109
+ case 'imagelayer':
110
+ return new TiledImageLayer(data);
111
+ case 'group':
112
+ return new TiledGroupLayer(data);
113
+ }
114
+ }
115
+
116
+ export { TiledGroupLayer, TiledImageLayer, TiledLayer, TiledObjectLayer, TiledTileLayer, createTiledLayer };
117
+ //# sourceMappingURL=TiledLayer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TiledLayer.js","sources":["../../../src/TiledLayer.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -1,88 +1,73 @@
1
- import type { Texture } from '@codexo/exojs';
2
- export interface TiledTileset {
3
- readonly firstgid: number;
4
- readonly source?: string;
5
- readonly image?: string;
6
- readonly name?: string;
7
- readonly tilewidth?: number;
8
- readonly tileheight?: number;
9
- readonly columns?: number;
10
- readonly tilecount?: number;
11
- readonly spacing?: number;
12
- readonly margin?: number;
13
- }
14
- export interface TiledLayer {
15
- readonly id: number;
16
- readonly name: string;
17
- readonly type: 'tilelayer' | 'objectgroup' | 'imagelayer' | 'group';
18
- readonly visible: boolean;
19
- readonly x: number;
20
- readonly y: number;
21
- readonly width?: number;
22
- readonly height?: number;
23
- readonly data?: number[];
24
- readonly objects?: TiledObject[];
25
- readonly opacity: number;
26
- }
27
- export interface TiledObject {
28
- readonly id: number;
29
- readonly name: string;
30
- readonly type: string;
31
- readonly x: number;
32
- readonly y: number;
33
- readonly width: number;
34
- readonly height: number;
35
- readonly rotation: number;
36
- readonly visible: boolean;
37
- readonly gid?: number;
38
- readonly properties?: TiledProperty[];
39
- }
40
- export interface TiledProperty {
41
- readonly name: string;
42
- readonly type: string;
43
- readonly value: unknown;
44
- }
45
- /** Raw data shape parsed from a Tiled JSON (.tmj) file. */
46
- export interface TiledMapData {
47
- readonly width: number;
48
- readonly height: number;
49
- readonly tilewidth: number;
50
- readonly tileheight: number;
51
- readonly infinite?: boolean;
52
- readonly orientation?: string;
53
- readonly renderorder?: string;
54
- readonly layers: readonly TiledLayer[];
55
- readonly tilesets: readonly TiledTileset[];
56
- readonly version?: string | number;
57
- readonly type?: string;
58
- }
1
+ import { TileMap } from '@codexo/exojs-tilemap';
2
+ import type { TiledMapData, TiledOrientation, TiledPropertyData, TiledRenderOrder } from './data';
3
+ import { type TiledLayer } from './TiledLayer';
4
+ import type { TiledTileset } from './TiledTileset';
59
5
  /**
60
- * Runtime representation of a loaded Tiled map.
6
+ * A parsed and validated Tiled map (`.tmj`).
61
7
  *
62
- * Exposes map metadata, layers, and tileset textures. Tileset textures
63
- * are owned by the Loader cache `TiledMap.destroy()` does NOT destroy them.
8
+ * `TiledMap` represents the parsed Tiled source format. `TileMap` is the
9
+ * format-independent ExoJS runtime map used for rendering, queries, and
10
+ * mutation.
64
11
  *
65
- * Only the initial proof scope is implemented: orthogonal tile layers,
66
- * basic tilesets, and basic object layers. TMX/XML, infinite maps, and
67
- * world streaming are not supported.
12
+ * Construction validates that {@link tilesets} cover a non-overlapping,
13
+ * duplicate-free range of global tile ids, and that every GID referenced by
14
+ * {@link layers} (tile layer cells, infinite-map chunks, and tile object
15
+ * `gid`s) falls within one of those ranges. Both checks throw
16
+ * {@link TiledFormatError} on failure.
68
17
  */
69
18
  export declare class TiledMap {
19
+ /** Resolved URL this map was loaded from. */
20
+ readonly source: string;
21
+ /** The validated raw map data this instance was built from. */
70
22
  readonly data: TiledMapData;
71
- readonly tilesetTextures: readonly Texture[];
23
+ readonly orientation: TiledOrientation;
24
+ readonly renderOrder?: TiledRenderOrder | undefined;
25
+ readonly class: string;
26
+ /** Map width in tiles. */
72
27
  readonly width: number;
28
+ /** Map height in tiles. */
73
29
  readonly height: number;
30
+ /** Tile grid cell width in pixels. */
74
31
  readonly tileWidth: number;
32
+ /** Tile grid cell height in pixels. */
75
33
  readonly tileHeight: number;
34
+ readonly infinite: boolean;
35
+ readonly backgroundColor?: string | undefined;
76
36
  readonly layers: readonly TiledLayer[];
37
+ /** Tilesets used by this map, sorted by {@link TiledTileset.firstGid} ascending. */
77
38
  readonly tilesets: readonly TiledTileset[];
78
- constructor(data: TiledMapData, tilesetTextures: readonly Texture[]);
79
- /** Tile layers only. */
80
- get tileLayers(): readonly TiledLayer[];
81
- /** Object group layers only. */
82
- get objectLayers(): readonly TiledLayer[];
39
+ readonly properties: readonly TiledPropertyData[];
40
+ constructor(source: string, data: TiledMapData, tilesets: readonly TiledTileset[]);
41
+ /**
42
+ * Returns the tileset that owns `gid`, or `undefined` if `gid` is `0`
43
+ * (the empty-cell sentinel) or is not covered by any tileset.
44
+ *
45
+ * Flip/rotation flag bits are masked off before the range lookup, so the
46
+ * raw GID values found in {@link TiledTileLayer.data}/`chunks` and
47
+ * {@link TiledObject.gid} can be passed directly.
48
+ */
49
+ findTilesetForGid(gid: number): TiledTileset | undefined;
50
+ /** Looks up a custom property by name. */
51
+ getProperty(name: string): TiledPropertyData | undefined;
52
+ /**
53
+ * Convert this parsed Tiled source model into a format-independent runtime
54
+ * {@link TileMap} from `@codexo/exojs-tilemap`.
55
+ *
56
+ * Only finite orthogonal maps with atlas tilesets are supported. A
57
+ * non-orthogonal or infinite map, or a collection-of-images tileset, throws
58
+ * {@link TiledFormatError} rather than silently producing wrong (misplaced)
59
+ * or empty geometry. Tile layers become renderable `TileLayer`s and object
60
+ * groups become data-only `ObjectLayer`s; group layer children are flattened
61
+ * in document order. Image layers are not yet converted.
62
+ *
63
+ * The returned `TileMap` does **not** own the tileset textures — they remain
64
+ * in the Loader cache. Destroying the returned map does not unload textures.
65
+ */
66
+ toTileMap(): TileMap;
83
67
  /**
84
- * Destroy this TiledMap. Does NOT destroy tileset textures they are
85
- * owned by the Loader's cache and may be shared with other callers.
68
+ * Releases this map's reference to its parsed source. Tileset textures are
69
+ * Loader-owned and may be shared with other maps; this does NOT destroy
70
+ * them.
86
71
  */
87
72
  destroy(): void;
88
73
  }