@yagejs/tilemap 0.1.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/README.md ADDED
@@ -0,0 +1,43 @@
1
+ # @yagejs/tilemap
2
+
3
+ Tile-based map loading and rendering for the [YAGE](https://yage.dev) 2D game engine.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @yagejs/tilemap
9
+ ```
10
+
11
+ Supports [Tiled](https://www.mapeditor.org/) map format out of the box. Bundles `@pixi/tilemap` for efficient rendering.
12
+
13
+ ## Usage
14
+
15
+ ```ts
16
+ import { Engine } from "@yagejs/core";
17
+ import { TilemapPlugin, TilemapComponent, tiledMap } from "@yagejs/tilemap";
18
+
19
+ const engine = new Engine();
20
+ engine.use(new TilemapPlugin());
21
+ ```
22
+
23
+ Load and render a Tiled map:
24
+
25
+ ```ts
26
+ const map = await assets.load(tiledMap("level1.json"));
27
+ entity.add(new TilemapComponent({ map }));
28
+ ```
29
+
30
+ ## What's in the box
31
+
32
+ - **TilemapPlugin / TilemapComponent** - tile-based map rendering
33
+ - **Tiled loader** - JSON format support with tilesets, object layers, properties
34
+ - **Collision extraction** - convert map shapes to `@yagejs/physics` colliders (optional)
35
+ - **Custom properties** - typed access to Tiled object properties
36
+
37
+ ## Docs
38
+
39
+ Full documentation at [yage.dev](https://yage.dev).
40
+
41
+ ## License
42
+
43
+ MIT
package/dist/index.cjs ADDED
@@ -0,0 +1,618 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : /* @__PURE__ */ Symbol.for("Symbol." + name);
8
+ var __typeError = (msg) => {
9
+ throw TypeError(msg);
10
+ };
11
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
12
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
13
+ var __export = (target, all) => {
14
+ for (var name in all)
15
+ __defProp(target, name, { get: all[name], enumerable: true });
16
+ };
17
+ var __copyProps = (to, from, except, desc) => {
18
+ if (from && typeof from === "object" || typeof from === "function") {
19
+ for (let key of __getOwnPropNames(from))
20
+ if (!__hasOwnProp.call(to, key) && key !== except)
21
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
22
+ }
23
+ return to;
24
+ };
25
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
26
+ var __decoratorStart = (base) => [, , , __create(base?.[__knownSymbol("metadata")] ?? null)];
27
+ var __decoratorStrings = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"];
28
+ var __expectFn = (fn) => fn !== void 0 && typeof fn !== "function" ? __typeError("Function expected") : fn;
29
+ var __decoratorContext = (kind, name, done, metadata, fns) => ({ kind: __decoratorStrings[kind], name, metadata, addInitializer: (fn) => done._ ? __typeError("Already initialized") : fns.push(__expectFn(fn || null)) });
30
+ var __decoratorMetadata = (array, target) => __defNormalProp(target, __knownSymbol("metadata"), array[3]);
31
+ var __runInitializers = (array, flags, self, value) => {
32
+ for (var i = 0, fns = array[flags >> 1], n = fns && fns.length; i < n; i++) flags & 1 ? fns[i].call(self) : value = fns[i].call(self, value);
33
+ return value;
34
+ };
35
+ var __decorateElement = (array, flags, name, decorators, target, extra) => {
36
+ var fn, it, done, ctx, access, k = flags & 7, s = !!(flags & 8), p = !!(flags & 16);
37
+ var j = k > 3 ? array.length + 1 : k ? s ? 1 : 2 : 0, key = __decoratorStrings[k + 5];
38
+ var initializers = k > 3 && (array[j - 1] = []), extraInitializers = array[j] || (array[j] = []);
39
+ var desc = k && (!p && !s && (target = target.prototype), k < 5 && (k > 3 || !p) && __getOwnPropDesc(k < 4 ? target : { get [name]() {
40
+ return __privateGet(this, extra);
41
+ }, set [name](x) {
42
+ return __privateSet(this, extra, x);
43
+ } }, name));
44
+ k ? p && k < 4 && __name(extra, (k > 2 ? "set " : k > 1 ? "get " : "") + name) : __name(target, name);
45
+ for (var i = decorators.length - 1; i >= 0; i--) {
46
+ ctx = __decoratorContext(k, name, done = {}, array[3], extraInitializers);
47
+ if (k) {
48
+ ctx.static = s, ctx.private = p, access = ctx.access = { has: p ? (x) => __privateIn(target, x) : (x) => name in x };
49
+ if (k ^ 3) access.get = p ? (x) => (k ^ 1 ? __privateGet : __privateMethod)(x, target, k ^ 4 ? extra : desc.get) : (x) => x[name];
50
+ if (k > 2) access.set = p ? (x, y) => __privateSet(x, target, y, k ^ 4 ? extra : desc.set) : (x, y) => x[name] = y;
51
+ }
52
+ it = (0, decorators[i])(k ? k < 4 ? p ? extra : desc[key] : k > 4 ? void 0 : { get: desc.get, set: desc.set } : target, ctx), done._ = 1;
53
+ if (k ^ 4 || it === void 0) __expectFn(it) && (k > 4 ? initializers.unshift(it) : k ? p ? extra = it : desc[key] = it : target = it);
54
+ else if (typeof it !== "object" || it === null) __typeError("Object expected");
55
+ else __expectFn(fn = it.get) && (desc.get = fn), __expectFn(fn = it.set) && (desc.set = fn), __expectFn(fn = it.init) && initializers.unshift(fn);
56
+ }
57
+ return k || __decoratorMetadata(array, target), desc && __defProp(target, name, desc), p ? k ^ 4 ? extra : desc : target;
58
+ };
59
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
60
+ var __privateIn = (member, obj) => Object(obj) !== obj ? __typeError('Cannot use the "in" operator on this value') : member.has(obj);
61
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
62
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
63
+ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
64
+
65
+ // src/index.ts
66
+ var index_exports = {};
67
+ __export(index_exports, {
68
+ TilemapComponent: () => TilemapComponent,
69
+ TilemapPlugin: () => TilemapPlugin,
70
+ TilemapRenderSystem: () => TilemapRenderSystem,
71
+ createTilemapLayers: () => createTilemapLayers,
72
+ extractCollisionShapes: () => extractCollisionShapes,
73
+ extractObjects: () => extractObjects,
74
+ getProperty: () => getProperty,
75
+ getPropertyArray: () => getPropertyArray,
76
+ resolveObjectRef: () => resolveObjectRef,
77
+ resolveObjectRefArray: () => resolveObjectRefArray,
78
+ tiledMap: () => tiledMap,
79
+ tiledMapAssetExtension: () => tiledMapAssetExtension,
80
+ toPhysicsColliders: () => toPhysicsColliders,
81
+ toTilemapData: () => toTilemapData
82
+ });
83
+ module.exports = __toCommonJS(index_exports);
84
+
85
+ // src/TilemapPlugin.ts
86
+ var import_core3 = require("@yagejs/core");
87
+ var import_pixi4 = require("pixi.js");
88
+
89
+ // src/tiled/tiledMapLoader.ts
90
+ var import_pixi = require("pixi.js");
91
+ var tiledMapLoaderParser = {
92
+ id: "tiledMapLoader",
93
+ extension: {
94
+ type: import_pixi.ExtensionType.LoadParser,
95
+ priority: import_pixi.LoaderParserPriority.High
96
+ },
97
+ async testParse(asset, resolvedAsset) {
98
+ if (!resolvedAsset?.src) return false;
99
+ if (import_pixi.path.extname(resolvedAsset.src).toLowerCase() !== ".json") return false;
100
+ const obj = asset;
101
+ return !!(obj.tilesets && obj.layers);
102
+ },
103
+ async parse(asset, resolvedAsset, loader) {
104
+ const src = resolvedAsset?.src;
105
+ if (!src || !loader) return asset;
106
+ let basePath = import_pixi.path.dirname(src);
107
+ if (basePath && !basePath.endsWith("/")) {
108
+ basePath += "/";
109
+ }
110
+ for (const tilesetRef of asset.tilesets) {
111
+ if (tilesetRef.source) {
112
+ const tilesetPath = basePath + tilesetRef.source;
113
+ const tilesetData = await loader.load({
114
+ src: tilesetPath
115
+ });
116
+ tilesetRef.data = tilesetData;
117
+ }
118
+ const tileset = tilesetRef.data;
119
+ if (!tileset) continue;
120
+ if (tileset.image && !tileset.tiles?.length) {
121
+ const imagePath = basePath + tileset.image;
122
+ const baseTexture = await import_pixi.Assets.load(imagePath);
123
+ const cols = tileset.columns;
124
+ const tw = tileset.tilewidth;
125
+ const th = tileset.tileheight;
126
+ const margin = tileset.margin ?? 0;
127
+ const spacing = tileset.spacing ?? 0;
128
+ for (let id = 0; id < tileset.tilecount; id++) {
129
+ const col = id % cols;
130
+ const row = Math.floor(id / cols);
131
+ const x = margin + col * (tw + spacing);
132
+ const y = margin + row * (th + spacing);
133
+ const frame = new import_pixi.Rectangle(x, y, tw, th);
134
+ const subtex = new import_pixi.Texture({
135
+ source: baseTexture.source,
136
+ frame
137
+ });
138
+ const cacheKey = `${tileset.name}:${id}`;
139
+ import_pixi.Assets.cache.set(cacheKey, subtex);
140
+ }
141
+ }
142
+ }
143
+ return asset;
144
+ },
145
+ unload() {
146
+ }
147
+ };
148
+ var tiledMapAssetExtension = {
149
+ extension: import_pixi.ExtensionType.Asset,
150
+ loader: tiledMapLoaderParser
151
+ };
152
+
153
+ // src/TilemapRenderSystem.ts
154
+ var import_core2 = require("@yagejs/core");
155
+
156
+ // src/TilemapComponent.ts
157
+ var import_core = require("@yagejs/core");
158
+ var import_pixi3 = require("pixi.js");
159
+ var import_renderer = require("@yagejs/renderer");
160
+
161
+ // src/tiled/parseTiledMap.ts
162
+ var import_tilemap = require("@pixi/tilemap");
163
+ var import_pixi2 = require("pixi.js");
164
+ function toTilemapData(map) {
165
+ const tileLayers = [];
166
+ const objectLayers = [];
167
+ for (const layer of map.layers) {
168
+ if (layer.type === "tilelayer") {
169
+ tileLayers.push({
170
+ name: layer.name,
171
+ data: layer.data,
172
+ width: layer.width,
173
+ height: layer.height,
174
+ visible: layer.visible
175
+ });
176
+ } else if (layer.type === "objectgroup") {
177
+ objectLayers.push({
178
+ name: layer.name,
179
+ objects: layer.objects.map(tiledObjectToMapObject),
180
+ visible: layer.visible
181
+ });
182
+ }
183
+ }
184
+ return {
185
+ width: map.width,
186
+ height: map.height,
187
+ tileWidth: map.tilewidth,
188
+ tileHeight: map.tileheight,
189
+ tileLayers,
190
+ objectLayers
191
+ };
192
+ }
193
+ __name(toTilemapData, "toTilemapData");
194
+ function tiledObjectToMapObject(obj) {
195
+ const result = {
196
+ id: obj.id,
197
+ name: obj.name,
198
+ x: obj.x,
199
+ y: obj.y,
200
+ width: obj.width,
201
+ height: obj.height,
202
+ rotation: obj.rotation,
203
+ visible: obj.visible
204
+ };
205
+ const cls = obj.class ?? obj.type;
206
+ if (cls) result.class = cls;
207
+ if (obj.point === true) result.point = true;
208
+ if (obj.polygon) result.polygon = obj.polygon;
209
+ if (obj.properties) {
210
+ result.properties = obj.properties.map((p) => ({
211
+ name: p.name,
212
+ type: p.type,
213
+ value: p.value
214
+ }));
215
+ }
216
+ return result;
217
+ }
218
+ __name(tiledObjectToMapObject, "tiledObjectToMapObject");
219
+ function findTileset(tilesets, gid) {
220
+ let result = null;
221
+ for (const ts of tilesets) {
222
+ if (ts.firstgid <= gid) {
223
+ if (!result || ts.firstgid > result.firstgid) {
224
+ result = ts;
225
+ }
226
+ }
227
+ }
228
+ return result;
229
+ }
230
+ __name(findTileset, "findTileset");
231
+ function resolveTileTexture(gid, tileset) {
232
+ const data = tileset.data;
233
+ if (!data) return null;
234
+ const localId = gid - tileset.firstgid;
235
+ if (data.tiles?.length) {
236
+ const tileData = data.tiles[localId];
237
+ if (!tileData?.image) return null;
238
+ const filenameMatch = tileData.image.match(/[^/]*$/);
239
+ const filename = filenameMatch?.[0];
240
+ if (!filename) return null;
241
+ const tex = import_pixi2.Assets.get(filename);
242
+ return tex ?? null;
243
+ }
244
+ if (data.image) {
245
+ const cacheKey = `${data.name}:${localId}`;
246
+ const tex = import_pixi2.Assets.get(cacheKey);
247
+ if (tex) return tex;
248
+ const filenameMatch = data.image.match(/[^/]*$/);
249
+ const filename = filenameMatch?.[0];
250
+ if (!filename) return null;
251
+ const baseTex = import_pixi2.Assets.get(filename);
252
+ if (!baseTex) return null;
253
+ const cols = data.columns;
254
+ const tw = data.tilewidth;
255
+ const th = data.tileheight;
256
+ const margin = data.margin ?? 0;
257
+ const spacing = data.spacing ?? 0;
258
+ const col = localId % cols;
259
+ const row = Math.floor(localId / cols);
260
+ const x = margin + col * (tw + spacing);
261
+ const y = margin + row * (th + spacing);
262
+ return new import_pixi2.Texture({
263
+ source: baseTex.source,
264
+ frame: new import_pixi2.Rectangle(x, y, tw, th)
265
+ });
266
+ }
267
+ return null;
268
+ }
269
+ __name(resolveTileTexture, "resolveTileTexture");
270
+ function createTilemapLayers(map, layerNames) {
271
+ const tileLayers = map.layers.filter(
272
+ (l) => l.type === "tilelayer"
273
+ );
274
+ const filtered = layerNames ? tileLayers.filter((l) => layerNames.includes(l.name)) : tileLayers;
275
+ return filtered.map((layer) => {
276
+ const tilemap = new import_tilemap.CompositeTilemap();
277
+ const { data, width } = layer;
278
+ for (let index = 0; index < data.length; index++) {
279
+ const gid = data[index];
280
+ if (gid === 0) continue;
281
+ const tileset = findTileset(map.tilesets, gid);
282
+ if (!tileset) {
283
+ throw new Error(`No tileset found for tile GID ${gid}`);
284
+ }
285
+ const texture = resolveTileTexture(gid, tileset);
286
+ if (!texture) {
287
+ throw new Error(
288
+ `Could not resolve texture for tile GID ${gid} in tileset "${tileset.data?.name}"`
289
+ );
290
+ }
291
+ const x = index % width;
292
+ const y = Math.floor(index / width);
293
+ tilemap.tile(texture, x * map.tilewidth, y * map.tileheight);
294
+ }
295
+ return tilemap;
296
+ });
297
+ }
298
+ __name(createTilemapLayers, "createTilemapLayers");
299
+ function extractObjects(map, objectLayerName) {
300
+ const objectLayers = map.layers.filter(
301
+ (l) => l.type === "objectgroup"
302
+ );
303
+ const filtered = objectLayerName ? objectLayers.filter((l) => l.name === objectLayerName) : objectLayers;
304
+ const result = {};
305
+ for (const layer of filtered) {
306
+ for (const obj of layer.objects) {
307
+ const key = obj.class ?? obj.type ?? obj.name;
308
+ if (!result[key]) {
309
+ result[key] = [];
310
+ }
311
+ result[key].push(obj);
312
+ }
313
+ }
314
+ return result;
315
+ }
316
+ __name(extractObjects, "extractObjects");
317
+
318
+ // src/colliders.ts
319
+ function extractCollisionShapes(map, objectLayerName) {
320
+ const filtered = objectLayerName ? map.objectLayers.filter((l) => l.name === objectLayerName) : map.objectLayers;
321
+ const shapes = [];
322
+ for (const layer of filtered) {
323
+ for (const obj of layer.objects) {
324
+ const shape = objectToColliderConfig(obj);
325
+ if (shape) shapes.push(shape);
326
+ }
327
+ }
328
+ return shapes;
329
+ }
330
+ __name(extractCollisionShapes, "extractCollisionShapes");
331
+ function objectToColliderConfig(obj) {
332
+ if (obj.point) return null;
333
+ if (obj.polygon) {
334
+ const config2 = {
335
+ type: "polygon",
336
+ x: obj.x,
337
+ y: obj.y,
338
+ vertices: obj.polygon.map((v) => ({ x: v.x, y: v.y }))
339
+ };
340
+ return config2;
341
+ }
342
+ const config = {
343
+ type: "rect",
344
+ x: obj.x,
345
+ y: obj.y,
346
+ width: obj.width,
347
+ height: obj.height
348
+ };
349
+ return config;
350
+ }
351
+ __name(objectToColliderConfig, "objectToColliderConfig");
352
+
353
+ // src/TilemapComponent.ts
354
+ var _TilemapComponent_decorators, _init, _a;
355
+ _TilemapComponent_decorators = [import_core.serializable];
356
+ var _TilemapComponent = class _TilemapComponent extends (_a = import_core.Component) {
357
+ static {
358
+ __name(this, "TilemapComponent");
359
+ }
360
+ container;
361
+ data;
362
+ _tiledMap;
363
+ _mapKey;
364
+ layerNames;
365
+ renderLayerName;
366
+ constructor(options) {
367
+ super();
368
+ if (!options.map && !options.mapKey) {
369
+ throw new Error(
370
+ "TilemapComponent requires either `map` or `mapKey`."
371
+ );
372
+ }
373
+ this._mapKey = options.mapKey ?? null;
374
+ const tiledMap2 = options.map ?? import_pixi3.Assets.get(options.mapKey);
375
+ if (!tiledMap2) {
376
+ throw new Error(
377
+ `TilemapComponent: map "${options.mapKey}" is not loaded. Add it to scene preload.`
378
+ );
379
+ }
380
+ this._tiledMap = tiledMap2;
381
+ this.data = toTilemapData(tiledMap2);
382
+ this.layerNames = options.layers;
383
+ this.renderLayerName = options.layer ?? "default";
384
+ this.container = new import_pixi3.Container();
385
+ }
386
+ onAdd() {
387
+ const tilemapLayers = createTilemapLayers(this._tiledMap, this.layerNames);
388
+ for (const layer of tilemapLayers) {
389
+ this.container.addChild(layer);
390
+ }
391
+ const layers = this.use(import_renderer.RenderLayerManagerKey);
392
+ const renderLayer = layers.get(this.renderLayerName);
393
+ renderLayer.container.addChild(this.container);
394
+ }
395
+ onDestroy() {
396
+ this.container.removeFromParent();
397
+ this.container.destroy({ children: true });
398
+ }
399
+ serialize() {
400
+ if (!this._mapKey) {
401
+ console.warn(
402
+ `TilemapComponent on "${this.entity?.name}": created with a TiledMapData object. Use { mapKey } for save/load support.`
403
+ );
404
+ return null;
405
+ }
406
+ return {
407
+ mapKey: this._mapKey,
408
+ layer: this.renderLayerName,
409
+ ...this.layerNames && { layers: this.layerNames }
410
+ };
411
+ }
412
+ static fromSnapshot(data) {
413
+ return new _TilemapComponent({
414
+ mapKey: data.mapKey,
415
+ layer: data.layer,
416
+ ...data.layers && { layers: data.layers }
417
+ });
418
+ }
419
+ /** Map width in pixels. */
420
+ get widthPx() {
421
+ return this.data.width * this.data.tileWidth;
422
+ }
423
+ /** Map height in pixels. */
424
+ get heightPx() {
425
+ return this.data.height * this.data.tileHeight;
426
+ }
427
+ /** Tile width in pixels. */
428
+ get tileWidth() {
429
+ return this.data.tileWidth;
430
+ }
431
+ /** Tile height in pixels. */
432
+ get tileHeight() {
433
+ return this.data.tileHeight;
434
+ }
435
+ /**
436
+ * Returns the tile GID at a world position, accounting for entity Transform offset.
437
+ * Returns null if the position is outside the map or the tile is empty.
438
+ */
439
+ getTileAt(worldX, worldY, layerName) {
440
+ const transform = this.entity.tryGet(import_core.Transform);
441
+ const offsetX = transform ? transform.position.x : 0;
442
+ const offsetY = transform ? transform.position.y : 0;
443
+ const localX = worldX - offsetX;
444
+ const localY = worldY - offsetY;
445
+ const col = Math.floor(localX / this.data.tileWidth);
446
+ const row = Math.floor(localY / this.data.tileHeight);
447
+ if (col < 0 || col >= this.data.width) return null;
448
+ if (row < 0 || row >= this.data.height) return null;
449
+ const layers = layerName ? this.data.tileLayers.filter((l) => l.name === layerName) : this.data.tileLayers;
450
+ for (let i = layers.length - 1; i >= 0; i--) {
451
+ const layer = layers[i];
452
+ const gid = layer.data[row * layer.width + col];
453
+ if (gid !== void 0 && gid !== 0) return gid;
454
+ }
455
+ return null;
456
+ }
457
+ /** Extract physics-agnostic collision shapes from object layers. */
458
+ getCollisionShapes(objectLayerName) {
459
+ return extractCollisionShapes(this.data, objectLayerName);
460
+ }
461
+ /** Extract objects from object layers grouped by class/name. */
462
+ getObjects(objectLayerName) {
463
+ const filtered = objectLayerName ? this.data.objectLayers.filter((l) => l.name === objectLayerName) : this.data.objectLayers;
464
+ const result = {};
465
+ for (const layer of filtered) {
466
+ for (const obj of layer.objects) {
467
+ const key = obj.class ?? obj.name;
468
+ if (!result[key]) {
469
+ result[key] = [];
470
+ }
471
+ result[key].push(obj);
472
+ }
473
+ }
474
+ return result;
475
+ }
476
+ };
477
+ _init = __decoratorStart(_a);
478
+ _TilemapComponent = __decorateElement(_init, 0, "TilemapComponent", _TilemapComponent_decorators, _TilemapComponent);
479
+ __runInitializers(_init, 1, _TilemapComponent);
480
+ var TilemapComponent = _TilemapComponent;
481
+
482
+ // src/TilemapRenderSystem.ts
483
+ var TilemapRenderSystem = class extends import_core2.System {
484
+ static {
485
+ __name(this, "TilemapRenderSystem");
486
+ }
487
+ phase = import_core2.Phase.Render;
488
+ priority = -1;
489
+ // Before DisplaySystem (0), so tilemaps render behind sprites
490
+ query;
491
+ onRegister(context) {
492
+ const queryCache = context.resolve(import_core2.QueryCacheKey);
493
+ this.query = queryCache.register([import_core2.Transform, TilemapComponent]);
494
+ }
495
+ update() {
496
+ for (const entity of this.query) {
497
+ const transform = entity.get(import_core2.Transform);
498
+ const tilemap = entity.get(TilemapComponent);
499
+ if (!tilemap.enabled) continue;
500
+ tilemap.container.position.x = transform.worldPosition.x;
501
+ tilemap.container.position.y = transform.worldPosition.y;
502
+ tilemap.container.rotation = transform.worldRotation;
503
+ tilemap.container.scale.x = transform.worldScale.x;
504
+ tilemap.container.scale.y = transform.worldScale.y;
505
+ }
506
+ }
507
+ };
508
+
509
+ // src/TilemapPlugin.ts
510
+ var TilemapPlugin = class {
511
+ static {
512
+ __name(this, "TilemapPlugin");
513
+ }
514
+ name = "tilemap";
515
+ version = "2.0.0";
516
+ dependencies = ["renderer"];
517
+ install(context) {
518
+ import_pixi4.extensions.add(tiledMapAssetExtension);
519
+ const am = context.tryResolve(import_core3.AssetManagerKey);
520
+ am?.registerLoader("tiledMap", {
521
+ load: /* @__PURE__ */ __name((path2) => import_pixi4.Assets.load(path2), "load"),
522
+ unload: /* @__PURE__ */ __name((path2) => {
523
+ import_pixi4.Assets.unload(path2);
524
+ }, "unload")
525
+ });
526
+ }
527
+ registerSystems(scheduler) {
528
+ scheduler.add(new TilemapRenderSystem());
529
+ }
530
+ };
531
+
532
+ // src/assets.ts
533
+ var import_core4 = require("@yagejs/core");
534
+ function tiledMap(path2) {
535
+ return new import_core4.AssetHandle("tiledMap", path2);
536
+ }
537
+ __name(tiledMap, "tiledMap");
538
+
539
+ // src/toPhysicsColliders.ts
540
+ function toPhysicsColliders(shapes) {
541
+ return shapes.map(toPhysicsCollider);
542
+ }
543
+ __name(toPhysicsColliders, "toPhysicsColliders");
544
+ function toPhysicsCollider(config) {
545
+ switch (config.type) {
546
+ case "polygon":
547
+ return {
548
+ shape: {
549
+ type: "polygon",
550
+ vertices: config.vertices
551
+ },
552
+ offset: { x: config.x, y: config.y }
553
+ };
554
+ case "rect":
555
+ return {
556
+ shape: { type: "box", width: config.width, height: config.height },
557
+ offset: {
558
+ x: config.x + config.width / 2,
559
+ y: config.y + config.height / 2
560
+ }
561
+ };
562
+ }
563
+ }
564
+ __name(toPhysicsCollider, "toPhysicsCollider");
565
+
566
+ // src/properties.ts
567
+ function getProperty(obj, name) {
568
+ const prop = obj.properties?.find((p) => p.name === name);
569
+ return prop?.value;
570
+ }
571
+ __name(getProperty, "getProperty");
572
+ function getPropertyArray(obj, name) {
573
+ const pattern = new RegExp(`^${escapeRegex(name)}\\[(\\d+)\\]$`);
574
+ const values = [];
575
+ if (!obj.properties) return values;
576
+ for (const prop of obj.properties) {
577
+ const match = prop.name.match(pattern);
578
+ if (match) {
579
+ const index = Number.parseInt(match[1], 10);
580
+ values[index] = prop.value;
581
+ }
582
+ }
583
+ return values;
584
+ }
585
+ __name(getPropertyArray, "getPropertyArray");
586
+ function resolveObjectRef(obj, propName, allObjects) {
587
+ const id = getProperty(obj, propName);
588
+ if (id === void 0) return void 0;
589
+ return allObjects.find((o) => o.id === id);
590
+ }
591
+ __name(resolveObjectRef, "resolveObjectRef");
592
+ function resolveObjectRefArray(obj, propName, allObjects) {
593
+ const ids = getPropertyArray(obj, propName);
594
+ return ids.map((id) => allObjects.find((o) => o.id === id)).filter((o) => o !== void 0);
595
+ }
596
+ __name(resolveObjectRefArray, "resolveObjectRefArray");
597
+ function escapeRegex(str) {
598
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
599
+ }
600
+ __name(escapeRegex, "escapeRegex");
601
+ // Annotate the CommonJS export names for ESM import in node:
602
+ 0 && (module.exports = {
603
+ TilemapComponent,
604
+ TilemapPlugin,
605
+ TilemapRenderSystem,
606
+ createTilemapLayers,
607
+ extractCollisionShapes,
608
+ extractObjects,
609
+ getProperty,
610
+ getPropertyArray,
611
+ resolveObjectRef,
612
+ resolveObjectRefArray,
613
+ tiledMap,
614
+ tiledMapAssetExtension,
615
+ toPhysicsColliders,
616
+ toTilemapData
617
+ });
618
+ //# sourceMappingURL=index.cjs.map