@yagejs/tilemap 0.4.0 → 0.6.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/index.cjs +166 -53
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +63 -6
- package/dist/index.d.ts +63 -6
- package/dist/index.js +165 -53
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -77,6 +77,7 @@ __export(index_exports, {
|
|
|
77
77
|
resolveObjectRefArray: () => resolveObjectRefArray,
|
|
78
78
|
tiledMap: () => tiledMap,
|
|
79
79
|
tiledMapAssetExtension: () => tiledMapAssetExtension,
|
|
80
|
+
tiledObjectKey: () => tiledObjectKey,
|
|
80
81
|
toPhysicsColliders: () => toPhysicsColliders,
|
|
81
82
|
toTilemapData: () => toTilemapData
|
|
82
83
|
});
|
|
@@ -350,6 +351,48 @@ function objectToColliderConfig(obj) {
|
|
|
350
351
|
}
|
|
351
352
|
__name(objectToColliderConfig, "objectToColliderConfig");
|
|
352
353
|
|
|
354
|
+
// src/keys.ts
|
|
355
|
+
function tiledObjectKey(prefix, objectId) {
|
|
356
|
+
return `${prefix}#object:${objectId}`;
|
|
357
|
+
}
|
|
358
|
+
__name(tiledObjectKey, "tiledObjectKey");
|
|
359
|
+
|
|
360
|
+
// src/properties.ts
|
|
361
|
+
function getProperty(obj, name) {
|
|
362
|
+
const prop = obj.properties?.find((p) => p.name === name);
|
|
363
|
+
return prop?.value;
|
|
364
|
+
}
|
|
365
|
+
__name(getProperty, "getProperty");
|
|
366
|
+
function getPropertyArray(obj, name) {
|
|
367
|
+
const pattern = new RegExp(`^${escapeRegex(name)}\\[(\\d+)\\]$`);
|
|
368
|
+
const values = [];
|
|
369
|
+
if (!obj.properties) return values;
|
|
370
|
+
for (const prop of obj.properties) {
|
|
371
|
+
const match = prop.name.match(pattern);
|
|
372
|
+
if (match) {
|
|
373
|
+
const index = Number.parseInt(match[1], 10);
|
|
374
|
+
values[index] = prop.value;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
return values;
|
|
378
|
+
}
|
|
379
|
+
__name(getPropertyArray, "getPropertyArray");
|
|
380
|
+
function resolveObjectRef(obj, propName, allObjects) {
|
|
381
|
+
const id = getProperty(obj, propName);
|
|
382
|
+
if (id === void 0) return void 0;
|
|
383
|
+
return allObjects.find((o) => o.id === id);
|
|
384
|
+
}
|
|
385
|
+
__name(resolveObjectRef, "resolveObjectRef");
|
|
386
|
+
function resolveObjectRefArray(obj, propName, allObjects) {
|
|
387
|
+
const ids = getPropertyArray(obj, propName);
|
|
388
|
+
return ids.map((id) => allObjects.find((o) => o.id === id)).filter((o) => o !== void 0);
|
|
389
|
+
}
|
|
390
|
+
__name(resolveObjectRefArray, "resolveObjectRefArray");
|
|
391
|
+
function escapeRegex(str) {
|
|
392
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
393
|
+
}
|
|
394
|
+
__name(escapeRegex, "escapeRegex");
|
|
395
|
+
|
|
353
396
|
// src/TilemapComponent.ts
|
|
354
397
|
var _TilemapComponent_decorators, _init, _a;
|
|
355
398
|
_TilemapComponent_decorators = [import_core.serializable];
|
|
@@ -359,28 +402,51 @@ var _TilemapComponent = class _TilemapComponent extends (_a = import_core.Compon
|
|
|
359
402
|
}
|
|
360
403
|
container;
|
|
361
404
|
data;
|
|
405
|
+
/** Asset path of this map, or `null` if constructed from a raw `TiledMapData` without one. */
|
|
406
|
+
mapKey;
|
|
407
|
+
/** Prefix used to derive auto-keys for entities spawned from objects. */
|
|
408
|
+
keyPrefix;
|
|
362
409
|
_tiledMap;
|
|
363
|
-
_mapKey;
|
|
364
410
|
layerNames;
|
|
365
411
|
renderLayerName;
|
|
412
|
+
_explicitKeyPrefix;
|
|
413
|
+
/** Lazy flat-list cache. The parsed map is treated as immutable post-construction; if that ever changes, callers must invalidate. */
|
|
414
|
+
_allObjectsCache;
|
|
366
415
|
constructor(options) {
|
|
367
416
|
super();
|
|
368
|
-
|
|
417
|
+
const sourceCount = (options.source ? 1 : 0) + (options.map ? 1 : 0) + (options.mapKey ? 1 : 0);
|
|
418
|
+
if (sourceCount === 0) {
|
|
369
419
|
throw new Error(
|
|
370
|
-
"TilemapComponent requires
|
|
420
|
+
"TilemapComponent requires one of `source`, `map`, or `mapKey`."
|
|
371
421
|
);
|
|
372
422
|
}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
423
|
+
if (options.source) {
|
|
424
|
+
this.mapKey = options.source.path;
|
|
425
|
+
const data = import_pixi3.Assets.get(options.source.path);
|
|
426
|
+
if (!data) {
|
|
427
|
+
throw new Error(
|
|
428
|
+
`TilemapComponent: source "${options.source.path}" is not loaded. Add it to scene preload.`
|
|
429
|
+
);
|
|
430
|
+
}
|
|
431
|
+
this._tiledMap = data;
|
|
432
|
+
} else if (options.mapKey) {
|
|
433
|
+
this.mapKey = options.mapKey;
|
|
434
|
+
const data = import_pixi3.Assets.get(options.mapKey);
|
|
435
|
+
if (!data) {
|
|
436
|
+
throw new Error(
|
|
437
|
+
`TilemapComponent: map "${options.mapKey}" is not loaded. Add it to scene preload.`
|
|
438
|
+
);
|
|
439
|
+
}
|
|
440
|
+
this._tiledMap = data;
|
|
441
|
+
} else {
|
|
442
|
+
this.mapKey = null;
|
|
443
|
+
this._tiledMap = options.map;
|
|
379
444
|
}
|
|
380
|
-
this.
|
|
381
|
-
this.data = toTilemapData(tiledMap2);
|
|
445
|
+
this.data = toTilemapData(this._tiledMap);
|
|
382
446
|
this.layerNames = options.layers;
|
|
383
447
|
this.renderLayerName = options.layer ?? "default";
|
|
448
|
+
this._explicitKeyPrefix = options.keyPrefix;
|
|
449
|
+
this.keyPrefix = options.keyPrefix ?? this.mapKey;
|
|
384
450
|
this.container = new import_pixi3.Container();
|
|
385
451
|
}
|
|
386
452
|
onAdd() {
|
|
@@ -396,23 +462,27 @@ var _TilemapComponent = class _TilemapComponent extends (_a = import_core.Compon
|
|
|
396
462
|
this.container.destroy({ children: true });
|
|
397
463
|
}
|
|
398
464
|
serialize() {
|
|
399
|
-
if (!this.
|
|
465
|
+
if (!this.mapKey) {
|
|
400
466
|
console.warn(
|
|
401
|
-
`TilemapComponent on "${this.entity?.name}": created with a TiledMapData object. Use { mapKey } for save/load support.`
|
|
467
|
+
`TilemapComponent on "${this.entity?.name}": created with a TiledMapData object. Use { source } or { mapKey } for save/load support.`
|
|
402
468
|
);
|
|
403
469
|
return null;
|
|
404
470
|
}
|
|
405
471
|
return {
|
|
406
|
-
mapKey: this.
|
|
472
|
+
mapKey: this.mapKey,
|
|
407
473
|
layer: this.renderLayerName,
|
|
408
|
-
...this.layerNames && { layers: this.layerNames }
|
|
474
|
+
...this.layerNames && { layers: this.layerNames },
|
|
475
|
+
...this._explicitKeyPrefix !== void 0 && {
|
|
476
|
+
keyPrefix: this._explicitKeyPrefix
|
|
477
|
+
}
|
|
409
478
|
};
|
|
410
479
|
}
|
|
411
480
|
static fromSnapshot(data) {
|
|
412
481
|
return new _TilemapComponent({
|
|
413
482
|
mapKey: data.mapKey,
|
|
414
483
|
layer: data.layer,
|
|
415
|
-
...data.layers && { layers: data.layers }
|
|
484
|
+
...data.layers && { layers: data.layers },
|
|
485
|
+
...data.keyPrefix !== void 0 && { keyPrefix: data.keyPrefix }
|
|
416
486
|
});
|
|
417
487
|
}
|
|
418
488
|
/** Map width in pixels. */
|
|
@@ -457,7 +527,7 @@ var _TilemapComponent = class _TilemapComponent extends (_a = import_core.Compon
|
|
|
457
527
|
getCollisionShapes(objectLayerName) {
|
|
458
528
|
return extractCollisionShapes(this.data, objectLayerName);
|
|
459
529
|
}
|
|
460
|
-
/**
|
|
530
|
+
/** Objects from object layers grouped by `class ?? name`. Use a layer name to scope. */
|
|
461
531
|
getObjects(objectLayerName) {
|
|
462
532
|
const filtered = objectLayerName ? this.data.objectLayers.filter((l) => l.name === objectLayerName) : this.data.objectLayers;
|
|
463
533
|
const result = {};
|
|
@@ -472,6 +542,84 @@ var _TilemapComponent = class _TilemapComponent extends (_a = import_core.Compon
|
|
|
472
542
|
}
|
|
473
543
|
return result;
|
|
474
544
|
}
|
|
545
|
+
/** Flat list of every object across every object layer. Memoized — safe because parsed map data is immutable post-construction. */
|
|
546
|
+
getAllObjects() {
|
|
547
|
+
if (this._allObjectsCache) return this._allObjectsCache;
|
|
548
|
+
const result = [];
|
|
549
|
+
for (const layer of this.data.objectLayers) {
|
|
550
|
+
for (const obj of layer.objects) result.push(obj);
|
|
551
|
+
}
|
|
552
|
+
this._allObjectsCache = result;
|
|
553
|
+
return result;
|
|
554
|
+
}
|
|
555
|
+
/**
|
|
556
|
+
* Iterate every object on the given layer (or every layer if omitted),
|
|
557
|
+
* passing the auto-derived stable key alongside each object so callers can
|
|
558
|
+
* spawn entities with `scene.spawn(Class, params, { key })`.
|
|
559
|
+
*
|
|
560
|
+
* Skips objects that don't have a key prefix (component constructed from raw
|
|
561
|
+
* `map:` without `mapKey` or `keyPrefix`) — those callers should iterate
|
|
562
|
+
* `getObjects` directly.
|
|
563
|
+
*/
|
|
564
|
+
forEachObject(layerName, fn) {
|
|
565
|
+
if (this.keyPrefix === null) {
|
|
566
|
+
throw new Error(
|
|
567
|
+
"TilemapComponent.forEachObject: cannot derive auto-keys without a `mapKey`, `source`, or explicit `keyPrefix`."
|
|
568
|
+
);
|
|
569
|
+
}
|
|
570
|
+
const layers = layerName ? this.data.objectLayers.filter((l) => l.name === layerName) : this.data.objectLayers;
|
|
571
|
+
for (const layer of layers) {
|
|
572
|
+
for (const obj of layer.objects) {
|
|
573
|
+
fn(obj, tiledObjectKey(this.keyPrefix, obj.id));
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
/** Auto-derived stable key for an object: `<keyPrefix>#object:<id>`. */
|
|
578
|
+
objectKey(obj) {
|
|
579
|
+
if (this.keyPrefix === null) {
|
|
580
|
+
throw new Error(
|
|
581
|
+
"TilemapComponent.objectKey: cannot derive a key without a `mapKey`, `source`, or explicit `keyPrefix`."
|
|
582
|
+
);
|
|
583
|
+
}
|
|
584
|
+
return tiledObjectKey(this.keyPrefix, obj.id);
|
|
585
|
+
}
|
|
586
|
+
/** Find an object by its Tiled `id`. Searches every object layer. */
|
|
587
|
+
findObject(id) {
|
|
588
|
+
for (const layer of this.data.objectLayers) {
|
|
589
|
+
for (const obj of layer.objects) {
|
|
590
|
+
if (obj.id === id) return obj;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
return void 0;
|
|
594
|
+
}
|
|
595
|
+
/** Find the first object with a matching `name`. Searches every object layer. */
|
|
596
|
+
findObjectByName(name) {
|
|
597
|
+
for (const layer of this.data.objectLayers) {
|
|
598
|
+
for (const obj of layer.objects) {
|
|
599
|
+
if (obj.name === name) return obj;
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
return void 0;
|
|
603
|
+
}
|
|
604
|
+
/** Read a typed custom property off any tilemap object. */
|
|
605
|
+
getProperty(obj, name) {
|
|
606
|
+
return getProperty(obj, name);
|
|
607
|
+
}
|
|
608
|
+
/** Read an indexed property bag (`name[0]`, `name[1]`, ...) as an array. */
|
|
609
|
+
getPropertyArray(obj, name) {
|
|
610
|
+
return getPropertyArray(obj, name);
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* Resolve a Tiled object-reference property to the actual object.
|
|
614
|
+
* Auto-collects across every layer so callers don't have to.
|
|
615
|
+
*/
|
|
616
|
+
resolveRef(obj, propName) {
|
|
617
|
+
return resolveObjectRef(obj, propName, this.getAllObjects());
|
|
618
|
+
}
|
|
619
|
+
/** Same as `resolveRef`, but for indexed object-reference arrays. */
|
|
620
|
+
resolveRefArray(obj, propName) {
|
|
621
|
+
return resolveObjectRefArray(obj, propName, this.getAllObjects());
|
|
622
|
+
}
|
|
475
623
|
};
|
|
476
624
|
_init = __decoratorStart(_a);
|
|
477
625
|
_TilemapComponent = __decorateElement(_init, 0, "TilemapComponent", _TilemapComponent_decorators, _TilemapComponent);
|
|
@@ -561,42 +709,6 @@ function toPhysicsCollider(config) {
|
|
|
561
709
|
}
|
|
562
710
|
}
|
|
563
711
|
__name(toPhysicsCollider, "toPhysicsCollider");
|
|
564
|
-
|
|
565
|
-
// src/properties.ts
|
|
566
|
-
function getProperty(obj, name) {
|
|
567
|
-
const prop = obj.properties?.find((p) => p.name === name);
|
|
568
|
-
return prop?.value;
|
|
569
|
-
}
|
|
570
|
-
__name(getProperty, "getProperty");
|
|
571
|
-
function getPropertyArray(obj, name) {
|
|
572
|
-
const pattern = new RegExp(`^${escapeRegex(name)}\\[(\\d+)\\]$`);
|
|
573
|
-
const values = [];
|
|
574
|
-
if (!obj.properties) return values;
|
|
575
|
-
for (const prop of obj.properties) {
|
|
576
|
-
const match = prop.name.match(pattern);
|
|
577
|
-
if (match) {
|
|
578
|
-
const index = Number.parseInt(match[1], 10);
|
|
579
|
-
values[index] = prop.value;
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
return values;
|
|
583
|
-
}
|
|
584
|
-
__name(getPropertyArray, "getPropertyArray");
|
|
585
|
-
function resolveObjectRef(obj, propName, allObjects) {
|
|
586
|
-
const id = getProperty(obj, propName);
|
|
587
|
-
if (id === void 0) return void 0;
|
|
588
|
-
return allObjects.find((o) => o.id === id);
|
|
589
|
-
}
|
|
590
|
-
__name(resolveObjectRef, "resolveObjectRef");
|
|
591
|
-
function resolveObjectRefArray(obj, propName, allObjects) {
|
|
592
|
-
const ids = getPropertyArray(obj, propName);
|
|
593
|
-
return ids.map((id) => allObjects.find((o) => o.id === id)).filter((o) => o !== void 0);
|
|
594
|
-
}
|
|
595
|
-
__name(resolveObjectRefArray, "resolveObjectRefArray");
|
|
596
|
-
function escapeRegex(str) {
|
|
597
|
-
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
598
|
-
}
|
|
599
|
-
__name(escapeRegex, "escapeRegex");
|
|
600
712
|
// Annotate the CommonJS export names for ESM import in node:
|
|
601
713
|
0 && (module.exports = {
|
|
602
714
|
TilemapComponent,
|
|
@@ -611,6 +723,7 @@ __name(escapeRegex, "escapeRegex");
|
|
|
611
723
|
resolveObjectRefArray,
|
|
612
724
|
tiledMap,
|
|
613
725
|
tiledMapAssetExtension,
|
|
726
|
+
tiledObjectKey,
|
|
614
727
|
toPhysicsColliders,
|
|
615
728
|
toTilemapData
|
|
616
729
|
});
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/TilemapPlugin.ts","../src/tiled/tiledMapLoader.ts","../src/TilemapRenderSystem.ts","../src/TilemapComponent.ts","../src/tiled/parseTiledMap.ts","../src/colliders.ts","../src/assets.ts","../src/toPhysicsColliders.ts","../src/properties.ts"],"sourcesContent":["// Plugin\nexport { TilemapPlugin } from \"./TilemapPlugin.js\";\n\n// Component\nexport { TilemapComponent } from \"./TilemapComponent.js\";\nexport type {\n TilemapComponentOptions,\n TilemapComponentData,\n} from \"./TilemapComponent.js\";\n\n// System\nexport { TilemapRenderSystem } from \"./TilemapRenderSystem.js\";\n\n// Asset handle factory\nexport { tiledMap } from \"./assets.js\";\n\n// Collision extraction\nexport { extractCollisionShapes } from \"./colliders.js\";\nexport { toPhysicsColliders } from \"./toPhysicsColliders.js\";\n\n// Property utilities\nexport {\n getProperty,\n getPropertyArray,\n resolveObjectRef,\n resolveObjectRefArray,\n} from \"./properties.js\";\n\n// Generic types\nexport type {\n TilemapData,\n TileLayerData,\n ObjectLayerData,\n MapObject,\n MapObjectProperty,\n HasProperties,\n TilemapColliderConfig,\n RectColliderConfig,\n PolygonColliderConfig,\n} from \"./types.js\";\n\n// Tiled-specific (re-exported for backward compatibility)\nexport { tiledMapAssetExtension } from \"./tiled/tiledMapLoader.js\";\nexport {\n createTilemapLayers,\n extractObjects,\n toTilemapData,\n} from \"./tiled/parseTiledMap.js\";\nexport type {\n TiledMapData,\n TileLayer,\n ObjectGroup,\n TileObject,\n RectangleObject,\n PolygonObject,\n PointObject,\n TileObjectProperty,\n TilesetRef,\n TilesetData,\n TileData,\n} from \"./tiled/types.js\";\n","import { AssetManagerKey } from \"@yagejs/core\";\nimport type { EngineContext, Plugin, SystemScheduler } from \"@yagejs/core\";\nimport { extensions, Assets } from \"pixi.js\";\nimport { tiledMapAssetExtension } from \"./tiled/tiledMapLoader.js\";\nimport { TilemapRenderSystem } from \"./TilemapRenderSystem.js\";\nimport type { TiledMapData } from \"./tiled/types.js\";\n\n/** Plugin that adds Tiled map loading and rendering to YAGE. */\nexport class TilemapPlugin implements Plugin {\n readonly name = \"tilemap\";\n readonly version = \"2.0.0\";\n readonly dependencies = [\"renderer\"] as const;\n\n install(context: EngineContext): void {\n // Register PixiJS loader extension for Tiled map JSON files\n extensions.add(tiledMapAssetExtension);\n\n // Register \"tiledMap\" loader with AssetManager\n const am = context.tryResolve(AssetManagerKey);\n am?.registerLoader(\"tiledMap\", {\n load: (path: string) => Assets.load<TiledMapData>(path),\n unload: (path: string) => {\n Assets.unload(path);\n },\n });\n }\n\n registerSystems(scheduler: SystemScheduler): void {\n scheduler.add(new TilemapRenderSystem());\n }\n}\n","import {\n ExtensionType,\n LoaderParserPriority,\n Assets,\n path,\n Texture,\n Rectangle,\n} from \"pixi.js\";\nimport type { LoaderParser, ResolvedAsset, Loader } from \"pixi.js\";\nimport type { TiledMapData, TilesetData, TilesetRef } from \"./types.js\";\n\n/**\n * PixiJS loader extension that detects Tiled map JSON files and resolves\n * their tileset references.\n *\n * Supports two tileset formats:\n * 1. **Collection-of-images** — tileset has `tiles[]` with image paths.\n * Assumes textures are already in the PixiJS cache (e.g. from a\n * pre-loaded spritesheet atlas).\n * 2. **Single-image tileset** — tileset has an `image` property pointing\n * to a spritesheet. The loader loads the image and creates sub-textures\n * for each tile based on grid layout.\n */\nconst tiledMapLoaderParser: LoaderParser<TiledMapData> = {\n id: \"tiledMapLoader\",\n\n extension: {\n type: ExtensionType.LoadParser,\n priority: LoaderParserPriority.High,\n },\n\n async testParse(\n asset: TiledMapData,\n resolvedAsset?: ResolvedAsset,\n ): Promise<boolean> {\n if (!resolvedAsset?.src) return false;\n if (path.extname(resolvedAsset.src).toLowerCase() !== \".json\") return false;\n const obj = asset as unknown as Record<string, unknown>;\n return !!(obj.tilesets && obj.layers);\n },\n\n async parse(\n asset: TiledMapData,\n resolvedAsset?: ResolvedAsset,\n loader?: Loader,\n ): Promise<TiledMapData> {\n const src = resolvedAsset?.src;\n if (!src || !loader) return asset;\n\n let basePath = path.dirname(src);\n if (basePath && !basePath.endsWith(\"/\")) {\n basePath += \"/\";\n }\n\n for (const tilesetRef of asset.tilesets as TilesetRef[]) {\n if (tilesetRef.source) {\n // External tileset JSON — load it\n const tilesetPath = basePath + tilesetRef.source;\n const tilesetData = (await loader.load<TilesetData>({\n src: tilesetPath,\n })) as TilesetData;\n tilesetRef.data = tilesetData;\n }\n\n const tileset = tilesetRef.data;\n if (!tileset) continue;\n\n // Single-image tileset: load the image and create sub-textures\n if (tileset.image && !tileset.tiles?.length) {\n const imagePath = basePath + tileset.image;\n const baseTexture = await Assets.load<Texture>(imagePath);\n const cols = tileset.columns;\n const tw = tileset.tilewidth;\n const th = tileset.tileheight;\n const margin = tileset.margin ?? 0;\n const spacing = tileset.spacing ?? 0;\n\n for (let id = 0; id < tileset.tilecount; id++) {\n const col = id % cols;\n const row = Math.floor(id / cols);\n const x = margin + col * (tw + spacing);\n const y = margin + row * (th + spacing);\n\n const frame = new Rectangle(x, y, tw, th);\n const subtex = new Texture({\n source: baseTexture.source,\n frame,\n });\n\n // Store subtexture in PixiJS cache with a key like \"tileset-name:id\"\n const cacheKey = `${tileset.name}:${id}`;\n Assets.cache.set(cacheKey, subtex);\n }\n }\n // Collection-of-images: textures are expected to already be\n // in the PixiJS cache (loaded via spritesheet atlas).\n }\n\n return asset;\n },\n\n unload() {},\n};\n\n/** PixiJS asset extension bundle for Tiled map JSON files. */\nexport const tiledMapAssetExtension = {\n extension: ExtensionType.Asset,\n loader: tiledMapLoaderParser,\n};\n","import { System, Phase, Transform, QueryCacheKey } from \"@yagejs/core\";\nimport type { EngineContext, QueryResult } from \"@yagejs/core\";\nimport { TilemapComponent } from \"./TilemapComponent.js\";\n\n/** Syncs Transform to TilemapComponent display containers. */\nexport class TilemapRenderSystem extends System {\n readonly phase = Phase.Render;\n readonly priority = -1; // Before DisplaySystem (0), so tilemaps render behind sprites\n\n private query!: QueryResult;\n\n onRegister(context: EngineContext): void {\n const queryCache = context.resolve(QueryCacheKey);\n this.query = queryCache.register([Transform, TilemapComponent]);\n }\n\n update(): void {\n for (const entity of this.query) {\n const transform = entity.get(Transform);\n const tilemap = entity.get(TilemapComponent);\n if (!tilemap.enabled) continue;\n\n tilemap.container.position.x = transform.worldPosition.x;\n tilemap.container.position.y = transform.worldPosition.y;\n tilemap.container.rotation = transform.worldRotation;\n tilemap.container.scale.x = transform.worldScale.x;\n tilemap.container.scale.y = transform.worldScale.y;\n }\n }\n}\n","import { Component, Transform, serializable } from \"@yagejs/core\";\nimport { Assets, Container } from \"pixi.js\";\nimport { SceneRenderTreeKey } from \"@yagejs/renderer\";\nimport { createTilemapLayers, toTilemapData } from \"./tiled/parseTiledMap.js\";\nimport { extractCollisionShapes } from \"./colliders.js\";\nimport type { TiledMapData } from \"./tiled/types.js\";\nimport type {\n TilemapData,\n MapObject,\n TilemapColliderConfig,\n} from \"./types.js\";\n\n/** Options for creating a TilemapComponent. */\nexport interface TilemapComponentOptions {\n /** Parsed Tiled map data (not serializable). */\n map?: TiledMapData;\n /** Asset path to the Tiled JSON (serializable, resolved via Assets.get). */\n mapKey?: string;\n /** Which tile layers to render. Omit to render all. */\n layers?: string[];\n /** Render layer name. Default: \"default\". */\n layer?: string;\n}\n\n/** Serializable snapshot of a TilemapComponent. */\nexport interface TilemapComponentData {\n mapKey: string;\n layers?: string[];\n layer: string;\n}\n\n/** Component that renders a Tiled map using @pixi/tilemap. */\n@serializable\nexport class TilemapComponent extends Component {\n readonly container: Container;\n readonly data: TilemapData;\n private readonly _tiledMap: TiledMapData;\n private readonly _mapKey: string | null;\n private readonly layerNames: string[] | undefined;\n private readonly renderLayerName: string;\n\n constructor(options: TilemapComponentOptions) {\n super();\n\n if (!options.map && !options.mapKey) {\n throw new Error(\n \"TilemapComponent requires either `map` or `mapKey`.\",\n );\n }\n\n this._mapKey = options.mapKey ?? null;\n const tiledMap = options.map ?? Assets.get<TiledMapData>(options.mapKey!);\n if (!tiledMap) {\n throw new Error(\n `TilemapComponent: map \"${options.mapKey}\" is not loaded. Add it to scene preload.`,\n );\n }\n\n this._tiledMap = tiledMap;\n this.data = toTilemapData(tiledMap);\n this.layerNames = options.layers;\n this.renderLayerName = options.layer ?? \"default\";\n this.container = new Container();\n }\n\n onAdd(): void {\n const tilemapLayers = createTilemapLayers(this._tiledMap, this.layerNames);\n for (const layer of tilemapLayers) {\n this.container.addChild(layer);\n }\n\n const renderLayer = this.use(SceneRenderTreeKey).get(this.renderLayerName);\n renderLayer.container.addChild(this.container);\n }\n\n onDestroy(): void {\n this.container.removeFromParent();\n this.container.destroy({ children: true });\n }\n\n serialize(): TilemapComponentData | null {\n if (!this._mapKey) {\n console.warn(\n `TilemapComponent on \"${this.entity?.name}\": created with a TiledMapData object. ` +\n `Use { mapKey } for save/load support.`,\n );\n return null;\n }\n return {\n mapKey: this._mapKey,\n layer: this.renderLayerName,\n ...(this.layerNames && { layers: this.layerNames }),\n };\n }\n\n static fromSnapshot(data: TilemapComponentData): TilemapComponent {\n return new TilemapComponent({\n mapKey: data.mapKey,\n layer: data.layer,\n ...(data.layers && { layers: data.layers }),\n });\n }\n\n /** Map width in pixels. */\n get widthPx(): number {\n return this.data.width * this.data.tileWidth;\n }\n\n /** Map height in pixels. */\n get heightPx(): number {\n return this.data.height * this.data.tileHeight;\n }\n\n /** Tile width in pixels. */\n get tileWidth(): number {\n return this.data.tileWidth;\n }\n\n /** Tile height in pixels. */\n get tileHeight(): number {\n return this.data.tileHeight;\n }\n\n /**\n * Returns the tile GID at a world position, accounting for entity Transform offset.\n * Returns null if the position is outside the map or the tile is empty.\n */\n getTileAt(\n worldX: number,\n worldY: number,\n layerName?: string,\n ): number | null {\n const transform = this.entity.tryGet(Transform);\n const offsetX = transform ? transform.position.x : 0;\n const offsetY = transform ? transform.position.y : 0;\n const localX = worldX - offsetX;\n const localY = worldY - offsetY;\n\n const col = Math.floor(localX / this.data.tileWidth);\n const row = Math.floor(localY / this.data.tileHeight);\n\n if (col < 0 || col >= this.data.width) return null;\n if (row < 0 || row >= this.data.height) return null;\n\n const layers = layerName\n ? this.data.tileLayers.filter((l) => l.name === layerName)\n : this.data.tileLayers;\n\n // Return first non-zero GID found (from last layer to first for top-most)\n for (let i = layers.length - 1; i >= 0; i--) {\n const layer = layers[i]!;\n const gid = layer.data[row * layer.width + col];\n if (gid !== undefined && gid !== 0) return gid;\n }\n\n return null;\n }\n\n /** Extract physics-agnostic collision shapes from object layers. */\n getCollisionShapes(objectLayerName?: string): TilemapColliderConfig[] {\n return extractCollisionShapes(this.data, objectLayerName);\n }\n\n /** Extract objects from object layers grouped by class/name. */\n getObjects(objectLayerName?: string): Record<string, MapObject[]> {\n const filtered = objectLayerName\n ? this.data.objectLayers.filter((l) => l.name === objectLayerName)\n : this.data.objectLayers;\n\n const result: Record<string, MapObject[]> = {};\n\n for (const layer of filtered) {\n for (const obj of layer.objects) {\n const key = obj.class ?? obj.name;\n if (!result[key]) {\n result[key] = [];\n }\n result[key].push(obj);\n }\n }\n\n return result;\n }\n}\n","import { CompositeTilemap } from \"@pixi/tilemap\";\nimport { Assets, Texture, Rectangle } from \"pixi.js\";\nimport type {\n TiledMapData,\n TileLayer,\n TilesetRef,\n ObjectGroup,\n TileObject,\n} from \"./types.js\";\nimport type {\n TilemapData,\n TileLayerData,\n ObjectLayerData,\n MapObject,\n} from \"../types.js\";\n\n// ─── Generic adapter ────────────────────────────────────────────────\n\n/**\n * Convert Tiled JSON data to the generic TilemapData format.\n */\nexport function toTilemapData(map: TiledMapData): TilemapData {\n const tileLayers: TileLayerData[] = [];\n const objectLayers: ObjectLayerData[] = [];\n\n for (const layer of map.layers) {\n if (layer.type === \"tilelayer\") {\n tileLayers.push({\n name: layer.name,\n data: layer.data,\n width: layer.width,\n height: layer.height,\n visible: layer.visible,\n });\n } else if (layer.type === \"objectgroup\") {\n objectLayers.push({\n name: layer.name,\n objects: layer.objects.map(tiledObjectToMapObject),\n visible: layer.visible,\n });\n }\n }\n\n return {\n width: map.width,\n height: map.height,\n tileWidth: map.tilewidth,\n tileHeight: map.tileheight,\n tileLayers,\n objectLayers,\n };\n}\n\nfunction tiledObjectToMapObject(obj: TileObject): MapObject {\n const result: MapObject = {\n id: obj.id,\n name: obj.name,\n x: obj.x,\n y: obj.y,\n width: obj.width,\n height: obj.height,\n rotation: obj.rotation,\n visible: obj.visible,\n };\n\n const cls = obj.class ?? obj.type;\n if (cls) result.class = cls;\n if (obj.point === true) result.point = true;\n if (obj.polygon) result.polygon = obj.polygon;\n if (obj.properties) {\n result.properties = obj.properties.map((p) => ({\n name: p.name,\n type: p.type,\n value: p.value,\n }));\n }\n\n return result;\n}\n\n// ─── Tiled-specific rendering ───────────────────────────────────────\n\n/**\n * Resolve the tileset that owns a given global tile ID.\n * Tilesets are sorted by firstgid; we find the last tileset whose firstgid <= gid.\n */\nfunction findTileset(tilesets: TilesetRef[], gid: number): TilesetRef | null {\n let result: TilesetRef | null = null;\n for (const ts of tilesets) {\n if (ts.firstgid <= gid) {\n if (!result || ts.firstgid > result.firstgid) {\n result = ts;\n }\n }\n }\n return result;\n}\n\n/**\n * Resolve the texture for a tile given its GID and owning tileset.\n */\nfunction resolveTileTexture(\n gid: number,\n tileset: TilesetRef,\n): Texture | null {\n const data = tileset.data;\n if (!data) return null;\n const localId = gid - tileset.firstgid;\n\n if (data.tiles?.length) {\n // Collection-of-images tileset: look up texture by filename from cache\n const tileData = data.tiles[localId];\n if (!tileData?.image) return null;\n const filenameMatch = tileData.image.match(/[^/]*$/);\n const filename = filenameMatch?.[0];\n if (!filename) return null;\n const tex = Assets.get<Texture>(filename);\n return tex ?? null;\n }\n\n if (data.image) {\n // Single-image tileset: sub-textures were created by the loader\n const cacheKey = `${data.name}:${localId}`;\n const tex = Assets.get<Texture>(cacheKey);\n if (tex) return tex;\n\n // Fallback: create sub-texture on the fly from the base image\n const filenameMatch = data.image.match(/[^/]*$/);\n const filename = filenameMatch?.[0];\n if (!filename) return null;\n const baseTex = Assets.get<Texture>(filename);\n if (!baseTex) return null;\n\n const cols = data.columns;\n const tw = data.tilewidth;\n const th = data.tileheight;\n const margin = data.margin ?? 0;\n const spacing = data.spacing ?? 0;\n const col = localId % cols;\n const row = Math.floor(localId / cols);\n const x = margin + col * (tw + spacing);\n const y = margin + row * (th + spacing);\n\n return new Texture({\n source: baseTex.source,\n frame: new Rectangle(x, y, tw, th),\n });\n }\n\n return null;\n}\n\n/**\n * Build CompositeTilemap display objects from a parsed Tiled map.\n *\n * @param map - Parsed TiledMapData (with resolved tilesets).\n * @param layerNames - Optional filter: only process these tile layer names.\n * @returns Array of CompositeTilemap, one per tile layer.\n */\nexport function createTilemapLayers(\n map: TiledMapData,\n layerNames?: string[],\n): CompositeTilemap[] {\n const tileLayers = map.layers.filter(\n (l): l is TileLayer => l.type === \"tilelayer\",\n );\n\n const filtered = layerNames\n ? tileLayers.filter((l) => layerNames.includes(l.name))\n : tileLayers;\n\n return filtered.map((layer) => {\n const tilemap = new CompositeTilemap();\n const { data, width } = layer;\n\n for (let index = 0; index < data.length; index++) {\n const gid = data[index]!;\n if (gid === 0) continue;\n\n const tileset = findTileset(map.tilesets, gid);\n if (!tileset) {\n throw new Error(`No tileset found for tile GID ${gid}`);\n }\n\n const texture = resolveTileTexture(gid, tileset);\n if (!texture) {\n throw new Error(\n `Could not resolve texture for tile GID ${gid} in tileset \"${tileset.data?.name}\"`,\n );\n }\n\n const x = index % width;\n const y = Math.floor(index / width);\n tilemap.tile(texture, x * map.tilewidth, y * map.tileheight);\n }\n\n return tilemap;\n });\n}\n\n/**\n * Extract objects from Tiled object layers, grouped by class/type/name.\n *\n * @param map - Parsed TiledMapData.\n * @param objectLayerName - Optional: only extract from this layer.\n * @returns Record mapping class/type/name to arrays of TileObject.\n */\nexport function extractObjects(\n map: TiledMapData,\n objectLayerName?: string,\n): Record<string, TileObject[]> {\n const objectLayers = map.layers.filter(\n (l): l is ObjectGroup => l.type === \"objectgroup\",\n );\n\n const filtered = objectLayerName\n ? objectLayers.filter((l) => l.name === objectLayerName)\n : objectLayers;\n\n const result: Record<string, TileObject[]> = {};\n\n for (const layer of filtered) {\n for (const obj of layer.objects) {\n const key = obj.class ?? obj.type ?? obj.name;\n if (!result[key]) {\n result[key] = [];\n }\n result[key].push(obj);\n }\n }\n\n return result;\n}\n","import type {\n TilemapData,\n MapObject,\n TilemapColliderConfig,\n RectColliderConfig,\n PolygonColliderConfig,\n} from \"./types.js\";\n\n/**\n * Extract physics-agnostic collision shapes from object layers.\n *\n * - Rectangle objects -> RectColliderConfig\n * - Polygon objects -> PolygonColliderConfig\n * - Point objects -> skipped (not collision shapes)\n *\n * @param map - Generic TilemapData.\n * @param objectLayerName - Optional: only extract from this layer.\n */\nexport function extractCollisionShapes(\n map: TilemapData,\n objectLayerName?: string,\n): TilemapColliderConfig[] {\n const filtered = objectLayerName\n ? map.objectLayers.filter((l) => l.name === objectLayerName)\n : map.objectLayers;\n\n const shapes: TilemapColliderConfig[] = [];\n\n for (const layer of filtered) {\n for (const obj of layer.objects) {\n const shape = objectToColliderConfig(obj);\n if (shape) shapes.push(shape);\n }\n }\n\n return shapes;\n}\n\n/**\n * Convert a single MapObject to a ColliderConfig.\n * Returns null for point objects (not collision shapes).\n */\nfunction objectToColliderConfig(obj: MapObject): TilemapColliderConfig | null {\n // Skip point objects\n if (obj.point) return null;\n\n if (obj.polygon) {\n const config: PolygonColliderConfig = {\n type: \"polygon\",\n x: obj.x,\n y: obj.y,\n vertices: obj.polygon.map((v) => ({ x: v.x, y: v.y })),\n };\n return config;\n }\n\n // Rectangle object\n const config: RectColliderConfig = {\n type: \"rect\",\n x: obj.x,\n y: obj.y,\n width: obj.width,\n height: obj.height,\n };\n return config;\n}\n","import { AssetHandle } from \"@yagejs/core\";\nimport type { TiledMapData } from \"./tiled/types.js\";\n\n/** Create a typed asset handle for a Tiled map JSON. */\nexport function tiledMap(path: string): AssetHandle<TiledMapData> {\n return new AssetHandle(\"tiledMap\", path);\n}\n","import type { ColliderConfig as PhysicsColliderConfig } from \"@yagejs/physics\";\nimport type { TilemapColliderConfig } from \"./types.js\";\n\n/**\n * Convert tilemap TilemapColliderConfig[] (top-left origin rects/polygons) into\n * physics-package ColliderConfig[] (center-origin shape + offset).\n */\nexport function toPhysicsColliders(\n shapes: TilemapColliderConfig[],\n): PhysicsColliderConfig[] {\n return shapes.map(toPhysicsCollider);\n}\n\nfunction toPhysicsCollider(config: TilemapColliderConfig): PhysicsColliderConfig {\n switch (config.type) {\n case \"polygon\":\n return {\n shape: {\n type: \"polygon\",\n vertices: config.vertices,\n },\n offset: { x: config.x, y: config.y },\n };\n case \"rect\":\n return {\n shape: { type: \"box\", width: config.width, height: config.height },\n offset: {\n x: config.x + config.width / 2,\n y: config.y + config.height / 2,\n },\n };\n }\n}\n","import type { HasProperties, MapObject } from \"./types.js\";\n\n/**\n * Get a single property value by name.\n * Returns `undefined` if the property is not found.\n */\nexport function getProperty<T = unknown>(\n obj: HasProperties,\n name: string,\n): T | undefined {\n const prop = obj.properties?.find((p) => p.name === name);\n return prop?.value as T | undefined;\n}\n\n/**\n * Get a pseudo-array of property values.\n *\n * Tiled doesn't support array properties natively, so a common convention\n * is to use indexed names like `spawns[0]`, `spawns[1]`, etc.\n * This function collects them into a proper array, preserving index order.\n */\nexport function getPropertyArray<T = unknown>(\n obj: HasProperties,\n name: string,\n): T[] {\n const pattern = new RegExp(`^${escapeRegex(name)}\\\\[(\\\\d+)\\\\]$`);\n const values: T[] = [];\n\n if (!obj.properties) return values;\n\n for (const prop of obj.properties) {\n const match = prop.name.match(pattern);\n if (match) {\n const index = Number.parseInt(match[1]!, 10);\n values[index] = prop.value as T;\n }\n }\n\n return values;\n}\n\n/**\n * Resolve a property of `type: \"object\"` (an ID reference) to the actual MapObject.\n * Returns `undefined` if the property doesn't exist or the referenced object isn't found.\n */\nexport function resolveObjectRef(\n obj: HasProperties,\n propName: string,\n allObjects: MapObject[],\n): MapObject | undefined {\n const id = getProperty<number>(obj, propName);\n if (id === undefined) return undefined;\n return allObjects.find((o) => o.id === id);\n}\n\n/**\n * Resolve a pseudo-array of object ID references to actual MapObjects.\n * Uses the `name[0]`, `name[1]` convention.\n */\nexport function resolveObjectRefArray(\n obj: HasProperties,\n propName: string,\n allObjects: MapObject[],\n): MapObject[] {\n const ids = getPropertyArray<number>(obj, propName);\n return ids\n .map((id) => allObjects.find((o) => o.id === id))\n .filter((o): o is MapObject => o !== undefined);\n}\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n"],"mappings":"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","names":["import_core","import_pixi","import_core","import_pixi","import_pixi","config","tiledMap","path","import_core","path"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/TilemapPlugin.ts","../src/tiled/tiledMapLoader.ts","../src/TilemapRenderSystem.ts","../src/TilemapComponent.ts","../src/tiled/parseTiledMap.ts","../src/colliders.ts","../src/keys.ts","../src/properties.ts","../src/assets.ts","../src/toPhysicsColliders.ts"],"sourcesContent":["// Plugin\nexport { TilemapPlugin } from \"./TilemapPlugin.js\";\n\n// Component\nexport { TilemapComponent } from \"./TilemapComponent.js\";\nexport type {\n TilemapComponentOptions,\n TilemapComponentData,\n} from \"./TilemapComponent.js\";\n\n// System\nexport { TilemapRenderSystem } from \"./TilemapRenderSystem.js\";\n\n// Asset handle factory\nexport { tiledMap } from \"./assets.js\";\n\n// Stable identity helpers\nexport { tiledObjectKey } from \"./keys.js\";\n\n// Collision extraction\nexport { extractCollisionShapes } from \"./colliders.js\";\nexport { toPhysicsColliders } from \"./toPhysicsColliders.js\";\n\n// Property utilities\nexport {\n getProperty,\n getPropertyArray,\n resolveObjectRef,\n resolveObjectRefArray,\n} from \"./properties.js\";\n\n// Generic types\nexport type {\n TilemapData,\n TileLayerData,\n ObjectLayerData,\n MapObject,\n MapObjectProperty,\n HasProperties,\n TilemapColliderConfig,\n RectColliderConfig,\n PolygonColliderConfig,\n} from \"./types.js\";\n\n// Tiled-specific (re-exported for backward compatibility)\nexport { tiledMapAssetExtension } from \"./tiled/tiledMapLoader.js\";\nexport {\n createTilemapLayers,\n extractObjects,\n toTilemapData,\n} from \"./tiled/parseTiledMap.js\";\nexport type {\n TiledMapData,\n TileLayer,\n ObjectGroup,\n TileObject,\n RectangleObject,\n PolygonObject,\n PointObject,\n TileObjectProperty,\n TilesetRef,\n TilesetData,\n TileData,\n} from \"./tiled/types.js\";\n","import { AssetManagerKey } from \"@yagejs/core\";\nimport type { EngineContext, Plugin, SystemScheduler } from \"@yagejs/core\";\nimport { extensions, Assets } from \"pixi.js\";\nimport { tiledMapAssetExtension } from \"./tiled/tiledMapLoader.js\";\nimport { TilemapRenderSystem } from \"./TilemapRenderSystem.js\";\nimport type { TiledMapData } from \"./tiled/types.js\";\n\n/** Plugin that adds Tiled map loading and rendering to YAGE. */\nexport class TilemapPlugin implements Plugin {\n readonly name = \"tilemap\";\n readonly version = \"2.0.0\";\n readonly dependencies = [\"renderer\"] as const;\n\n install(context: EngineContext): void {\n // Register PixiJS loader extension for Tiled map JSON files\n extensions.add(tiledMapAssetExtension);\n\n // Register \"tiledMap\" loader with AssetManager\n const am = context.tryResolve(AssetManagerKey);\n am?.registerLoader(\"tiledMap\", {\n load: (path: string) => Assets.load<TiledMapData>(path),\n unload: (path: string) => {\n Assets.unload(path);\n },\n });\n }\n\n registerSystems(scheduler: SystemScheduler): void {\n scheduler.add(new TilemapRenderSystem());\n }\n}\n","import {\n ExtensionType,\n LoaderParserPriority,\n Assets,\n path,\n Texture,\n Rectangle,\n} from \"pixi.js\";\nimport type { LoaderParser, ResolvedAsset, Loader } from \"pixi.js\";\nimport type { TiledMapData, TilesetData, TilesetRef } from \"./types.js\";\n\n/**\n * PixiJS loader extension that detects Tiled map JSON files and resolves\n * their tileset references.\n *\n * Supports two tileset formats:\n * 1. **Collection-of-images** — tileset has `tiles[]` with image paths.\n * Assumes textures are already in the PixiJS cache (e.g. from a\n * pre-loaded spritesheet atlas).\n * 2. **Single-image tileset** — tileset has an `image` property pointing\n * to a spritesheet. The loader loads the image and creates sub-textures\n * for each tile based on grid layout.\n */\nconst tiledMapLoaderParser: LoaderParser<TiledMapData> = {\n id: \"tiledMapLoader\",\n\n extension: {\n type: ExtensionType.LoadParser,\n priority: LoaderParserPriority.High,\n },\n\n async testParse(\n asset: TiledMapData,\n resolvedAsset?: ResolvedAsset,\n ): Promise<boolean> {\n if (!resolvedAsset?.src) return false;\n if (path.extname(resolvedAsset.src).toLowerCase() !== \".json\") return false;\n const obj = asset as unknown as Record<string, unknown>;\n return !!(obj.tilesets && obj.layers);\n },\n\n async parse(\n asset: TiledMapData,\n resolvedAsset?: ResolvedAsset,\n loader?: Loader,\n ): Promise<TiledMapData> {\n const src = resolvedAsset?.src;\n if (!src || !loader) return asset;\n\n let basePath = path.dirname(src);\n if (basePath && !basePath.endsWith(\"/\")) {\n basePath += \"/\";\n }\n\n for (const tilesetRef of asset.tilesets as TilesetRef[]) {\n if (tilesetRef.source) {\n // External tileset JSON — load it\n const tilesetPath = basePath + tilesetRef.source;\n const tilesetData = (await loader.load<TilesetData>({\n src: tilesetPath,\n })) as TilesetData;\n tilesetRef.data = tilesetData;\n }\n\n const tileset = tilesetRef.data;\n if (!tileset) continue;\n\n // Single-image tileset: load the image and create sub-textures\n if (tileset.image && !tileset.tiles?.length) {\n const imagePath = basePath + tileset.image;\n const baseTexture = await Assets.load<Texture>(imagePath);\n const cols = tileset.columns;\n const tw = tileset.tilewidth;\n const th = tileset.tileheight;\n const margin = tileset.margin ?? 0;\n const spacing = tileset.spacing ?? 0;\n\n for (let id = 0; id < tileset.tilecount; id++) {\n const col = id % cols;\n const row = Math.floor(id / cols);\n const x = margin + col * (tw + spacing);\n const y = margin + row * (th + spacing);\n\n const frame = new Rectangle(x, y, tw, th);\n const subtex = new Texture({\n source: baseTexture.source,\n frame,\n });\n\n // Store subtexture in PixiJS cache with a key like \"tileset-name:id\"\n const cacheKey = `${tileset.name}:${id}`;\n Assets.cache.set(cacheKey, subtex);\n }\n }\n // Collection-of-images: textures are expected to already be\n // in the PixiJS cache (loaded via spritesheet atlas).\n }\n\n return asset;\n },\n\n unload() {},\n};\n\n/** PixiJS asset extension bundle for Tiled map JSON files. */\nexport const tiledMapAssetExtension = {\n extension: ExtensionType.Asset,\n loader: tiledMapLoaderParser,\n};\n","import { System, Phase, Transform, QueryCacheKey } from \"@yagejs/core\";\nimport type { EngineContext, QueryResult } from \"@yagejs/core\";\nimport { TilemapComponent } from \"./TilemapComponent.js\";\n\n/** Syncs Transform to TilemapComponent display containers. */\nexport class TilemapRenderSystem extends System {\n readonly phase = Phase.Render;\n readonly priority = -1; // Before DisplaySystem (0), so tilemaps render behind sprites\n\n private query!: QueryResult;\n\n onRegister(context: EngineContext): void {\n const queryCache = context.resolve(QueryCacheKey);\n this.query = queryCache.register([Transform, TilemapComponent]);\n }\n\n update(): void {\n for (const entity of this.query) {\n const transform = entity.get(Transform);\n const tilemap = entity.get(TilemapComponent);\n if (!tilemap.enabled) continue;\n\n tilemap.container.position.x = transform.worldPosition.x;\n tilemap.container.position.y = transform.worldPosition.y;\n tilemap.container.rotation = transform.worldRotation;\n tilemap.container.scale.x = transform.worldScale.x;\n tilemap.container.scale.y = transform.worldScale.y;\n }\n }\n}\n","import { Component, Transform, serializable } from \"@yagejs/core\";\nimport type { AssetHandle } from \"@yagejs/core\";\nimport { Assets, Container } from \"pixi.js\";\nimport { SceneRenderTreeKey } from \"@yagejs/renderer\";\nimport { createTilemapLayers, toTilemapData } from \"./tiled/parseTiledMap.js\";\nimport { extractCollisionShapes } from \"./colliders.js\";\nimport { tiledObjectKey } from \"./keys.js\";\nimport {\n getProperty,\n getPropertyArray,\n resolveObjectRef,\n resolveObjectRefArray,\n} from \"./properties.js\";\nimport type { TiledMapData } from \"./tiled/types.js\";\nimport type {\n TilemapData,\n MapObject,\n TilemapColliderConfig,\n} from \"./types.js\";\n\n/** Options for creating a TilemapComponent. */\nexport interface TilemapComponentOptions {\n /** Asset handle for the map. Preferred — captures both the parsed data and the asset path. */\n source?: AssetHandle<TiledMapData>;\n /** Parsed Tiled map data. Use only when you don't have an AssetHandle. Save/load and auto-keys require `mapKey` or `source`. */\n map?: TiledMapData;\n /** Asset path to the Tiled JSON. Resolved via `Assets.get`. Save/load uses this. */\n mapKey?: string;\n /** Which tile layers to render. Omit to render all. */\n layers?: string[];\n /** Render layer name. Default: \"default\". */\n layer?: string;\n /**\n * Override prefix used when auto-keying entities spawned from Tiled objects.\n * Defaults to `mapKey`. Set this when multiple instances of the same map need\n * distinct entity-key namespaces (e.g. instanced dungeons).\n */\n keyPrefix?: string;\n}\n\n/** Serializable snapshot of a TilemapComponent. */\nexport interface TilemapComponentData {\n mapKey: string;\n layers?: string[];\n layer: string;\n keyPrefix?: string;\n}\n\n/** Component that renders a Tiled map using @pixi/tilemap. */\n@serializable\nexport class TilemapComponent extends Component {\n readonly container: Container;\n readonly data: TilemapData;\n /** Asset path of this map, or `null` if constructed from a raw `TiledMapData` without one. */\n readonly mapKey: string | null;\n /** Prefix used to derive auto-keys for entities spawned from objects. */\n readonly keyPrefix: string | null;\n private readonly _tiledMap: TiledMapData;\n private readonly layerNames: string[] | undefined;\n private readonly renderLayerName: string;\n private readonly _explicitKeyPrefix: string | undefined;\n /** Lazy flat-list cache. The parsed map is treated as immutable post-construction; if that ever changes, callers must invalidate. */\n private _allObjectsCache: MapObject[] | undefined;\n\n constructor(options: TilemapComponentOptions) {\n super();\n\n const sourceCount =\n (options.source ? 1 : 0) +\n (options.map ? 1 : 0) +\n (options.mapKey ? 1 : 0);\n if (sourceCount === 0) {\n throw new Error(\n \"TilemapComponent requires one of `source`, `map`, or `mapKey`.\",\n );\n }\n\n if (options.source) {\n this.mapKey = options.source.path;\n const data = Assets.get<TiledMapData>(options.source.path);\n if (!data) {\n throw new Error(\n `TilemapComponent: source \"${options.source.path}\" is not loaded. Add it to scene preload.`,\n );\n }\n this._tiledMap = data;\n } else if (options.mapKey) {\n this.mapKey = options.mapKey;\n const data = Assets.get<TiledMapData>(options.mapKey);\n if (!data) {\n throw new Error(\n `TilemapComponent: map \"${options.mapKey}\" is not loaded. Add it to scene preload.`,\n );\n }\n this._tiledMap = data;\n } else {\n this.mapKey = null;\n this._tiledMap = options.map!;\n }\n\n this.data = toTilemapData(this._tiledMap);\n this.layerNames = options.layers;\n this.renderLayerName = options.layer ?? \"default\";\n this._explicitKeyPrefix = options.keyPrefix;\n this.keyPrefix = options.keyPrefix ?? this.mapKey;\n this.container = new Container();\n }\n\n onAdd(): void {\n const tilemapLayers = createTilemapLayers(this._tiledMap, this.layerNames);\n for (const layer of tilemapLayers) {\n this.container.addChild(layer);\n }\n\n const renderLayer = this.use(SceneRenderTreeKey).get(this.renderLayerName);\n renderLayer.container.addChild(this.container);\n }\n\n onDestroy(): void {\n this.container.removeFromParent();\n this.container.destroy({ children: true });\n }\n\n serialize(): TilemapComponentData | null {\n if (!this.mapKey) {\n console.warn(\n `TilemapComponent on \"${this.entity?.name}\": created with a TiledMapData object. ` +\n `Use { source } or { mapKey } for save/load support.`,\n );\n return null;\n }\n return {\n mapKey: this.mapKey,\n layer: this.renderLayerName,\n ...(this.layerNames && { layers: this.layerNames }),\n ...(this._explicitKeyPrefix !== undefined && {\n keyPrefix: this._explicitKeyPrefix,\n }),\n };\n }\n\n static fromSnapshot(data: TilemapComponentData): TilemapComponent {\n return new TilemapComponent({\n mapKey: data.mapKey,\n layer: data.layer,\n ...(data.layers && { layers: data.layers }),\n ...(data.keyPrefix !== undefined && { keyPrefix: data.keyPrefix }),\n });\n }\n\n /** Map width in pixels. */\n get widthPx(): number {\n return this.data.width * this.data.tileWidth;\n }\n\n /** Map height in pixels. */\n get heightPx(): number {\n return this.data.height * this.data.tileHeight;\n }\n\n /** Tile width in pixels. */\n get tileWidth(): number {\n return this.data.tileWidth;\n }\n\n /** Tile height in pixels. */\n get tileHeight(): number {\n return this.data.tileHeight;\n }\n\n /**\n * Returns the tile GID at a world position, accounting for entity Transform offset.\n * Returns null if the position is outside the map or the tile is empty.\n */\n getTileAt(\n worldX: number,\n worldY: number,\n layerName?: string,\n ): number | null {\n const transform = this.entity.tryGet(Transform);\n const offsetX = transform ? transform.position.x : 0;\n const offsetY = transform ? transform.position.y : 0;\n const localX = worldX - offsetX;\n const localY = worldY - offsetY;\n\n const col = Math.floor(localX / this.data.tileWidth);\n const row = Math.floor(localY / this.data.tileHeight);\n\n if (col < 0 || col >= this.data.width) return null;\n if (row < 0 || row >= this.data.height) return null;\n\n const layers = layerName\n ? this.data.tileLayers.filter((l) => l.name === layerName)\n : this.data.tileLayers;\n\n // Return first non-zero GID found (from last layer to first for top-most)\n for (let i = layers.length - 1; i >= 0; i--) {\n const layer = layers[i]!;\n const gid = layer.data[row * layer.width + col];\n if (gid !== undefined && gid !== 0) return gid;\n }\n\n return null;\n }\n\n /** Extract physics-agnostic collision shapes from object layers. */\n getCollisionShapes(objectLayerName?: string): TilemapColliderConfig[] {\n return extractCollisionShapes(this.data, objectLayerName);\n }\n\n /** Objects from object layers grouped by `class ?? name`. Use a layer name to scope. */\n getObjects(objectLayerName?: string): Record<string, MapObject[]> {\n const filtered = objectLayerName\n ? this.data.objectLayers.filter((l) => l.name === objectLayerName)\n : this.data.objectLayers;\n\n const result: Record<string, MapObject[]> = {};\n\n for (const layer of filtered) {\n for (const obj of layer.objects) {\n const key = obj.class ?? obj.name;\n if (!result[key]) {\n result[key] = [];\n }\n result[key].push(obj);\n }\n }\n\n return result;\n }\n\n /** Flat list of every object across every object layer. Memoized — safe because parsed map data is immutable post-construction. */\n getAllObjects(): MapObject[] {\n if (this._allObjectsCache) return this._allObjectsCache;\n const result: MapObject[] = [];\n for (const layer of this.data.objectLayers) {\n for (const obj of layer.objects) result.push(obj);\n }\n this._allObjectsCache = result;\n return result;\n }\n\n /**\n * Iterate every object on the given layer (or every layer if omitted),\n * passing the auto-derived stable key alongside each object so callers can\n * spawn entities with `scene.spawn(Class, params, { key })`.\n *\n * Skips objects that don't have a key prefix (component constructed from raw\n * `map:` without `mapKey` or `keyPrefix`) — those callers should iterate\n * `getObjects` directly.\n */\n forEachObject(\n layerName: string | undefined,\n fn: (obj: MapObject, key: string) => void,\n ): void {\n if (this.keyPrefix === null) {\n throw new Error(\n \"TilemapComponent.forEachObject: cannot derive auto-keys without a `mapKey`, `source`, or explicit `keyPrefix`.\",\n );\n }\n const layers = layerName\n ? this.data.objectLayers.filter((l) => l.name === layerName)\n : this.data.objectLayers;\n for (const layer of layers) {\n for (const obj of layer.objects) {\n fn(obj, tiledObjectKey(this.keyPrefix, obj.id));\n }\n }\n }\n\n /** Auto-derived stable key for an object: `<keyPrefix>#object:<id>`. */\n objectKey(obj: MapObject): string {\n if (this.keyPrefix === null) {\n throw new Error(\n \"TilemapComponent.objectKey: cannot derive a key without a `mapKey`, `source`, or explicit `keyPrefix`.\",\n );\n }\n return tiledObjectKey(this.keyPrefix, obj.id);\n }\n\n /** Find an object by its Tiled `id`. Searches every object layer. */\n findObject(id: number): MapObject | undefined {\n for (const layer of this.data.objectLayers) {\n for (const obj of layer.objects) {\n if (obj.id === id) return obj;\n }\n }\n return undefined;\n }\n\n /** Find the first object with a matching `name`. Searches every object layer. */\n findObjectByName(name: string): MapObject | undefined {\n for (const layer of this.data.objectLayers) {\n for (const obj of layer.objects) {\n if (obj.name === name) return obj;\n }\n }\n return undefined;\n }\n\n /** Read a typed custom property off any tilemap object. */\n getProperty<T = unknown>(obj: MapObject, name: string): T | undefined {\n return getProperty<T>(obj, name);\n }\n\n /** Read an indexed property bag (`name[0]`, `name[1]`, ...) as an array. */\n getPropertyArray<T = unknown>(obj: MapObject, name: string): T[] {\n return getPropertyArray<T>(obj, name);\n }\n\n /**\n * Resolve a Tiled object-reference property to the actual object.\n * Auto-collects across every layer so callers don't have to.\n */\n resolveRef(obj: MapObject, propName: string): MapObject | undefined {\n return resolveObjectRef(obj, propName, this.getAllObjects());\n }\n\n /** Same as `resolveRef`, but for indexed object-reference arrays. */\n resolveRefArray(obj: MapObject, propName: string): MapObject[] {\n return resolveObjectRefArray(obj, propName, this.getAllObjects());\n }\n}\n","import { CompositeTilemap } from \"@pixi/tilemap\";\nimport { Assets, Texture, Rectangle } from \"pixi.js\";\nimport type {\n TiledMapData,\n TileLayer,\n TilesetRef,\n ObjectGroup,\n TileObject,\n} from \"./types.js\";\nimport type {\n TilemapData,\n TileLayerData,\n ObjectLayerData,\n MapObject,\n} from \"../types.js\";\n\n// ─── Generic adapter ────────────────────────────────────────────────\n\n/**\n * Convert Tiled JSON data to the generic TilemapData format.\n */\nexport function toTilemapData(map: TiledMapData): TilemapData {\n const tileLayers: TileLayerData[] = [];\n const objectLayers: ObjectLayerData[] = [];\n\n for (const layer of map.layers) {\n if (layer.type === \"tilelayer\") {\n tileLayers.push({\n name: layer.name,\n data: layer.data,\n width: layer.width,\n height: layer.height,\n visible: layer.visible,\n });\n } else if (layer.type === \"objectgroup\") {\n objectLayers.push({\n name: layer.name,\n objects: layer.objects.map(tiledObjectToMapObject),\n visible: layer.visible,\n });\n }\n }\n\n return {\n width: map.width,\n height: map.height,\n tileWidth: map.tilewidth,\n tileHeight: map.tileheight,\n tileLayers,\n objectLayers,\n };\n}\n\nfunction tiledObjectToMapObject(obj: TileObject): MapObject {\n const result: MapObject = {\n id: obj.id,\n name: obj.name,\n x: obj.x,\n y: obj.y,\n width: obj.width,\n height: obj.height,\n rotation: obj.rotation,\n visible: obj.visible,\n };\n\n const cls = obj.class ?? obj.type;\n if (cls) result.class = cls;\n if (obj.point === true) result.point = true;\n if (obj.polygon) result.polygon = obj.polygon;\n if (obj.properties) {\n result.properties = obj.properties.map((p) => ({\n name: p.name,\n type: p.type,\n value: p.value,\n }));\n }\n\n return result;\n}\n\n// ─── Tiled-specific rendering ───────────────────────────────────────\n\n/**\n * Resolve the tileset that owns a given global tile ID.\n * Tilesets are sorted by firstgid; we find the last tileset whose firstgid <= gid.\n */\nfunction findTileset(tilesets: TilesetRef[], gid: number): TilesetRef | null {\n let result: TilesetRef | null = null;\n for (const ts of tilesets) {\n if (ts.firstgid <= gid) {\n if (!result || ts.firstgid > result.firstgid) {\n result = ts;\n }\n }\n }\n return result;\n}\n\n/**\n * Resolve the texture for a tile given its GID and owning tileset.\n */\nfunction resolveTileTexture(\n gid: number,\n tileset: TilesetRef,\n): Texture | null {\n const data = tileset.data;\n if (!data) return null;\n const localId = gid - tileset.firstgid;\n\n if (data.tiles?.length) {\n // Collection-of-images tileset: look up texture by filename from cache\n const tileData = data.tiles[localId];\n if (!tileData?.image) return null;\n const filenameMatch = tileData.image.match(/[^/]*$/);\n const filename = filenameMatch?.[0];\n if (!filename) return null;\n const tex = Assets.get<Texture>(filename);\n return tex ?? null;\n }\n\n if (data.image) {\n // Single-image tileset: sub-textures were created by the loader\n const cacheKey = `${data.name}:${localId}`;\n const tex = Assets.get<Texture>(cacheKey);\n if (tex) return tex;\n\n // Fallback: create sub-texture on the fly from the base image\n const filenameMatch = data.image.match(/[^/]*$/);\n const filename = filenameMatch?.[0];\n if (!filename) return null;\n const baseTex = Assets.get<Texture>(filename);\n if (!baseTex) return null;\n\n const cols = data.columns;\n const tw = data.tilewidth;\n const th = data.tileheight;\n const margin = data.margin ?? 0;\n const spacing = data.spacing ?? 0;\n const col = localId % cols;\n const row = Math.floor(localId / cols);\n const x = margin + col * (tw + spacing);\n const y = margin + row * (th + spacing);\n\n return new Texture({\n source: baseTex.source,\n frame: new Rectangle(x, y, tw, th),\n });\n }\n\n return null;\n}\n\n/**\n * Build CompositeTilemap display objects from a parsed Tiled map.\n *\n * @param map - Parsed TiledMapData (with resolved tilesets).\n * @param layerNames - Optional filter: only process these tile layer names.\n * @returns Array of CompositeTilemap, one per tile layer.\n */\nexport function createTilemapLayers(\n map: TiledMapData,\n layerNames?: string[],\n): CompositeTilemap[] {\n const tileLayers = map.layers.filter(\n (l): l is TileLayer => l.type === \"tilelayer\",\n );\n\n const filtered = layerNames\n ? tileLayers.filter((l) => layerNames.includes(l.name))\n : tileLayers;\n\n return filtered.map((layer) => {\n const tilemap = new CompositeTilemap();\n const { data, width } = layer;\n\n for (let index = 0; index < data.length; index++) {\n const gid = data[index]!;\n if (gid === 0) continue;\n\n const tileset = findTileset(map.tilesets, gid);\n if (!tileset) {\n throw new Error(`No tileset found for tile GID ${gid}`);\n }\n\n const texture = resolveTileTexture(gid, tileset);\n if (!texture) {\n throw new Error(\n `Could not resolve texture for tile GID ${gid} in tileset \"${tileset.data?.name}\"`,\n );\n }\n\n const x = index % width;\n const y = Math.floor(index / width);\n tilemap.tile(texture, x * map.tilewidth, y * map.tileheight);\n }\n\n return tilemap;\n });\n}\n\n/**\n * Extract objects from Tiled object layers, grouped by class/type/name.\n *\n * @param map - Parsed TiledMapData.\n * @param objectLayerName - Optional: only extract from this layer.\n * @returns Record mapping class/type/name to arrays of TileObject.\n */\nexport function extractObjects(\n map: TiledMapData,\n objectLayerName?: string,\n): Record<string, TileObject[]> {\n const objectLayers = map.layers.filter(\n (l): l is ObjectGroup => l.type === \"objectgroup\",\n );\n\n const filtered = objectLayerName\n ? objectLayers.filter((l) => l.name === objectLayerName)\n : objectLayers;\n\n const result: Record<string, TileObject[]> = {};\n\n for (const layer of filtered) {\n for (const obj of layer.objects) {\n const key = obj.class ?? obj.type ?? obj.name;\n if (!result[key]) {\n result[key] = [];\n }\n result[key].push(obj);\n }\n }\n\n return result;\n}\n","import type {\n TilemapData,\n MapObject,\n TilemapColliderConfig,\n RectColliderConfig,\n PolygonColliderConfig,\n} from \"./types.js\";\n\n/**\n * Extract physics-agnostic collision shapes from object layers.\n *\n * - Rectangle objects -> RectColliderConfig\n * - Polygon objects -> PolygonColliderConfig\n * - Point objects -> skipped (not collision shapes)\n *\n * @param map - Generic TilemapData.\n * @param objectLayerName - Optional: only extract from this layer.\n */\nexport function extractCollisionShapes(\n map: TilemapData,\n objectLayerName?: string,\n): TilemapColliderConfig[] {\n const filtered = objectLayerName\n ? map.objectLayers.filter((l) => l.name === objectLayerName)\n : map.objectLayers;\n\n const shapes: TilemapColliderConfig[] = [];\n\n for (const layer of filtered) {\n for (const obj of layer.objects) {\n const shape = objectToColliderConfig(obj);\n if (shape) shapes.push(shape);\n }\n }\n\n return shapes;\n}\n\n/**\n * Convert a single MapObject to a ColliderConfig.\n * Returns null for point objects (not collision shapes).\n */\nfunction objectToColliderConfig(obj: MapObject): TilemapColliderConfig | null {\n // Skip point objects\n if (obj.point) return null;\n\n if (obj.polygon) {\n const config: PolygonColliderConfig = {\n type: \"polygon\",\n x: obj.x,\n y: obj.y,\n vertices: obj.polygon.map((v) => ({ x: v.x, y: v.y })),\n };\n return config;\n }\n\n // Rectangle object\n const config: RectColliderConfig = {\n type: \"rect\",\n x: obj.x,\n y: obj.y,\n width: obj.width,\n height: obj.height,\n };\n return config;\n}\n","/**\n * Build the stable identity key for an entity sourced from a Tiled object.\n *\n * Format: `<prefix>#object:<id>`. The prefix is normally the map's asset path\n * (e.g. `/assets/dungeon/dungeon-map.json#object:42`); pass an explicit prefix\n * when distinguishing between multiple instances of the same map.\n *\n * Use this to thread Tiled object identity into `scene.spawn(Class, params, { key })`\n * so persistent stores (`defineSet<string>`, `defineMap<string, T>`) can key off\n * authored level content without each game inventing its own naming scheme.\n */\nexport function tiledObjectKey(prefix: string, objectId: number): string {\n return `${prefix}#object:${objectId}`;\n}\n","import type { HasProperties, MapObject } from \"./types.js\";\n\n/**\n * Get a single property value by name.\n * Returns `undefined` if the property is not found.\n */\nexport function getProperty<T = unknown>(\n obj: HasProperties,\n name: string,\n): T | undefined {\n const prop = obj.properties?.find((p) => p.name === name);\n return prop?.value as T | undefined;\n}\n\n/**\n * Get a pseudo-array of property values.\n *\n * Tiled doesn't support array properties natively, so a common convention\n * is to use indexed names like `spawns[0]`, `spawns[1]`, etc.\n * This function collects them into a proper array, preserving index order.\n */\nexport function getPropertyArray<T = unknown>(\n obj: HasProperties,\n name: string,\n): T[] {\n const pattern = new RegExp(`^${escapeRegex(name)}\\\\[(\\\\d+)\\\\]$`);\n const values: T[] = [];\n\n if (!obj.properties) return values;\n\n for (const prop of obj.properties) {\n const match = prop.name.match(pattern);\n if (match) {\n const index = Number.parseInt(match[1]!, 10);\n values[index] = prop.value as T;\n }\n }\n\n return values;\n}\n\n/**\n * Resolve a property of `type: \"object\"` (an ID reference) to the actual MapObject.\n * Returns `undefined` if the property doesn't exist or the referenced object isn't found.\n */\nexport function resolveObjectRef(\n obj: HasProperties,\n propName: string,\n allObjects: MapObject[],\n): MapObject | undefined {\n const id = getProperty<number>(obj, propName);\n if (id === undefined) return undefined;\n return allObjects.find((o) => o.id === id);\n}\n\n/**\n * Resolve a pseudo-array of object ID references to actual MapObjects.\n * Uses the `name[0]`, `name[1]` convention.\n */\nexport function resolveObjectRefArray(\n obj: HasProperties,\n propName: string,\n allObjects: MapObject[],\n): MapObject[] {\n const ids = getPropertyArray<number>(obj, propName);\n return ids\n .map((id) => allObjects.find((o) => o.id === id))\n .filter((o): o is MapObject => o !== undefined);\n}\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n","import { AssetHandle } from \"@yagejs/core\";\nimport type { TiledMapData } from \"./tiled/types.js\";\n\n/** Create a typed asset handle for a Tiled map JSON. */\nexport function tiledMap(path: string): AssetHandle<TiledMapData> {\n return new AssetHandle(\"tiledMap\", path);\n}\n","import type { ColliderConfig as PhysicsColliderConfig } from \"@yagejs/physics\";\nimport type { TilemapColliderConfig } from \"./types.js\";\n\n/**\n * Convert tilemap TilemapColliderConfig[] (top-left origin rects/polygons) into\n * physics-package ColliderConfig[] (center-origin shape + offset).\n */\nexport function toPhysicsColliders(\n shapes: TilemapColliderConfig[],\n): PhysicsColliderConfig[] {\n return shapes.map(toPhysicsCollider);\n}\n\nfunction toPhysicsCollider(config: TilemapColliderConfig): PhysicsColliderConfig {\n switch (config.type) {\n case \"polygon\":\n return {\n shape: {\n type: \"polygon\",\n vertices: config.vertices,\n },\n offset: { x: config.x, y: config.y },\n };\n case \"rect\":\n return {\n shape: { type: \"box\", width: config.width, height: config.height },\n offset: {\n x: config.x + config.width / 2,\n y: config.y + config.height / 2,\n },\n };\n }\n}\n"],"mappings":"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","names":["import_core","import_pixi","import_core","import_pixi","import_pixi","config","path","import_core","path"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Plugin, EngineContext, SystemScheduler, Component, System, Phase
|
|
1
|
+
import { Plugin, EngineContext, SystemScheduler, Component, AssetHandle, System, Phase } from '@yagejs/core';
|
|
2
2
|
import { Container, ExtensionType, LoaderParser } from 'pixi.js';
|
|
3
3
|
import { ColliderConfig } from '@yagejs/physics';
|
|
4
4
|
import { CompositeTilemap } from '@pixi/tilemap';
|
|
@@ -202,29 +202,44 @@ type TilemapColliderConfig = RectColliderConfig | PolygonColliderConfig;
|
|
|
202
202
|
|
|
203
203
|
/** Options for creating a TilemapComponent. */
|
|
204
204
|
interface TilemapComponentOptions {
|
|
205
|
-
/**
|
|
205
|
+
/** Asset handle for the map. Preferred — captures both the parsed data and the asset path. */
|
|
206
|
+
source?: AssetHandle<TiledMapData>;
|
|
207
|
+
/** Parsed Tiled map data. Use only when you don't have an AssetHandle. Save/load and auto-keys require `mapKey` or `source`. */
|
|
206
208
|
map?: TiledMapData;
|
|
207
|
-
/** Asset path to the Tiled JSON
|
|
209
|
+
/** Asset path to the Tiled JSON. Resolved via `Assets.get`. Save/load uses this. */
|
|
208
210
|
mapKey?: string;
|
|
209
211
|
/** Which tile layers to render. Omit to render all. */
|
|
210
212
|
layers?: string[];
|
|
211
213
|
/** Render layer name. Default: "default". */
|
|
212
214
|
layer?: string;
|
|
215
|
+
/**
|
|
216
|
+
* Override prefix used when auto-keying entities spawned from Tiled objects.
|
|
217
|
+
* Defaults to `mapKey`. Set this when multiple instances of the same map need
|
|
218
|
+
* distinct entity-key namespaces (e.g. instanced dungeons).
|
|
219
|
+
*/
|
|
220
|
+
keyPrefix?: string;
|
|
213
221
|
}
|
|
214
222
|
/** Serializable snapshot of a TilemapComponent. */
|
|
215
223
|
interface TilemapComponentData {
|
|
216
224
|
mapKey: string;
|
|
217
225
|
layers?: string[];
|
|
218
226
|
layer: string;
|
|
227
|
+
keyPrefix?: string;
|
|
219
228
|
}
|
|
220
229
|
/** Component that renders a Tiled map using @pixi/tilemap. */
|
|
221
230
|
declare class TilemapComponent extends Component {
|
|
222
231
|
readonly container: Container;
|
|
223
232
|
readonly data: TilemapData;
|
|
233
|
+
/** Asset path of this map, or `null` if constructed from a raw `TiledMapData` without one. */
|
|
234
|
+
readonly mapKey: string | null;
|
|
235
|
+
/** Prefix used to derive auto-keys for entities spawned from objects. */
|
|
236
|
+
readonly keyPrefix: string | null;
|
|
224
237
|
private readonly _tiledMap;
|
|
225
|
-
private readonly _mapKey;
|
|
226
238
|
private readonly layerNames;
|
|
227
239
|
private readonly renderLayerName;
|
|
240
|
+
private readonly _explicitKeyPrefix;
|
|
241
|
+
/** Lazy flat-list cache. The parsed map is treated as immutable post-construction; if that ever changes, callers must invalidate. */
|
|
242
|
+
private _allObjectsCache;
|
|
228
243
|
constructor(options: TilemapComponentOptions);
|
|
229
244
|
onAdd(): void;
|
|
230
245
|
onDestroy(): void;
|
|
@@ -245,8 +260,37 @@ declare class TilemapComponent extends Component {
|
|
|
245
260
|
getTileAt(worldX: number, worldY: number, layerName?: string): number | null;
|
|
246
261
|
/** Extract physics-agnostic collision shapes from object layers. */
|
|
247
262
|
getCollisionShapes(objectLayerName?: string): TilemapColliderConfig[];
|
|
248
|
-
/**
|
|
263
|
+
/** Objects from object layers grouped by `class ?? name`. Use a layer name to scope. */
|
|
249
264
|
getObjects(objectLayerName?: string): Record<string, MapObject[]>;
|
|
265
|
+
/** Flat list of every object across every object layer. Memoized — safe because parsed map data is immutable post-construction. */
|
|
266
|
+
getAllObjects(): MapObject[];
|
|
267
|
+
/**
|
|
268
|
+
* Iterate every object on the given layer (or every layer if omitted),
|
|
269
|
+
* passing the auto-derived stable key alongside each object so callers can
|
|
270
|
+
* spawn entities with `scene.spawn(Class, params, { key })`.
|
|
271
|
+
*
|
|
272
|
+
* Skips objects that don't have a key prefix (component constructed from raw
|
|
273
|
+
* `map:` without `mapKey` or `keyPrefix`) — those callers should iterate
|
|
274
|
+
* `getObjects` directly.
|
|
275
|
+
*/
|
|
276
|
+
forEachObject(layerName: string | undefined, fn: (obj: MapObject, key: string) => void): void;
|
|
277
|
+
/** Auto-derived stable key for an object: `<keyPrefix>#object:<id>`. */
|
|
278
|
+
objectKey(obj: MapObject): string;
|
|
279
|
+
/** Find an object by its Tiled `id`. Searches every object layer. */
|
|
280
|
+
findObject(id: number): MapObject | undefined;
|
|
281
|
+
/** Find the first object with a matching `name`. Searches every object layer. */
|
|
282
|
+
findObjectByName(name: string): MapObject | undefined;
|
|
283
|
+
/** Read a typed custom property off any tilemap object. */
|
|
284
|
+
getProperty<T = unknown>(obj: MapObject, name: string): T | undefined;
|
|
285
|
+
/** Read an indexed property bag (`name[0]`, `name[1]`, ...) as an array. */
|
|
286
|
+
getPropertyArray<T = unknown>(obj: MapObject, name: string): T[];
|
|
287
|
+
/**
|
|
288
|
+
* Resolve a Tiled object-reference property to the actual object.
|
|
289
|
+
* Auto-collects across every layer so callers don't have to.
|
|
290
|
+
*/
|
|
291
|
+
resolveRef(obj: MapObject, propName: string): MapObject | undefined;
|
|
292
|
+
/** Same as `resolveRef`, but for indexed object-reference arrays. */
|
|
293
|
+
resolveRefArray(obj: MapObject, propName: string): MapObject[];
|
|
250
294
|
}
|
|
251
295
|
|
|
252
296
|
/** Syncs Transform to TilemapComponent display containers. */
|
|
@@ -261,6 +305,19 @@ declare class TilemapRenderSystem extends System {
|
|
|
261
305
|
/** Create a typed asset handle for a Tiled map JSON. */
|
|
262
306
|
declare function tiledMap(path: string): AssetHandle<TiledMapData>;
|
|
263
307
|
|
|
308
|
+
/**
|
|
309
|
+
* Build the stable identity key for an entity sourced from a Tiled object.
|
|
310
|
+
*
|
|
311
|
+
* Format: `<prefix>#object:<id>`. The prefix is normally the map's asset path
|
|
312
|
+
* (e.g. `/assets/dungeon/dungeon-map.json#object:42`); pass an explicit prefix
|
|
313
|
+
* when distinguishing between multiple instances of the same map.
|
|
314
|
+
*
|
|
315
|
+
* Use this to thread Tiled object identity into `scene.spawn(Class, params, { key })`
|
|
316
|
+
* so persistent stores (`defineSet<string>`, `defineMap<string, T>`) can key off
|
|
317
|
+
* authored level content without each game inventing its own naming scheme.
|
|
318
|
+
*/
|
|
319
|
+
declare function tiledObjectKey(prefix: string, objectId: number): string;
|
|
320
|
+
|
|
264
321
|
/**
|
|
265
322
|
* Extract physics-agnostic collision shapes from object layers.
|
|
266
323
|
*
|
|
@@ -330,4 +387,4 @@ declare function createTilemapLayers(map: TiledMapData, layerNames?: string[]):
|
|
|
330
387
|
*/
|
|
331
388
|
declare function extractObjects(map: TiledMapData, objectLayerName?: string): Record<string, TileObject[]>;
|
|
332
389
|
|
|
333
|
-
export { type HasProperties, type MapObject, type MapObjectProperty, type ObjectGroup, type ObjectLayerData, type PointObject, type PolygonColliderConfig, type PolygonObject, type RectColliderConfig, type RectangleObject, type TileData, type TileLayer, type TileLayerData, type TileObject, type TileObjectProperty, type TiledMapData, type TilemapColliderConfig, TilemapComponent, type TilemapComponentData, type TilemapComponentOptions, type TilemapData, TilemapPlugin, TilemapRenderSystem, type TilesetData, type TilesetRef, createTilemapLayers, extractCollisionShapes, extractObjects, getProperty, getPropertyArray, resolveObjectRef, resolveObjectRefArray, tiledMap, tiledMapAssetExtension, toPhysicsColliders, toTilemapData };
|
|
390
|
+
export { type HasProperties, type MapObject, type MapObjectProperty, type ObjectGroup, type ObjectLayerData, type PointObject, type PolygonColliderConfig, type PolygonObject, type RectColliderConfig, type RectangleObject, type TileData, type TileLayer, type TileLayerData, type TileObject, type TileObjectProperty, type TiledMapData, type TilemapColliderConfig, TilemapComponent, type TilemapComponentData, type TilemapComponentOptions, type TilemapData, TilemapPlugin, TilemapRenderSystem, type TilesetData, type TilesetRef, createTilemapLayers, extractCollisionShapes, extractObjects, getProperty, getPropertyArray, resolveObjectRef, resolveObjectRefArray, tiledMap, tiledMapAssetExtension, tiledObjectKey, toPhysicsColliders, toTilemapData };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Plugin, EngineContext, SystemScheduler, Component, System, Phase
|
|
1
|
+
import { Plugin, EngineContext, SystemScheduler, Component, AssetHandle, System, Phase } from '@yagejs/core';
|
|
2
2
|
import { Container, ExtensionType, LoaderParser } from 'pixi.js';
|
|
3
3
|
import { ColliderConfig } from '@yagejs/physics';
|
|
4
4
|
import { CompositeTilemap } from '@pixi/tilemap';
|
|
@@ -202,29 +202,44 @@ type TilemapColliderConfig = RectColliderConfig | PolygonColliderConfig;
|
|
|
202
202
|
|
|
203
203
|
/** Options for creating a TilemapComponent. */
|
|
204
204
|
interface TilemapComponentOptions {
|
|
205
|
-
/**
|
|
205
|
+
/** Asset handle for the map. Preferred — captures both the parsed data and the asset path. */
|
|
206
|
+
source?: AssetHandle<TiledMapData>;
|
|
207
|
+
/** Parsed Tiled map data. Use only when you don't have an AssetHandle. Save/load and auto-keys require `mapKey` or `source`. */
|
|
206
208
|
map?: TiledMapData;
|
|
207
|
-
/** Asset path to the Tiled JSON
|
|
209
|
+
/** Asset path to the Tiled JSON. Resolved via `Assets.get`. Save/load uses this. */
|
|
208
210
|
mapKey?: string;
|
|
209
211
|
/** Which tile layers to render. Omit to render all. */
|
|
210
212
|
layers?: string[];
|
|
211
213
|
/** Render layer name. Default: "default". */
|
|
212
214
|
layer?: string;
|
|
215
|
+
/**
|
|
216
|
+
* Override prefix used when auto-keying entities spawned from Tiled objects.
|
|
217
|
+
* Defaults to `mapKey`. Set this when multiple instances of the same map need
|
|
218
|
+
* distinct entity-key namespaces (e.g. instanced dungeons).
|
|
219
|
+
*/
|
|
220
|
+
keyPrefix?: string;
|
|
213
221
|
}
|
|
214
222
|
/** Serializable snapshot of a TilemapComponent. */
|
|
215
223
|
interface TilemapComponentData {
|
|
216
224
|
mapKey: string;
|
|
217
225
|
layers?: string[];
|
|
218
226
|
layer: string;
|
|
227
|
+
keyPrefix?: string;
|
|
219
228
|
}
|
|
220
229
|
/** Component that renders a Tiled map using @pixi/tilemap. */
|
|
221
230
|
declare class TilemapComponent extends Component {
|
|
222
231
|
readonly container: Container;
|
|
223
232
|
readonly data: TilemapData;
|
|
233
|
+
/** Asset path of this map, or `null` if constructed from a raw `TiledMapData` without one. */
|
|
234
|
+
readonly mapKey: string | null;
|
|
235
|
+
/** Prefix used to derive auto-keys for entities spawned from objects. */
|
|
236
|
+
readonly keyPrefix: string | null;
|
|
224
237
|
private readonly _tiledMap;
|
|
225
|
-
private readonly _mapKey;
|
|
226
238
|
private readonly layerNames;
|
|
227
239
|
private readonly renderLayerName;
|
|
240
|
+
private readonly _explicitKeyPrefix;
|
|
241
|
+
/** Lazy flat-list cache. The parsed map is treated as immutable post-construction; if that ever changes, callers must invalidate. */
|
|
242
|
+
private _allObjectsCache;
|
|
228
243
|
constructor(options: TilemapComponentOptions);
|
|
229
244
|
onAdd(): void;
|
|
230
245
|
onDestroy(): void;
|
|
@@ -245,8 +260,37 @@ declare class TilemapComponent extends Component {
|
|
|
245
260
|
getTileAt(worldX: number, worldY: number, layerName?: string): number | null;
|
|
246
261
|
/** Extract physics-agnostic collision shapes from object layers. */
|
|
247
262
|
getCollisionShapes(objectLayerName?: string): TilemapColliderConfig[];
|
|
248
|
-
/**
|
|
263
|
+
/** Objects from object layers grouped by `class ?? name`. Use a layer name to scope. */
|
|
249
264
|
getObjects(objectLayerName?: string): Record<string, MapObject[]>;
|
|
265
|
+
/** Flat list of every object across every object layer. Memoized — safe because parsed map data is immutable post-construction. */
|
|
266
|
+
getAllObjects(): MapObject[];
|
|
267
|
+
/**
|
|
268
|
+
* Iterate every object on the given layer (or every layer if omitted),
|
|
269
|
+
* passing the auto-derived stable key alongside each object so callers can
|
|
270
|
+
* spawn entities with `scene.spawn(Class, params, { key })`.
|
|
271
|
+
*
|
|
272
|
+
* Skips objects that don't have a key prefix (component constructed from raw
|
|
273
|
+
* `map:` without `mapKey` or `keyPrefix`) — those callers should iterate
|
|
274
|
+
* `getObjects` directly.
|
|
275
|
+
*/
|
|
276
|
+
forEachObject(layerName: string | undefined, fn: (obj: MapObject, key: string) => void): void;
|
|
277
|
+
/** Auto-derived stable key for an object: `<keyPrefix>#object:<id>`. */
|
|
278
|
+
objectKey(obj: MapObject): string;
|
|
279
|
+
/** Find an object by its Tiled `id`. Searches every object layer. */
|
|
280
|
+
findObject(id: number): MapObject | undefined;
|
|
281
|
+
/** Find the first object with a matching `name`. Searches every object layer. */
|
|
282
|
+
findObjectByName(name: string): MapObject | undefined;
|
|
283
|
+
/** Read a typed custom property off any tilemap object. */
|
|
284
|
+
getProperty<T = unknown>(obj: MapObject, name: string): T | undefined;
|
|
285
|
+
/** Read an indexed property bag (`name[0]`, `name[1]`, ...) as an array. */
|
|
286
|
+
getPropertyArray<T = unknown>(obj: MapObject, name: string): T[];
|
|
287
|
+
/**
|
|
288
|
+
* Resolve a Tiled object-reference property to the actual object.
|
|
289
|
+
* Auto-collects across every layer so callers don't have to.
|
|
290
|
+
*/
|
|
291
|
+
resolveRef(obj: MapObject, propName: string): MapObject | undefined;
|
|
292
|
+
/** Same as `resolveRef`, but for indexed object-reference arrays. */
|
|
293
|
+
resolveRefArray(obj: MapObject, propName: string): MapObject[];
|
|
250
294
|
}
|
|
251
295
|
|
|
252
296
|
/** Syncs Transform to TilemapComponent display containers. */
|
|
@@ -261,6 +305,19 @@ declare class TilemapRenderSystem extends System {
|
|
|
261
305
|
/** Create a typed asset handle for a Tiled map JSON. */
|
|
262
306
|
declare function tiledMap(path: string): AssetHandle<TiledMapData>;
|
|
263
307
|
|
|
308
|
+
/**
|
|
309
|
+
* Build the stable identity key for an entity sourced from a Tiled object.
|
|
310
|
+
*
|
|
311
|
+
* Format: `<prefix>#object:<id>`. The prefix is normally the map's asset path
|
|
312
|
+
* (e.g. `/assets/dungeon/dungeon-map.json#object:42`); pass an explicit prefix
|
|
313
|
+
* when distinguishing between multiple instances of the same map.
|
|
314
|
+
*
|
|
315
|
+
* Use this to thread Tiled object identity into `scene.spawn(Class, params, { key })`
|
|
316
|
+
* so persistent stores (`defineSet<string>`, `defineMap<string, T>`) can key off
|
|
317
|
+
* authored level content without each game inventing its own naming scheme.
|
|
318
|
+
*/
|
|
319
|
+
declare function tiledObjectKey(prefix: string, objectId: number): string;
|
|
320
|
+
|
|
264
321
|
/**
|
|
265
322
|
* Extract physics-agnostic collision shapes from object layers.
|
|
266
323
|
*
|
|
@@ -330,4 +387,4 @@ declare function createTilemapLayers(map: TiledMapData, layerNames?: string[]):
|
|
|
330
387
|
*/
|
|
331
388
|
declare function extractObjects(map: TiledMapData, objectLayerName?: string): Record<string, TileObject[]>;
|
|
332
389
|
|
|
333
|
-
export { type HasProperties, type MapObject, type MapObjectProperty, type ObjectGroup, type ObjectLayerData, type PointObject, type PolygonColliderConfig, type PolygonObject, type RectColliderConfig, type RectangleObject, type TileData, type TileLayer, type TileLayerData, type TileObject, type TileObjectProperty, type TiledMapData, type TilemapColliderConfig, TilemapComponent, type TilemapComponentData, type TilemapComponentOptions, type TilemapData, TilemapPlugin, TilemapRenderSystem, type TilesetData, type TilesetRef, createTilemapLayers, extractCollisionShapes, extractObjects, getProperty, getPropertyArray, resolveObjectRef, resolveObjectRefArray, tiledMap, tiledMapAssetExtension, toPhysicsColliders, toTilemapData };
|
|
390
|
+
export { type HasProperties, type MapObject, type MapObjectProperty, type ObjectGroup, type ObjectLayerData, type PointObject, type PolygonColliderConfig, type PolygonObject, type RectColliderConfig, type RectangleObject, type TileData, type TileLayer, type TileLayerData, type TileObject, type TileObjectProperty, type TiledMapData, type TilemapColliderConfig, TilemapComponent, type TilemapComponentData, type TilemapComponentOptions, type TilemapData, TilemapPlugin, TilemapRenderSystem, type TilesetData, type TilesetRef, createTilemapLayers, extractCollisionShapes, extractObjects, getProperty, getPropertyArray, resolveObjectRef, resolveObjectRefArray, tiledMap, tiledMapAssetExtension, tiledObjectKey, toPhysicsColliders, toTilemapData };
|
package/dist/index.js
CHANGED
|
@@ -321,6 +321,48 @@ function objectToColliderConfig(obj) {
|
|
|
321
321
|
}
|
|
322
322
|
__name(objectToColliderConfig, "objectToColliderConfig");
|
|
323
323
|
|
|
324
|
+
// src/keys.ts
|
|
325
|
+
function tiledObjectKey(prefix, objectId) {
|
|
326
|
+
return `${prefix}#object:${objectId}`;
|
|
327
|
+
}
|
|
328
|
+
__name(tiledObjectKey, "tiledObjectKey");
|
|
329
|
+
|
|
330
|
+
// src/properties.ts
|
|
331
|
+
function getProperty(obj, name) {
|
|
332
|
+
const prop = obj.properties?.find((p) => p.name === name);
|
|
333
|
+
return prop?.value;
|
|
334
|
+
}
|
|
335
|
+
__name(getProperty, "getProperty");
|
|
336
|
+
function getPropertyArray(obj, name) {
|
|
337
|
+
const pattern = new RegExp(`^${escapeRegex(name)}\\[(\\d+)\\]$`);
|
|
338
|
+
const values = [];
|
|
339
|
+
if (!obj.properties) return values;
|
|
340
|
+
for (const prop of obj.properties) {
|
|
341
|
+
const match = prop.name.match(pattern);
|
|
342
|
+
if (match) {
|
|
343
|
+
const index = Number.parseInt(match[1], 10);
|
|
344
|
+
values[index] = prop.value;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
return values;
|
|
348
|
+
}
|
|
349
|
+
__name(getPropertyArray, "getPropertyArray");
|
|
350
|
+
function resolveObjectRef(obj, propName, allObjects) {
|
|
351
|
+
const id = getProperty(obj, propName);
|
|
352
|
+
if (id === void 0) return void 0;
|
|
353
|
+
return allObjects.find((o) => o.id === id);
|
|
354
|
+
}
|
|
355
|
+
__name(resolveObjectRef, "resolveObjectRef");
|
|
356
|
+
function resolveObjectRefArray(obj, propName, allObjects) {
|
|
357
|
+
const ids = getPropertyArray(obj, propName);
|
|
358
|
+
return ids.map((id) => allObjects.find((o) => o.id === id)).filter((o) => o !== void 0);
|
|
359
|
+
}
|
|
360
|
+
__name(resolveObjectRefArray, "resolveObjectRefArray");
|
|
361
|
+
function escapeRegex(str) {
|
|
362
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
363
|
+
}
|
|
364
|
+
__name(escapeRegex, "escapeRegex");
|
|
365
|
+
|
|
324
366
|
// src/TilemapComponent.ts
|
|
325
367
|
var _TilemapComponent_decorators, _init, _a;
|
|
326
368
|
_TilemapComponent_decorators = [serializable];
|
|
@@ -330,28 +372,51 @@ var _TilemapComponent = class _TilemapComponent extends (_a = Component) {
|
|
|
330
372
|
}
|
|
331
373
|
container;
|
|
332
374
|
data;
|
|
375
|
+
/** Asset path of this map, or `null` if constructed from a raw `TiledMapData` without one. */
|
|
376
|
+
mapKey;
|
|
377
|
+
/** Prefix used to derive auto-keys for entities spawned from objects. */
|
|
378
|
+
keyPrefix;
|
|
333
379
|
_tiledMap;
|
|
334
|
-
_mapKey;
|
|
335
380
|
layerNames;
|
|
336
381
|
renderLayerName;
|
|
382
|
+
_explicitKeyPrefix;
|
|
383
|
+
/** Lazy flat-list cache. The parsed map is treated as immutable post-construction; if that ever changes, callers must invalidate. */
|
|
384
|
+
_allObjectsCache;
|
|
337
385
|
constructor(options) {
|
|
338
386
|
super();
|
|
339
|
-
|
|
387
|
+
const sourceCount = (options.source ? 1 : 0) + (options.map ? 1 : 0) + (options.mapKey ? 1 : 0);
|
|
388
|
+
if (sourceCount === 0) {
|
|
340
389
|
throw new Error(
|
|
341
|
-
"TilemapComponent requires
|
|
390
|
+
"TilemapComponent requires one of `source`, `map`, or `mapKey`."
|
|
342
391
|
);
|
|
343
392
|
}
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
393
|
+
if (options.source) {
|
|
394
|
+
this.mapKey = options.source.path;
|
|
395
|
+
const data = Assets3.get(options.source.path);
|
|
396
|
+
if (!data) {
|
|
397
|
+
throw new Error(
|
|
398
|
+
`TilemapComponent: source "${options.source.path}" is not loaded. Add it to scene preload.`
|
|
399
|
+
);
|
|
400
|
+
}
|
|
401
|
+
this._tiledMap = data;
|
|
402
|
+
} else if (options.mapKey) {
|
|
403
|
+
this.mapKey = options.mapKey;
|
|
404
|
+
const data = Assets3.get(options.mapKey);
|
|
405
|
+
if (!data) {
|
|
406
|
+
throw new Error(
|
|
407
|
+
`TilemapComponent: map "${options.mapKey}" is not loaded. Add it to scene preload.`
|
|
408
|
+
);
|
|
409
|
+
}
|
|
410
|
+
this._tiledMap = data;
|
|
411
|
+
} else {
|
|
412
|
+
this.mapKey = null;
|
|
413
|
+
this._tiledMap = options.map;
|
|
350
414
|
}
|
|
351
|
-
this.
|
|
352
|
-
this.data = toTilemapData(tiledMap2);
|
|
415
|
+
this.data = toTilemapData(this._tiledMap);
|
|
353
416
|
this.layerNames = options.layers;
|
|
354
417
|
this.renderLayerName = options.layer ?? "default";
|
|
418
|
+
this._explicitKeyPrefix = options.keyPrefix;
|
|
419
|
+
this.keyPrefix = options.keyPrefix ?? this.mapKey;
|
|
355
420
|
this.container = new Container();
|
|
356
421
|
}
|
|
357
422
|
onAdd() {
|
|
@@ -367,23 +432,27 @@ var _TilemapComponent = class _TilemapComponent extends (_a = Component) {
|
|
|
367
432
|
this.container.destroy({ children: true });
|
|
368
433
|
}
|
|
369
434
|
serialize() {
|
|
370
|
-
if (!this.
|
|
435
|
+
if (!this.mapKey) {
|
|
371
436
|
console.warn(
|
|
372
|
-
`TilemapComponent on "${this.entity?.name}": created with a TiledMapData object. Use { mapKey } for save/load support.`
|
|
437
|
+
`TilemapComponent on "${this.entity?.name}": created with a TiledMapData object. Use { source } or { mapKey } for save/load support.`
|
|
373
438
|
);
|
|
374
439
|
return null;
|
|
375
440
|
}
|
|
376
441
|
return {
|
|
377
|
-
mapKey: this.
|
|
442
|
+
mapKey: this.mapKey,
|
|
378
443
|
layer: this.renderLayerName,
|
|
379
|
-
...this.layerNames && { layers: this.layerNames }
|
|
444
|
+
...this.layerNames && { layers: this.layerNames },
|
|
445
|
+
...this._explicitKeyPrefix !== void 0 && {
|
|
446
|
+
keyPrefix: this._explicitKeyPrefix
|
|
447
|
+
}
|
|
380
448
|
};
|
|
381
449
|
}
|
|
382
450
|
static fromSnapshot(data) {
|
|
383
451
|
return new _TilemapComponent({
|
|
384
452
|
mapKey: data.mapKey,
|
|
385
453
|
layer: data.layer,
|
|
386
|
-
...data.layers && { layers: data.layers }
|
|
454
|
+
...data.layers && { layers: data.layers },
|
|
455
|
+
...data.keyPrefix !== void 0 && { keyPrefix: data.keyPrefix }
|
|
387
456
|
});
|
|
388
457
|
}
|
|
389
458
|
/** Map width in pixels. */
|
|
@@ -428,7 +497,7 @@ var _TilemapComponent = class _TilemapComponent extends (_a = Component) {
|
|
|
428
497
|
getCollisionShapes(objectLayerName) {
|
|
429
498
|
return extractCollisionShapes(this.data, objectLayerName);
|
|
430
499
|
}
|
|
431
|
-
/**
|
|
500
|
+
/** Objects from object layers grouped by `class ?? name`. Use a layer name to scope. */
|
|
432
501
|
getObjects(objectLayerName) {
|
|
433
502
|
const filtered = objectLayerName ? this.data.objectLayers.filter((l) => l.name === objectLayerName) : this.data.objectLayers;
|
|
434
503
|
const result = {};
|
|
@@ -443,6 +512,84 @@ var _TilemapComponent = class _TilemapComponent extends (_a = Component) {
|
|
|
443
512
|
}
|
|
444
513
|
return result;
|
|
445
514
|
}
|
|
515
|
+
/** Flat list of every object across every object layer. Memoized — safe because parsed map data is immutable post-construction. */
|
|
516
|
+
getAllObjects() {
|
|
517
|
+
if (this._allObjectsCache) return this._allObjectsCache;
|
|
518
|
+
const result = [];
|
|
519
|
+
for (const layer of this.data.objectLayers) {
|
|
520
|
+
for (const obj of layer.objects) result.push(obj);
|
|
521
|
+
}
|
|
522
|
+
this._allObjectsCache = result;
|
|
523
|
+
return result;
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Iterate every object on the given layer (or every layer if omitted),
|
|
527
|
+
* passing the auto-derived stable key alongside each object so callers can
|
|
528
|
+
* spawn entities with `scene.spawn(Class, params, { key })`.
|
|
529
|
+
*
|
|
530
|
+
* Skips objects that don't have a key prefix (component constructed from raw
|
|
531
|
+
* `map:` without `mapKey` or `keyPrefix`) — those callers should iterate
|
|
532
|
+
* `getObjects` directly.
|
|
533
|
+
*/
|
|
534
|
+
forEachObject(layerName, fn) {
|
|
535
|
+
if (this.keyPrefix === null) {
|
|
536
|
+
throw new Error(
|
|
537
|
+
"TilemapComponent.forEachObject: cannot derive auto-keys without a `mapKey`, `source`, or explicit `keyPrefix`."
|
|
538
|
+
);
|
|
539
|
+
}
|
|
540
|
+
const layers = layerName ? this.data.objectLayers.filter((l) => l.name === layerName) : this.data.objectLayers;
|
|
541
|
+
for (const layer of layers) {
|
|
542
|
+
for (const obj of layer.objects) {
|
|
543
|
+
fn(obj, tiledObjectKey(this.keyPrefix, obj.id));
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
/** Auto-derived stable key for an object: `<keyPrefix>#object:<id>`. */
|
|
548
|
+
objectKey(obj) {
|
|
549
|
+
if (this.keyPrefix === null) {
|
|
550
|
+
throw new Error(
|
|
551
|
+
"TilemapComponent.objectKey: cannot derive a key without a `mapKey`, `source`, or explicit `keyPrefix`."
|
|
552
|
+
);
|
|
553
|
+
}
|
|
554
|
+
return tiledObjectKey(this.keyPrefix, obj.id);
|
|
555
|
+
}
|
|
556
|
+
/** Find an object by its Tiled `id`. Searches every object layer. */
|
|
557
|
+
findObject(id) {
|
|
558
|
+
for (const layer of this.data.objectLayers) {
|
|
559
|
+
for (const obj of layer.objects) {
|
|
560
|
+
if (obj.id === id) return obj;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
return void 0;
|
|
564
|
+
}
|
|
565
|
+
/** Find the first object with a matching `name`. Searches every object layer. */
|
|
566
|
+
findObjectByName(name) {
|
|
567
|
+
for (const layer of this.data.objectLayers) {
|
|
568
|
+
for (const obj of layer.objects) {
|
|
569
|
+
if (obj.name === name) return obj;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
return void 0;
|
|
573
|
+
}
|
|
574
|
+
/** Read a typed custom property off any tilemap object. */
|
|
575
|
+
getProperty(obj, name) {
|
|
576
|
+
return getProperty(obj, name);
|
|
577
|
+
}
|
|
578
|
+
/** Read an indexed property bag (`name[0]`, `name[1]`, ...) as an array. */
|
|
579
|
+
getPropertyArray(obj, name) {
|
|
580
|
+
return getPropertyArray(obj, name);
|
|
581
|
+
}
|
|
582
|
+
/**
|
|
583
|
+
* Resolve a Tiled object-reference property to the actual object.
|
|
584
|
+
* Auto-collects across every layer so callers don't have to.
|
|
585
|
+
*/
|
|
586
|
+
resolveRef(obj, propName) {
|
|
587
|
+
return resolveObjectRef(obj, propName, this.getAllObjects());
|
|
588
|
+
}
|
|
589
|
+
/** Same as `resolveRef`, but for indexed object-reference arrays. */
|
|
590
|
+
resolveRefArray(obj, propName) {
|
|
591
|
+
return resolveObjectRefArray(obj, propName, this.getAllObjects());
|
|
592
|
+
}
|
|
446
593
|
};
|
|
447
594
|
_init = __decoratorStart(_a);
|
|
448
595
|
_TilemapComponent = __decorateElement(_init, 0, "TilemapComponent", _TilemapComponent_decorators, _TilemapComponent);
|
|
@@ -532,42 +679,6 @@ function toPhysicsCollider(config) {
|
|
|
532
679
|
}
|
|
533
680
|
}
|
|
534
681
|
__name(toPhysicsCollider, "toPhysicsCollider");
|
|
535
|
-
|
|
536
|
-
// src/properties.ts
|
|
537
|
-
function getProperty(obj, name) {
|
|
538
|
-
const prop = obj.properties?.find((p) => p.name === name);
|
|
539
|
-
return prop?.value;
|
|
540
|
-
}
|
|
541
|
-
__name(getProperty, "getProperty");
|
|
542
|
-
function getPropertyArray(obj, name) {
|
|
543
|
-
const pattern = new RegExp(`^${escapeRegex(name)}\\[(\\d+)\\]$`);
|
|
544
|
-
const values = [];
|
|
545
|
-
if (!obj.properties) return values;
|
|
546
|
-
for (const prop of obj.properties) {
|
|
547
|
-
const match = prop.name.match(pattern);
|
|
548
|
-
if (match) {
|
|
549
|
-
const index = Number.parseInt(match[1], 10);
|
|
550
|
-
values[index] = prop.value;
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
return values;
|
|
554
|
-
}
|
|
555
|
-
__name(getPropertyArray, "getPropertyArray");
|
|
556
|
-
function resolveObjectRef(obj, propName, allObjects) {
|
|
557
|
-
const id = getProperty(obj, propName);
|
|
558
|
-
if (id === void 0) return void 0;
|
|
559
|
-
return allObjects.find((o) => o.id === id);
|
|
560
|
-
}
|
|
561
|
-
__name(resolveObjectRef, "resolveObjectRef");
|
|
562
|
-
function resolveObjectRefArray(obj, propName, allObjects) {
|
|
563
|
-
const ids = getPropertyArray(obj, propName);
|
|
564
|
-
return ids.map((id) => allObjects.find((o) => o.id === id)).filter((o) => o !== void 0);
|
|
565
|
-
}
|
|
566
|
-
__name(resolveObjectRefArray, "resolveObjectRefArray");
|
|
567
|
-
function escapeRegex(str) {
|
|
568
|
-
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
569
|
-
}
|
|
570
|
-
__name(escapeRegex, "escapeRegex");
|
|
571
682
|
export {
|
|
572
683
|
TilemapComponent,
|
|
573
684
|
TilemapPlugin,
|
|
@@ -581,6 +692,7 @@ export {
|
|
|
581
692
|
resolveObjectRefArray,
|
|
582
693
|
tiledMap,
|
|
583
694
|
tiledMapAssetExtension,
|
|
695
|
+
tiledObjectKey,
|
|
584
696
|
toPhysicsColliders,
|
|
585
697
|
toTilemapData
|
|
586
698
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/TilemapPlugin.ts","../src/tiled/tiledMapLoader.ts","../src/TilemapRenderSystem.ts","../src/TilemapComponent.ts","../src/tiled/parseTiledMap.ts","../src/colliders.ts","../src/assets.ts","../src/toPhysicsColliders.ts","../src/properties.ts"],"sourcesContent":["import { AssetManagerKey } from \"@yagejs/core\";\nimport type { EngineContext, Plugin, SystemScheduler } from \"@yagejs/core\";\nimport { extensions, Assets } from \"pixi.js\";\nimport { tiledMapAssetExtension } from \"./tiled/tiledMapLoader.js\";\nimport { TilemapRenderSystem } from \"./TilemapRenderSystem.js\";\nimport type { TiledMapData } from \"./tiled/types.js\";\n\n/** Plugin that adds Tiled map loading and rendering to YAGE. */\nexport class TilemapPlugin implements Plugin {\n readonly name = \"tilemap\";\n readonly version = \"2.0.0\";\n readonly dependencies = [\"renderer\"] as const;\n\n install(context: EngineContext): void {\n // Register PixiJS loader extension for Tiled map JSON files\n extensions.add(tiledMapAssetExtension);\n\n // Register \"tiledMap\" loader with AssetManager\n const am = context.tryResolve(AssetManagerKey);\n am?.registerLoader(\"tiledMap\", {\n load: (path: string) => Assets.load<TiledMapData>(path),\n unload: (path: string) => {\n Assets.unload(path);\n },\n });\n }\n\n registerSystems(scheduler: SystemScheduler): void {\n scheduler.add(new TilemapRenderSystem());\n }\n}\n","import {\n ExtensionType,\n LoaderParserPriority,\n Assets,\n path,\n Texture,\n Rectangle,\n} from \"pixi.js\";\nimport type { LoaderParser, ResolvedAsset, Loader } from \"pixi.js\";\nimport type { TiledMapData, TilesetData, TilesetRef } from \"./types.js\";\n\n/**\n * PixiJS loader extension that detects Tiled map JSON files and resolves\n * their tileset references.\n *\n * Supports two tileset formats:\n * 1. **Collection-of-images** — tileset has `tiles[]` with image paths.\n * Assumes textures are already in the PixiJS cache (e.g. from a\n * pre-loaded spritesheet atlas).\n * 2. **Single-image tileset** — tileset has an `image` property pointing\n * to a spritesheet. The loader loads the image and creates sub-textures\n * for each tile based on grid layout.\n */\nconst tiledMapLoaderParser: LoaderParser<TiledMapData> = {\n id: \"tiledMapLoader\",\n\n extension: {\n type: ExtensionType.LoadParser,\n priority: LoaderParserPriority.High,\n },\n\n async testParse(\n asset: TiledMapData,\n resolvedAsset?: ResolvedAsset,\n ): Promise<boolean> {\n if (!resolvedAsset?.src) return false;\n if (path.extname(resolvedAsset.src).toLowerCase() !== \".json\") return false;\n const obj = asset as unknown as Record<string, unknown>;\n return !!(obj.tilesets && obj.layers);\n },\n\n async parse(\n asset: TiledMapData,\n resolvedAsset?: ResolvedAsset,\n loader?: Loader,\n ): Promise<TiledMapData> {\n const src = resolvedAsset?.src;\n if (!src || !loader) return asset;\n\n let basePath = path.dirname(src);\n if (basePath && !basePath.endsWith(\"/\")) {\n basePath += \"/\";\n }\n\n for (const tilesetRef of asset.tilesets as TilesetRef[]) {\n if (tilesetRef.source) {\n // External tileset JSON — load it\n const tilesetPath = basePath + tilesetRef.source;\n const tilesetData = (await loader.load<TilesetData>({\n src: tilesetPath,\n })) as TilesetData;\n tilesetRef.data = tilesetData;\n }\n\n const tileset = tilesetRef.data;\n if (!tileset) continue;\n\n // Single-image tileset: load the image and create sub-textures\n if (tileset.image && !tileset.tiles?.length) {\n const imagePath = basePath + tileset.image;\n const baseTexture = await Assets.load<Texture>(imagePath);\n const cols = tileset.columns;\n const tw = tileset.tilewidth;\n const th = tileset.tileheight;\n const margin = tileset.margin ?? 0;\n const spacing = tileset.spacing ?? 0;\n\n for (let id = 0; id < tileset.tilecount; id++) {\n const col = id % cols;\n const row = Math.floor(id / cols);\n const x = margin + col * (tw + spacing);\n const y = margin + row * (th + spacing);\n\n const frame = new Rectangle(x, y, tw, th);\n const subtex = new Texture({\n source: baseTexture.source,\n frame,\n });\n\n // Store subtexture in PixiJS cache with a key like \"tileset-name:id\"\n const cacheKey = `${tileset.name}:${id}`;\n Assets.cache.set(cacheKey, subtex);\n }\n }\n // Collection-of-images: textures are expected to already be\n // in the PixiJS cache (loaded via spritesheet atlas).\n }\n\n return asset;\n },\n\n unload() {},\n};\n\n/** PixiJS asset extension bundle for Tiled map JSON files. */\nexport const tiledMapAssetExtension = {\n extension: ExtensionType.Asset,\n loader: tiledMapLoaderParser,\n};\n","import { System, Phase, Transform, QueryCacheKey } from \"@yagejs/core\";\nimport type { EngineContext, QueryResult } from \"@yagejs/core\";\nimport { TilemapComponent } from \"./TilemapComponent.js\";\n\n/** Syncs Transform to TilemapComponent display containers. */\nexport class TilemapRenderSystem extends System {\n readonly phase = Phase.Render;\n readonly priority = -1; // Before DisplaySystem (0), so tilemaps render behind sprites\n\n private query!: QueryResult;\n\n onRegister(context: EngineContext): void {\n const queryCache = context.resolve(QueryCacheKey);\n this.query = queryCache.register([Transform, TilemapComponent]);\n }\n\n update(): void {\n for (const entity of this.query) {\n const transform = entity.get(Transform);\n const tilemap = entity.get(TilemapComponent);\n if (!tilemap.enabled) continue;\n\n tilemap.container.position.x = transform.worldPosition.x;\n tilemap.container.position.y = transform.worldPosition.y;\n tilemap.container.rotation = transform.worldRotation;\n tilemap.container.scale.x = transform.worldScale.x;\n tilemap.container.scale.y = transform.worldScale.y;\n }\n }\n}\n","import { Component, Transform, serializable } from \"@yagejs/core\";\nimport { Assets, Container } from \"pixi.js\";\nimport { SceneRenderTreeKey } from \"@yagejs/renderer\";\nimport { createTilemapLayers, toTilemapData } from \"./tiled/parseTiledMap.js\";\nimport { extractCollisionShapes } from \"./colliders.js\";\nimport type { TiledMapData } from \"./tiled/types.js\";\nimport type {\n TilemapData,\n MapObject,\n TilemapColliderConfig,\n} from \"./types.js\";\n\n/** Options for creating a TilemapComponent. */\nexport interface TilemapComponentOptions {\n /** Parsed Tiled map data (not serializable). */\n map?: TiledMapData;\n /** Asset path to the Tiled JSON (serializable, resolved via Assets.get). */\n mapKey?: string;\n /** Which tile layers to render. Omit to render all. */\n layers?: string[];\n /** Render layer name. Default: \"default\". */\n layer?: string;\n}\n\n/** Serializable snapshot of a TilemapComponent. */\nexport interface TilemapComponentData {\n mapKey: string;\n layers?: string[];\n layer: string;\n}\n\n/** Component that renders a Tiled map using @pixi/tilemap. */\n@serializable\nexport class TilemapComponent extends Component {\n readonly container: Container;\n readonly data: TilemapData;\n private readonly _tiledMap: TiledMapData;\n private readonly _mapKey: string | null;\n private readonly layerNames: string[] | undefined;\n private readonly renderLayerName: string;\n\n constructor(options: TilemapComponentOptions) {\n super();\n\n if (!options.map && !options.mapKey) {\n throw new Error(\n \"TilemapComponent requires either `map` or `mapKey`.\",\n );\n }\n\n this._mapKey = options.mapKey ?? null;\n const tiledMap = options.map ?? Assets.get<TiledMapData>(options.mapKey!);\n if (!tiledMap) {\n throw new Error(\n `TilemapComponent: map \"${options.mapKey}\" is not loaded. Add it to scene preload.`,\n );\n }\n\n this._tiledMap = tiledMap;\n this.data = toTilemapData(tiledMap);\n this.layerNames = options.layers;\n this.renderLayerName = options.layer ?? \"default\";\n this.container = new Container();\n }\n\n onAdd(): void {\n const tilemapLayers = createTilemapLayers(this._tiledMap, this.layerNames);\n for (const layer of tilemapLayers) {\n this.container.addChild(layer);\n }\n\n const renderLayer = this.use(SceneRenderTreeKey).get(this.renderLayerName);\n renderLayer.container.addChild(this.container);\n }\n\n onDestroy(): void {\n this.container.removeFromParent();\n this.container.destroy({ children: true });\n }\n\n serialize(): TilemapComponentData | null {\n if (!this._mapKey) {\n console.warn(\n `TilemapComponent on \"${this.entity?.name}\": created with a TiledMapData object. ` +\n `Use { mapKey } for save/load support.`,\n );\n return null;\n }\n return {\n mapKey: this._mapKey,\n layer: this.renderLayerName,\n ...(this.layerNames && { layers: this.layerNames }),\n };\n }\n\n static fromSnapshot(data: TilemapComponentData): TilemapComponent {\n return new TilemapComponent({\n mapKey: data.mapKey,\n layer: data.layer,\n ...(data.layers && { layers: data.layers }),\n });\n }\n\n /** Map width in pixels. */\n get widthPx(): number {\n return this.data.width * this.data.tileWidth;\n }\n\n /** Map height in pixels. */\n get heightPx(): number {\n return this.data.height * this.data.tileHeight;\n }\n\n /** Tile width in pixels. */\n get tileWidth(): number {\n return this.data.tileWidth;\n }\n\n /** Tile height in pixels. */\n get tileHeight(): number {\n return this.data.tileHeight;\n }\n\n /**\n * Returns the tile GID at a world position, accounting for entity Transform offset.\n * Returns null if the position is outside the map or the tile is empty.\n */\n getTileAt(\n worldX: number,\n worldY: number,\n layerName?: string,\n ): number | null {\n const transform = this.entity.tryGet(Transform);\n const offsetX = transform ? transform.position.x : 0;\n const offsetY = transform ? transform.position.y : 0;\n const localX = worldX - offsetX;\n const localY = worldY - offsetY;\n\n const col = Math.floor(localX / this.data.tileWidth);\n const row = Math.floor(localY / this.data.tileHeight);\n\n if (col < 0 || col >= this.data.width) return null;\n if (row < 0 || row >= this.data.height) return null;\n\n const layers = layerName\n ? this.data.tileLayers.filter((l) => l.name === layerName)\n : this.data.tileLayers;\n\n // Return first non-zero GID found (from last layer to first for top-most)\n for (let i = layers.length - 1; i >= 0; i--) {\n const layer = layers[i]!;\n const gid = layer.data[row * layer.width + col];\n if (gid !== undefined && gid !== 0) return gid;\n }\n\n return null;\n }\n\n /** Extract physics-agnostic collision shapes from object layers. */\n getCollisionShapes(objectLayerName?: string): TilemapColliderConfig[] {\n return extractCollisionShapes(this.data, objectLayerName);\n }\n\n /** Extract objects from object layers grouped by class/name. */\n getObjects(objectLayerName?: string): Record<string, MapObject[]> {\n const filtered = objectLayerName\n ? this.data.objectLayers.filter((l) => l.name === objectLayerName)\n : this.data.objectLayers;\n\n const result: Record<string, MapObject[]> = {};\n\n for (const layer of filtered) {\n for (const obj of layer.objects) {\n const key = obj.class ?? obj.name;\n if (!result[key]) {\n result[key] = [];\n }\n result[key].push(obj);\n }\n }\n\n return result;\n }\n}\n","import { CompositeTilemap } from \"@pixi/tilemap\";\nimport { Assets, Texture, Rectangle } from \"pixi.js\";\nimport type {\n TiledMapData,\n TileLayer,\n TilesetRef,\n ObjectGroup,\n TileObject,\n} from \"./types.js\";\nimport type {\n TilemapData,\n TileLayerData,\n ObjectLayerData,\n MapObject,\n} from \"../types.js\";\n\n// ─── Generic adapter ────────────────────────────────────────────────\n\n/**\n * Convert Tiled JSON data to the generic TilemapData format.\n */\nexport function toTilemapData(map: TiledMapData): TilemapData {\n const tileLayers: TileLayerData[] = [];\n const objectLayers: ObjectLayerData[] = [];\n\n for (const layer of map.layers) {\n if (layer.type === \"tilelayer\") {\n tileLayers.push({\n name: layer.name,\n data: layer.data,\n width: layer.width,\n height: layer.height,\n visible: layer.visible,\n });\n } else if (layer.type === \"objectgroup\") {\n objectLayers.push({\n name: layer.name,\n objects: layer.objects.map(tiledObjectToMapObject),\n visible: layer.visible,\n });\n }\n }\n\n return {\n width: map.width,\n height: map.height,\n tileWidth: map.tilewidth,\n tileHeight: map.tileheight,\n tileLayers,\n objectLayers,\n };\n}\n\nfunction tiledObjectToMapObject(obj: TileObject): MapObject {\n const result: MapObject = {\n id: obj.id,\n name: obj.name,\n x: obj.x,\n y: obj.y,\n width: obj.width,\n height: obj.height,\n rotation: obj.rotation,\n visible: obj.visible,\n };\n\n const cls = obj.class ?? obj.type;\n if (cls) result.class = cls;\n if (obj.point === true) result.point = true;\n if (obj.polygon) result.polygon = obj.polygon;\n if (obj.properties) {\n result.properties = obj.properties.map((p) => ({\n name: p.name,\n type: p.type,\n value: p.value,\n }));\n }\n\n return result;\n}\n\n// ─── Tiled-specific rendering ───────────────────────────────────────\n\n/**\n * Resolve the tileset that owns a given global tile ID.\n * Tilesets are sorted by firstgid; we find the last tileset whose firstgid <= gid.\n */\nfunction findTileset(tilesets: TilesetRef[], gid: number): TilesetRef | null {\n let result: TilesetRef | null = null;\n for (const ts of tilesets) {\n if (ts.firstgid <= gid) {\n if (!result || ts.firstgid > result.firstgid) {\n result = ts;\n }\n }\n }\n return result;\n}\n\n/**\n * Resolve the texture for a tile given its GID and owning tileset.\n */\nfunction resolveTileTexture(\n gid: number,\n tileset: TilesetRef,\n): Texture | null {\n const data = tileset.data;\n if (!data) return null;\n const localId = gid - tileset.firstgid;\n\n if (data.tiles?.length) {\n // Collection-of-images tileset: look up texture by filename from cache\n const tileData = data.tiles[localId];\n if (!tileData?.image) return null;\n const filenameMatch = tileData.image.match(/[^/]*$/);\n const filename = filenameMatch?.[0];\n if (!filename) return null;\n const tex = Assets.get<Texture>(filename);\n return tex ?? null;\n }\n\n if (data.image) {\n // Single-image tileset: sub-textures were created by the loader\n const cacheKey = `${data.name}:${localId}`;\n const tex = Assets.get<Texture>(cacheKey);\n if (tex) return tex;\n\n // Fallback: create sub-texture on the fly from the base image\n const filenameMatch = data.image.match(/[^/]*$/);\n const filename = filenameMatch?.[0];\n if (!filename) return null;\n const baseTex = Assets.get<Texture>(filename);\n if (!baseTex) return null;\n\n const cols = data.columns;\n const tw = data.tilewidth;\n const th = data.tileheight;\n const margin = data.margin ?? 0;\n const spacing = data.spacing ?? 0;\n const col = localId % cols;\n const row = Math.floor(localId / cols);\n const x = margin + col * (tw + spacing);\n const y = margin + row * (th + spacing);\n\n return new Texture({\n source: baseTex.source,\n frame: new Rectangle(x, y, tw, th),\n });\n }\n\n return null;\n}\n\n/**\n * Build CompositeTilemap display objects from a parsed Tiled map.\n *\n * @param map - Parsed TiledMapData (with resolved tilesets).\n * @param layerNames - Optional filter: only process these tile layer names.\n * @returns Array of CompositeTilemap, one per tile layer.\n */\nexport function createTilemapLayers(\n map: TiledMapData,\n layerNames?: string[],\n): CompositeTilemap[] {\n const tileLayers = map.layers.filter(\n (l): l is TileLayer => l.type === \"tilelayer\",\n );\n\n const filtered = layerNames\n ? tileLayers.filter((l) => layerNames.includes(l.name))\n : tileLayers;\n\n return filtered.map((layer) => {\n const tilemap = new CompositeTilemap();\n const { data, width } = layer;\n\n for (let index = 0; index < data.length; index++) {\n const gid = data[index]!;\n if (gid === 0) continue;\n\n const tileset = findTileset(map.tilesets, gid);\n if (!tileset) {\n throw new Error(`No tileset found for tile GID ${gid}`);\n }\n\n const texture = resolveTileTexture(gid, tileset);\n if (!texture) {\n throw new Error(\n `Could not resolve texture for tile GID ${gid} in tileset \"${tileset.data?.name}\"`,\n );\n }\n\n const x = index % width;\n const y = Math.floor(index / width);\n tilemap.tile(texture, x * map.tilewidth, y * map.tileheight);\n }\n\n return tilemap;\n });\n}\n\n/**\n * Extract objects from Tiled object layers, grouped by class/type/name.\n *\n * @param map - Parsed TiledMapData.\n * @param objectLayerName - Optional: only extract from this layer.\n * @returns Record mapping class/type/name to arrays of TileObject.\n */\nexport function extractObjects(\n map: TiledMapData,\n objectLayerName?: string,\n): Record<string, TileObject[]> {\n const objectLayers = map.layers.filter(\n (l): l is ObjectGroup => l.type === \"objectgroup\",\n );\n\n const filtered = objectLayerName\n ? objectLayers.filter((l) => l.name === objectLayerName)\n : objectLayers;\n\n const result: Record<string, TileObject[]> = {};\n\n for (const layer of filtered) {\n for (const obj of layer.objects) {\n const key = obj.class ?? obj.type ?? obj.name;\n if (!result[key]) {\n result[key] = [];\n }\n result[key].push(obj);\n }\n }\n\n return result;\n}\n","import type {\n TilemapData,\n MapObject,\n TilemapColliderConfig,\n RectColliderConfig,\n PolygonColliderConfig,\n} from \"./types.js\";\n\n/**\n * Extract physics-agnostic collision shapes from object layers.\n *\n * - Rectangle objects -> RectColliderConfig\n * - Polygon objects -> PolygonColliderConfig\n * - Point objects -> skipped (not collision shapes)\n *\n * @param map - Generic TilemapData.\n * @param objectLayerName - Optional: only extract from this layer.\n */\nexport function extractCollisionShapes(\n map: TilemapData,\n objectLayerName?: string,\n): TilemapColliderConfig[] {\n const filtered = objectLayerName\n ? map.objectLayers.filter((l) => l.name === objectLayerName)\n : map.objectLayers;\n\n const shapes: TilemapColliderConfig[] = [];\n\n for (const layer of filtered) {\n for (const obj of layer.objects) {\n const shape = objectToColliderConfig(obj);\n if (shape) shapes.push(shape);\n }\n }\n\n return shapes;\n}\n\n/**\n * Convert a single MapObject to a ColliderConfig.\n * Returns null for point objects (not collision shapes).\n */\nfunction objectToColliderConfig(obj: MapObject): TilemapColliderConfig | null {\n // Skip point objects\n if (obj.point) return null;\n\n if (obj.polygon) {\n const config: PolygonColliderConfig = {\n type: \"polygon\",\n x: obj.x,\n y: obj.y,\n vertices: obj.polygon.map((v) => ({ x: v.x, y: v.y })),\n };\n return config;\n }\n\n // Rectangle object\n const config: RectColliderConfig = {\n type: \"rect\",\n x: obj.x,\n y: obj.y,\n width: obj.width,\n height: obj.height,\n };\n return config;\n}\n","import { AssetHandle } from \"@yagejs/core\";\nimport type { TiledMapData } from \"./tiled/types.js\";\n\n/** Create a typed asset handle for a Tiled map JSON. */\nexport function tiledMap(path: string): AssetHandle<TiledMapData> {\n return new AssetHandle(\"tiledMap\", path);\n}\n","import type { ColliderConfig as PhysicsColliderConfig } from \"@yagejs/physics\";\nimport type { TilemapColliderConfig } from \"./types.js\";\n\n/**\n * Convert tilemap TilemapColliderConfig[] (top-left origin rects/polygons) into\n * physics-package ColliderConfig[] (center-origin shape + offset).\n */\nexport function toPhysicsColliders(\n shapes: TilemapColliderConfig[],\n): PhysicsColliderConfig[] {\n return shapes.map(toPhysicsCollider);\n}\n\nfunction toPhysicsCollider(config: TilemapColliderConfig): PhysicsColliderConfig {\n switch (config.type) {\n case \"polygon\":\n return {\n shape: {\n type: \"polygon\",\n vertices: config.vertices,\n },\n offset: { x: config.x, y: config.y },\n };\n case \"rect\":\n return {\n shape: { type: \"box\", width: config.width, height: config.height },\n offset: {\n x: config.x + config.width / 2,\n y: config.y + config.height / 2,\n },\n };\n }\n}\n","import type { HasProperties, MapObject } from \"./types.js\";\n\n/**\n * Get a single property value by name.\n * Returns `undefined` if the property is not found.\n */\nexport function getProperty<T = unknown>(\n obj: HasProperties,\n name: string,\n): T | undefined {\n const prop = obj.properties?.find((p) => p.name === name);\n return prop?.value as T | undefined;\n}\n\n/**\n * Get a pseudo-array of property values.\n *\n * Tiled doesn't support array properties natively, so a common convention\n * is to use indexed names like `spawns[0]`, `spawns[1]`, etc.\n * This function collects them into a proper array, preserving index order.\n */\nexport function getPropertyArray<T = unknown>(\n obj: HasProperties,\n name: string,\n): T[] {\n const pattern = new RegExp(`^${escapeRegex(name)}\\\\[(\\\\d+)\\\\]$`);\n const values: T[] = [];\n\n if (!obj.properties) return values;\n\n for (const prop of obj.properties) {\n const match = prop.name.match(pattern);\n if (match) {\n const index = Number.parseInt(match[1]!, 10);\n values[index] = prop.value as T;\n }\n }\n\n return values;\n}\n\n/**\n * Resolve a property of `type: \"object\"` (an ID reference) to the actual MapObject.\n * Returns `undefined` if the property doesn't exist or the referenced object isn't found.\n */\nexport function resolveObjectRef(\n obj: HasProperties,\n propName: string,\n allObjects: MapObject[],\n): MapObject | undefined {\n const id = getProperty<number>(obj, propName);\n if (id === undefined) return undefined;\n return allObjects.find((o) => o.id === id);\n}\n\n/**\n * Resolve a pseudo-array of object ID references to actual MapObjects.\n * Uses the `name[0]`, `name[1]` convention.\n */\nexport function resolveObjectRefArray(\n obj: HasProperties,\n propName: string,\n allObjects: MapObject[],\n): MapObject[] {\n const ids = getPropertyArray<number>(obj, propName);\n return ids\n .map((id) => allObjects.find((o) => o.id === id))\n .filter((o): o is MapObject => o !== undefined);\n}\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n"],"mappings":"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","names":["Assets","Transform","Assets","Assets","Texture","Rectangle","Assets","Texture","Rectangle","config","tiledMap","Assets","Transform","path","Assets","path"]}
|
|
1
|
+
{"version":3,"sources":["../src/TilemapPlugin.ts","../src/tiled/tiledMapLoader.ts","../src/TilemapRenderSystem.ts","../src/TilemapComponent.ts","../src/tiled/parseTiledMap.ts","../src/colliders.ts","../src/keys.ts","../src/properties.ts","../src/assets.ts","../src/toPhysicsColliders.ts"],"sourcesContent":["import { AssetManagerKey } from \"@yagejs/core\";\nimport type { EngineContext, Plugin, SystemScheduler } from \"@yagejs/core\";\nimport { extensions, Assets } from \"pixi.js\";\nimport { tiledMapAssetExtension } from \"./tiled/tiledMapLoader.js\";\nimport { TilemapRenderSystem } from \"./TilemapRenderSystem.js\";\nimport type { TiledMapData } from \"./tiled/types.js\";\n\n/** Plugin that adds Tiled map loading and rendering to YAGE. */\nexport class TilemapPlugin implements Plugin {\n readonly name = \"tilemap\";\n readonly version = \"2.0.0\";\n readonly dependencies = [\"renderer\"] as const;\n\n install(context: EngineContext): void {\n // Register PixiJS loader extension for Tiled map JSON files\n extensions.add(tiledMapAssetExtension);\n\n // Register \"tiledMap\" loader with AssetManager\n const am = context.tryResolve(AssetManagerKey);\n am?.registerLoader(\"tiledMap\", {\n load: (path: string) => Assets.load<TiledMapData>(path),\n unload: (path: string) => {\n Assets.unload(path);\n },\n });\n }\n\n registerSystems(scheduler: SystemScheduler): void {\n scheduler.add(new TilemapRenderSystem());\n }\n}\n","import {\n ExtensionType,\n LoaderParserPriority,\n Assets,\n path,\n Texture,\n Rectangle,\n} from \"pixi.js\";\nimport type { LoaderParser, ResolvedAsset, Loader } from \"pixi.js\";\nimport type { TiledMapData, TilesetData, TilesetRef } from \"./types.js\";\n\n/**\n * PixiJS loader extension that detects Tiled map JSON files and resolves\n * their tileset references.\n *\n * Supports two tileset formats:\n * 1. **Collection-of-images** — tileset has `tiles[]` with image paths.\n * Assumes textures are already in the PixiJS cache (e.g. from a\n * pre-loaded spritesheet atlas).\n * 2. **Single-image tileset** — tileset has an `image` property pointing\n * to a spritesheet. The loader loads the image and creates sub-textures\n * for each tile based on grid layout.\n */\nconst tiledMapLoaderParser: LoaderParser<TiledMapData> = {\n id: \"tiledMapLoader\",\n\n extension: {\n type: ExtensionType.LoadParser,\n priority: LoaderParserPriority.High,\n },\n\n async testParse(\n asset: TiledMapData,\n resolvedAsset?: ResolvedAsset,\n ): Promise<boolean> {\n if (!resolvedAsset?.src) return false;\n if (path.extname(resolvedAsset.src).toLowerCase() !== \".json\") return false;\n const obj = asset as unknown as Record<string, unknown>;\n return !!(obj.tilesets && obj.layers);\n },\n\n async parse(\n asset: TiledMapData,\n resolvedAsset?: ResolvedAsset,\n loader?: Loader,\n ): Promise<TiledMapData> {\n const src = resolvedAsset?.src;\n if (!src || !loader) return asset;\n\n let basePath = path.dirname(src);\n if (basePath && !basePath.endsWith(\"/\")) {\n basePath += \"/\";\n }\n\n for (const tilesetRef of asset.tilesets as TilesetRef[]) {\n if (tilesetRef.source) {\n // External tileset JSON — load it\n const tilesetPath = basePath + tilesetRef.source;\n const tilesetData = (await loader.load<TilesetData>({\n src: tilesetPath,\n })) as TilesetData;\n tilesetRef.data = tilesetData;\n }\n\n const tileset = tilesetRef.data;\n if (!tileset) continue;\n\n // Single-image tileset: load the image and create sub-textures\n if (tileset.image && !tileset.tiles?.length) {\n const imagePath = basePath + tileset.image;\n const baseTexture = await Assets.load<Texture>(imagePath);\n const cols = tileset.columns;\n const tw = tileset.tilewidth;\n const th = tileset.tileheight;\n const margin = tileset.margin ?? 0;\n const spacing = tileset.spacing ?? 0;\n\n for (let id = 0; id < tileset.tilecount; id++) {\n const col = id % cols;\n const row = Math.floor(id / cols);\n const x = margin + col * (tw + spacing);\n const y = margin + row * (th + spacing);\n\n const frame = new Rectangle(x, y, tw, th);\n const subtex = new Texture({\n source: baseTexture.source,\n frame,\n });\n\n // Store subtexture in PixiJS cache with a key like \"tileset-name:id\"\n const cacheKey = `${tileset.name}:${id}`;\n Assets.cache.set(cacheKey, subtex);\n }\n }\n // Collection-of-images: textures are expected to already be\n // in the PixiJS cache (loaded via spritesheet atlas).\n }\n\n return asset;\n },\n\n unload() {},\n};\n\n/** PixiJS asset extension bundle for Tiled map JSON files. */\nexport const tiledMapAssetExtension = {\n extension: ExtensionType.Asset,\n loader: tiledMapLoaderParser,\n};\n","import { System, Phase, Transform, QueryCacheKey } from \"@yagejs/core\";\nimport type { EngineContext, QueryResult } from \"@yagejs/core\";\nimport { TilemapComponent } from \"./TilemapComponent.js\";\n\n/** Syncs Transform to TilemapComponent display containers. */\nexport class TilemapRenderSystem extends System {\n readonly phase = Phase.Render;\n readonly priority = -1; // Before DisplaySystem (0), so tilemaps render behind sprites\n\n private query!: QueryResult;\n\n onRegister(context: EngineContext): void {\n const queryCache = context.resolve(QueryCacheKey);\n this.query = queryCache.register([Transform, TilemapComponent]);\n }\n\n update(): void {\n for (const entity of this.query) {\n const transform = entity.get(Transform);\n const tilemap = entity.get(TilemapComponent);\n if (!tilemap.enabled) continue;\n\n tilemap.container.position.x = transform.worldPosition.x;\n tilemap.container.position.y = transform.worldPosition.y;\n tilemap.container.rotation = transform.worldRotation;\n tilemap.container.scale.x = transform.worldScale.x;\n tilemap.container.scale.y = transform.worldScale.y;\n }\n }\n}\n","import { Component, Transform, serializable } from \"@yagejs/core\";\nimport type { AssetHandle } from \"@yagejs/core\";\nimport { Assets, Container } from \"pixi.js\";\nimport { SceneRenderTreeKey } from \"@yagejs/renderer\";\nimport { createTilemapLayers, toTilemapData } from \"./tiled/parseTiledMap.js\";\nimport { extractCollisionShapes } from \"./colliders.js\";\nimport { tiledObjectKey } from \"./keys.js\";\nimport {\n getProperty,\n getPropertyArray,\n resolveObjectRef,\n resolveObjectRefArray,\n} from \"./properties.js\";\nimport type { TiledMapData } from \"./tiled/types.js\";\nimport type {\n TilemapData,\n MapObject,\n TilemapColliderConfig,\n} from \"./types.js\";\n\n/** Options for creating a TilemapComponent. */\nexport interface TilemapComponentOptions {\n /** Asset handle for the map. Preferred — captures both the parsed data and the asset path. */\n source?: AssetHandle<TiledMapData>;\n /** Parsed Tiled map data. Use only when you don't have an AssetHandle. Save/load and auto-keys require `mapKey` or `source`. */\n map?: TiledMapData;\n /** Asset path to the Tiled JSON. Resolved via `Assets.get`. Save/load uses this. */\n mapKey?: string;\n /** Which tile layers to render. Omit to render all. */\n layers?: string[];\n /** Render layer name. Default: \"default\". */\n layer?: string;\n /**\n * Override prefix used when auto-keying entities spawned from Tiled objects.\n * Defaults to `mapKey`. Set this when multiple instances of the same map need\n * distinct entity-key namespaces (e.g. instanced dungeons).\n */\n keyPrefix?: string;\n}\n\n/** Serializable snapshot of a TilemapComponent. */\nexport interface TilemapComponentData {\n mapKey: string;\n layers?: string[];\n layer: string;\n keyPrefix?: string;\n}\n\n/** Component that renders a Tiled map using @pixi/tilemap. */\n@serializable\nexport class TilemapComponent extends Component {\n readonly container: Container;\n readonly data: TilemapData;\n /** Asset path of this map, or `null` if constructed from a raw `TiledMapData` without one. */\n readonly mapKey: string | null;\n /** Prefix used to derive auto-keys for entities spawned from objects. */\n readonly keyPrefix: string | null;\n private readonly _tiledMap: TiledMapData;\n private readonly layerNames: string[] | undefined;\n private readonly renderLayerName: string;\n private readonly _explicitKeyPrefix: string | undefined;\n /** Lazy flat-list cache. The parsed map is treated as immutable post-construction; if that ever changes, callers must invalidate. */\n private _allObjectsCache: MapObject[] | undefined;\n\n constructor(options: TilemapComponentOptions) {\n super();\n\n const sourceCount =\n (options.source ? 1 : 0) +\n (options.map ? 1 : 0) +\n (options.mapKey ? 1 : 0);\n if (sourceCount === 0) {\n throw new Error(\n \"TilemapComponent requires one of `source`, `map`, or `mapKey`.\",\n );\n }\n\n if (options.source) {\n this.mapKey = options.source.path;\n const data = Assets.get<TiledMapData>(options.source.path);\n if (!data) {\n throw new Error(\n `TilemapComponent: source \"${options.source.path}\" is not loaded. Add it to scene preload.`,\n );\n }\n this._tiledMap = data;\n } else if (options.mapKey) {\n this.mapKey = options.mapKey;\n const data = Assets.get<TiledMapData>(options.mapKey);\n if (!data) {\n throw new Error(\n `TilemapComponent: map \"${options.mapKey}\" is not loaded. Add it to scene preload.`,\n );\n }\n this._tiledMap = data;\n } else {\n this.mapKey = null;\n this._tiledMap = options.map!;\n }\n\n this.data = toTilemapData(this._tiledMap);\n this.layerNames = options.layers;\n this.renderLayerName = options.layer ?? \"default\";\n this._explicitKeyPrefix = options.keyPrefix;\n this.keyPrefix = options.keyPrefix ?? this.mapKey;\n this.container = new Container();\n }\n\n onAdd(): void {\n const tilemapLayers = createTilemapLayers(this._tiledMap, this.layerNames);\n for (const layer of tilemapLayers) {\n this.container.addChild(layer);\n }\n\n const renderLayer = this.use(SceneRenderTreeKey).get(this.renderLayerName);\n renderLayer.container.addChild(this.container);\n }\n\n onDestroy(): void {\n this.container.removeFromParent();\n this.container.destroy({ children: true });\n }\n\n serialize(): TilemapComponentData | null {\n if (!this.mapKey) {\n console.warn(\n `TilemapComponent on \"${this.entity?.name}\": created with a TiledMapData object. ` +\n `Use { source } or { mapKey } for save/load support.`,\n );\n return null;\n }\n return {\n mapKey: this.mapKey,\n layer: this.renderLayerName,\n ...(this.layerNames && { layers: this.layerNames }),\n ...(this._explicitKeyPrefix !== undefined && {\n keyPrefix: this._explicitKeyPrefix,\n }),\n };\n }\n\n static fromSnapshot(data: TilemapComponentData): TilemapComponent {\n return new TilemapComponent({\n mapKey: data.mapKey,\n layer: data.layer,\n ...(data.layers && { layers: data.layers }),\n ...(data.keyPrefix !== undefined && { keyPrefix: data.keyPrefix }),\n });\n }\n\n /** Map width in pixels. */\n get widthPx(): number {\n return this.data.width * this.data.tileWidth;\n }\n\n /** Map height in pixels. */\n get heightPx(): number {\n return this.data.height * this.data.tileHeight;\n }\n\n /** Tile width in pixels. */\n get tileWidth(): number {\n return this.data.tileWidth;\n }\n\n /** Tile height in pixels. */\n get tileHeight(): number {\n return this.data.tileHeight;\n }\n\n /**\n * Returns the tile GID at a world position, accounting for entity Transform offset.\n * Returns null if the position is outside the map or the tile is empty.\n */\n getTileAt(\n worldX: number,\n worldY: number,\n layerName?: string,\n ): number | null {\n const transform = this.entity.tryGet(Transform);\n const offsetX = transform ? transform.position.x : 0;\n const offsetY = transform ? transform.position.y : 0;\n const localX = worldX - offsetX;\n const localY = worldY - offsetY;\n\n const col = Math.floor(localX / this.data.tileWidth);\n const row = Math.floor(localY / this.data.tileHeight);\n\n if (col < 0 || col >= this.data.width) return null;\n if (row < 0 || row >= this.data.height) return null;\n\n const layers = layerName\n ? this.data.tileLayers.filter((l) => l.name === layerName)\n : this.data.tileLayers;\n\n // Return first non-zero GID found (from last layer to first for top-most)\n for (let i = layers.length - 1; i >= 0; i--) {\n const layer = layers[i]!;\n const gid = layer.data[row * layer.width + col];\n if (gid !== undefined && gid !== 0) return gid;\n }\n\n return null;\n }\n\n /** Extract physics-agnostic collision shapes from object layers. */\n getCollisionShapes(objectLayerName?: string): TilemapColliderConfig[] {\n return extractCollisionShapes(this.data, objectLayerName);\n }\n\n /** Objects from object layers grouped by `class ?? name`. Use a layer name to scope. */\n getObjects(objectLayerName?: string): Record<string, MapObject[]> {\n const filtered = objectLayerName\n ? this.data.objectLayers.filter((l) => l.name === objectLayerName)\n : this.data.objectLayers;\n\n const result: Record<string, MapObject[]> = {};\n\n for (const layer of filtered) {\n for (const obj of layer.objects) {\n const key = obj.class ?? obj.name;\n if (!result[key]) {\n result[key] = [];\n }\n result[key].push(obj);\n }\n }\n\n return result;\n }\n\n /** Flat list of every object across every object layer. Memoized — safe because parsed map data is immutable post-construction. */\n getAllObjects(): MapObject[] {\n if (this._allObjectsCache) return this._allObjectsCache;\n const result: MapObject[] = [];\n for (const layer of this.data.objectLayers) {\n for (const obj of layer.objects) result.push(obj);\n }\n this._allObjectsCache = result;\n return result;\n }\n\n /**\n * Iterate every object on the given layer (or every layer if omitted),\n * passing the auto-derived stable key alongside each object so callers can\n * spawn entities with `scene.spawn(Class, params, { key })`.\n *\n * Skips objects that don't have a key prefix (component constructed from raw\n * `map:` without `mapKey` or `keyPrefix`) — those callers should iterate\n * `getObjects` directly.\n */\n forEachObject(\n layerName: string | undefined,\n fn: (obj: MapObject, key: string) => void,\n ): void {\n if (this.keyPrefix === null) {\n throw new Error(\n \"TilemapComponent.forEachObject: cannot derive auto-keys without a `mapKey`, `source`, or explicit `keyPrefix`.\",\n );\n }\n const layers = layerName\n ? this.data.objectLayers.filter((l) => l.name === layerName)\n : this.data.objectLayers;\n for (const layer of layers) {\n for (const obj of layer.objects) {\n fn(obj, tiledObjectKey(this.keyPrefix, obj.id));\n }\n }\n }\n\n /** Auto-derived stable key for an object: `<keyPrefix>#object:<id>`. */\n objectKey(obj: MapObject): string {\n if (this.keyPrefix === null) {\n throw new Error(\n \"TilemapComponent.objectKey: cannot derive a key without a `mapKey`, `source`, or explicit `keyPrefix`.\",\n );\n }\n return tiledObjectKey(this.keyPrefix, obj.id);\n }\n\n /** Find an object by its Tiled `id`. Searches every object layer. */\n findObject(id: number): MapObject | undefined {\n for (const layer of this.data.objectLayers) {\n for (const obj of layer.objects) {\n if (obj.id === id) return obj;\n }\n }\n return undefined;\n }\n\n /** Find the first object with a matching `name`. Searches every object layer. */\n findObjectByName(name: string): MapObject | undefined {\n for (const layer of this.data.objectLayers) {\n for (const obj of layer.objects) {\n if (obj.name === name) return obj;\n }\n }\n return undefined;\n }\n\n /** Read a typed custom property off any tilemap object. */\n getProperty<T = unknown>(obj: MapObject, name: string): T | undefined {\n return getProperty<T>(obj, name);\n }\n\n /** Read an indexed property bag (`name[0]`, `name[1]`, ...) as an array. */\n getPropertyArray<T = unknown>(obj: MapObject, name: string): T[] {\n return getPropertyArray<T>(obj, name);\n }\n\n /**\n * Resolve a Tiled object-reference property to the actual object.\n * Auto-collects across every layer so callers don't have to.\n */\n resolveRef(obj: MapObject, propName: string): MapObject | undefined {\n return resolveObjectRef(obj, propName, this.getAllObjects());\n }\n\n /** Same as `resolveRef`, but for indexed object-reference arrays. */\n resolveRefArray(obj: MapObject, propName: string): MapObject[] {\n return resolveObjectRefArray(obj, propName, this.getAllObjects());\n }\n}\n","import { CompositeTilemap } from \"@pixi/tilemap\";\nimport { Assets, Texture, Rectangle } from \"pixi.js\";\nimport type {\n TiledMapData,\n TileLayer,\n TilesetRef,\n ObjectGroup,\n TileObject,\n} from \"./types.js\";\nimport type {\n TilemapData,\n TileLayerData,\n ObjectLayerData,\n MapObject,\n} from \"../types.js\";\n\n// ─── Generic adapter ────────────────────────────────────────────────\n\n/**\n * Convert Tiled JSON data to the generic TilemapData format.\n */\nexport function toTilemapData(map: TiledMapData): TilemapData {\n const tileLayers: TileLayerData[] = [];\n const objectLayers: ObjectLayerData[] = [];\n\n for (const layer of map.layers) {\n if (layer.type === \"tilelayer\") {\n tileLayers.push({\n name: layer.name,\n data: layer.data,\n width: layer.width,\n height: layer.height,\n visible: layer.visible,\n });\n } else if (layer.type === \"objectgroup\") {\n objectLayers.push({\n name: layer.name,\n objects: layer.objects.map(tiledObjectToMapObject),\n visible: layer.visible,\n });\n }\n }\n\n return {\n width: map.width,\n height: map.height,\n tileWidth: map.tilewidth,\n tileHeight: map.tileheight,\n tileLayers,\n objectLayers,\n };\n}\n\nfunction tiledObjectToMapObject(obj: TileObject): MapObject {\n const result: MapObject = {\n id: obj.id,\n name: obj.name,\n x: obj.x,\n y: obj.y,\n width: obj.width,\n height: obj.height,\n rotation: obj.rotation,\n visible: obj.visible,\n };\n\n const cls = obj.class ?? obj.type;\n if (cls) result.class = cls;\n if (obj.point === true) result.point = true;\n if (obj.polygon) result.polygon = obj.polygon;\n if (obj.properties) {\n result.properties = obj.properties.map((p) => ({\n name: p.name,\n type: p.type,\n value: p.value,\n }));\n }\n\n return result;\n}\n\n// ─── Tiled-specific rendering ───────────────────────────────────────\n\n/**\n * Resolve the tileset that owns a given global tile ID.\n * Tilesets are sorted by firstgid; we find the last tileset whose firstgid <= gid.\n */\nfunction findTileset(tilesets: TilesetRef[], gid: number): TilesetRef | null {\n let result: TilesetRef | null = null;\n for (const ts of tilesets) {\n if (ts.firstgid <= gid) {\n if (!result || ts.firstgid > result.firstgid) {\n result = ts;\n }\n }\n }\n return result;\n}\n\n/**\n * Resolve the texture for a tile given its GID and owning tileset.\n */\nfunction resolveTileTexture(\n gid: number,\n tileset: TilesetRef,\n): Texture | null {\n const data = tileset.data;\n if (!data) return null;\n const localId = gid - tileset.firstgid;\n\n if (data.tiles?.length) {\n // Collection-of-images tileset: look up texture by filename from cache\n const tileData = data.tiles[localId];\n if (!tileData?.image) return null;\n const filenameMatch = tileData.image.match(/[^/]*$/);\n const filename = filenameMatch?.[0];\n if (!filename) return null;\n const tex = Assets.get<Texture>(filename);\n return tex ?? null;\n }\n\n if (data.image) {\n // Single-image tileset: sub-textures were created by the loader\n const cacheKey = `${data.name}:${localId}`;\n const tex = Assets.get<Texture>(cacheKey);\n if (tex) return tex;\n\n // Fallback: create sub-texture on the fly from the base image\n const filenameMatch = data.image.match(/[^/]*$/);\n const filename = filenameMatch?.[0];\n if (!filename) return null;\n const baseTex = Assets.get<Texture>(filename);\n if (!baseTex) return null;\n\n const cols = data.columns;\n const tw = data.tilewidth;\n const th = data.tileheight;\n const margin = data.margin ?? 0;\n const spacing = data.spacing ?? 0;\n const col = localId % cols;\n const row = Math.floor(localId / cols);\n const x = margin + col * (tw + spacing);\n const y = margin + row * (th + spacing);\n\n return new Texture({\n source: baseTex.source,\n frame: new Rectangle(x, y, tw, th),\n });\n }\n\n return null;\n}\n\n/**\n * Build CompositeTilemap display objects from a parsed Tiled map.\n *\n * @param map - Parsed TiledMapData (with resolved tilesets).\n * @param layerNames - Optional filter: only process these tile layer names.\n * @returns Array of CompositeTilemap, one per tile layer.\n */\nexport function createTilemapLayers(\n map: TiledMapData,\n layerNames?: string[],\n): CompositeTilemap[] {\n const tileLayers = map.layers.filter(\n (l): l is TileLayer => l.type === \"tilelayer\",\n );\n\n const filtered = layerNames\n ? tileLayers.filter((l) => layerNames.includes(l.name))\n : tileLayers;\n\n return filtered.map((layer) => {\n const tilemap = new CompositeTilemap();\n const { data, width } = layer;\n\n for (let index = 0; index < data.length; index++) {\n const gid = data[index]!;\n if (gid === 0) continue;\n\n const tileset = findTileset(map.tilesets, gid);\n if (!tileset) {\n throw new Error(`No tileset found for tile GID ${gid}`);\n }\n\n const texture = resolveTileTexture(gid, tileset);\n if (!texture) {\n throw new Error(\n `Could not resolve texture for tile GID ${gid} in tileset \"${tileset.data?.name}\"`,\n );\n }\n\n const x = index % width;\n const y = Math.floor(index / width);\n tilemap.tile(texture, x * map.tilewidth, y * map.tileheight);\n }\n\n return tilemap;\n });\n}\n\n/**\n * Extract objects from Tiled object layers, grouped by class/type/name.\n *\n * @param map - Parsed TiledMapData.\n * @param objectLayerName - Optional: only extract from this layer.\n * @returns Record mapping class/type/name to arrays of TileObject.\n */\nexport function extractObjects(\n map: TiledMapData,\n objectLayerName?: string,\n): Record<string, TileObject[]> {\n const objectLayers = map.layers.filter(\n (l): l is ObjectGroup => l.type === \"objectgroup\",\n );\n\n const filtered = objectLayerName\n ? objectLayers.filter((l) => l.name === objectLayerName)\n : objectLayers;\n\n const result: Record<string, TileObject[]> = {};\n\n for (const layer of filtered) {\n for (const obj of layer.objects) {\n const key = obj.class ?? obj.type ?? obj.name;\n if (!result[key]) {\n result[key] = [];\n }\n result[key].push(obj);\n }\n }\n\n return result;\n}\n","import type {\n TilemapData,\n MapObject,\n TilemapColliderConfig,\n RectColliderConfig,\n PolygonColliderConfig,\n} from \"./types.js\";\n\n/**\n * Extract physics-agnostic collision shapes from object layers.\n *\n * - Rectangle objects -> RectColliderConfig\n * - Polygon objects -> PolygonColliderConfig\n * - Point objects -> skipped (not collision shapes)\n *\n * @param map - Generic TilemapData.\n * @param objectLayerName - Optional: only extract from this layer.\n */\nexport function extractCollisionShapes(\n map: TilemapData,\n objectLayerName?: string,\n): TilemapColliderConfig[] {\n const filtered = objectLayerName\n ? map.objectLayers.filter((l) => l.name === objectLayerName)\n : map.objectLayers;\n\n const shapes: TilemapColliderConfig[] = [];\n\n for (const layer of filtered) {\n for (const obj of layer.objects) {\n const shape = objectToColliderConfig(obj);\n if (shape) shapes.push(shape);\n }\n }\n\n return shapes;\n}\n\n/**\n * Convert a single MapObject to a ColliderConfig.\n * Returns null for point objects (not collision shapes).\n */\nfunction objectToColliderConfig(obj: MapObject): TilemapColliderConfig | null {\n // Skip point objects\n if (obj.point) return null;\n\n if (obj.polygon) {\n const config: PolygonColliderConfig = {\n type: \"polygon\",\n x: obj.x,\n y: obj.y,\n vertices: obj.polygon.map((v) => ({ x: v.x, y: v.y })),\n };\n return config;\n }\n\n // Rectangle object\n const config: RectColliderConfig = {\n type: \"rect\",\n x: obj.x,\n y: obj.y,\n width: obj.width,\n height: obj.height,\n };\n return config;\n}\n","/**\n * Build the stable identity key for an entity sourced from a Tiled object.\n *\n * Format: `<prefix>#object:<id>`. The prefix is normally the map's asset path\n * (e.g. `/assets/dungeon/dungeon-map.json#object:42`); pass an explicit prefix\n * when distinguishing between multiple instances of the same map.\n *\n * Use this to thread Tiled object identity into `scene.spawn(Class, params, { key })`\n * so persistent stores (`defineSet<string>`, `defineMap<string, T>`) can key off\n * authored level content without each game inventing its own naming scheme.\n */\nexport function tiledObjectKey(prefix: string, objectId: number): string {\n return `${prefix}#object:${objectId}`;\n}\n","import type { HasProperties, MapObject } from \"./types.js\";\n\n/**\n * Get a single property value by name.\n * Returns `undefined` if the property is not found.\n */\nexport function getProperty<T = unknown>(\n obj: HasProperties,\n name: string,\n): T | undefined {\n const prop = obj.properties?.find((p) => p.name === name);\n return prop?.value as T | undefined;\n}\n\n/**\n * Get a pseudo-array of property values.\n *\n * Tiled doesn't support array properties natively, so a common convention\n * is to use indexed names like `spawns[0]`, `spawns[1]`, etc.\n * This function collects them into a proper array, preserving index order.\n */\nexport function getPropertyArray<T = unknown>(\n obj: HasProperties,\n name: string,\n): T[] {\n const pattern = new RegExp(`^${escapeRegex(name)}\\\\[(\\\\d+)\\\\]$`);\n const values: T[] = [];\n\n if (!obj.properties) return values;\n\n for (const prop of obj.properties) {\n const match = prop.name.match(pattern);\n if (match) {\n const index = Number.parseInt(match[1]!, 10);\n values[index] = prop.value as T;\n }\n }\n\n return values;\n}\n\n/**\n * Resolve a property of `type: \"object\"` (an ID reference) to the actual MapObject.\n * Returns `undefined` if the property doesn't exist or the referenced object isn't found.\n */\nexport function resolveObjectRef(\n obj: HasProperties,\n propName: string,\n allObjects: MapObject[],\n): MapObject | undefined {\n const id = getProperty<number>(obj, propName);\n if (id === undefined) return undefined;\n return allObjects.find((o) => o.id === id);\n}\n\n/**\n * Resolve a pseudo-array of object ID references to actual MapObjects.\n * Uses the `name[0]`, `name[1]` convention.\n */\nexport function resolveObjectRefArray(\n obj: HasProperties,\n propName: string,\n allObjects: MapObject[],\n): MapObject[] {\n const ids = getPropertyArray<number>(obj, propName);\n return ids\n .map((id) => allObjects.find((o) => o.id === id))\n .filter((o): o is MapObject => o !== undefined);\n}\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n","import { AssetHandle } from \"@yagejs/core\";\nimport type { TiledMapData } from \"./tiled/types.js\";\n\n/** Create a typed asset handle for a Tiled map JSON. */\nexport function tiledMap(path: string): AssetHandle<TiledMapData> {\n return new AssetHandle(\"tiledMap\", path);\n}\n","import type { ColliderConfig as PhysicsColliderConfig } from \"@yagejs/physics\";\nimport type { TilemapColliderConfig } from \"./types.js\";\n\n/**\n * Convert tilemap TilemapColliderConfig[] (top-left origin rects/polygons) into\n * physics-package ColliderConfig[] (center-origin shape + offset).\n */\nexport function toPhysicsColliders(\n shapes: TilemapColliderConfig[],\n): PhysicsColliderConfig[] {\n return shapes.map(toPhysicsCollider);\n}\n\nfunction toPhysicsCollider(config: TilemapColliderConfig): PhysicsColliderConfig {\n switch (config.type) {\n case \"polygon\":\n return {\n shape: {\n type: \"polygon\",\n vertices: config.vertices,\n },\n offset: { x: config.x, y: config.y },\n };\n case \"rect\":\n return {\n shape: { type: \"box\", width: config.width, height: config.height },\n offset: {\n x: config.x + config.width / 2,\n y: config.y + config.height / 2,\n },\n };\n }\n}\n"],"mappings":"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","names":["Assets","Transform","Assets","Assets","Texture","Rectangle","Assets","Texture","Rectangle","config","Assets","Transform","path","Assets","path"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yagejs/tilemap",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Tile-based map loading and rendering for YAGE",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"yage",
|
|
@@ -48,12 +48,12 @@
|
|
|
48
48
|
"clean": "rm -rf dist"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@yagejs/core": "^0.
|
|
52
|
-
"@yagejs/renderer": "^0.
|
|
51
|
+
"@yagejs/core": "^0.6.0",
|
|
52
|
+
"@yagejs/renderer": "^0.6.0",
|
|
53
53
|
"@pixi/tilemap": "^5.0.0",
|
|
54
54
|
"pixi.js": "^8.5.0"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@yagejs/physics": "^0.
|
|
57
|
+
"@yagejs/physics": "^0.6.0"
|
|
58
58
|
}
|
|
59
59
|
}
|