@rpgjs/tiledmap 5.0.0-alpha.4 → 5.0.0-alpha.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,18 @@
1
+ import { useProps, useDefineProps, signal, effect, h, Container } from "canvasengine";
2
+ import { EventLayerComponent } from "@rpgjs/client";
3
+ import { TiledMap } from "@canvasengine/presets";
4
+ function component($$props) {
5
+ useProps($$props);
6
+ const defineProps = useDefineProps($$props);
7
+ var _a = defineProps(), data = _a.data, params = _a.params;
8
+ var map = signal(data());
9
+ var basePath = signal(params().basePath);
10
+ effect(function() {
11
+ map.set(data());
12
+ });
13
+ let $this = h(Container, null, h(TiledMap, { map, basePath, createLayersPerTilesZ: true, objectLayer: () => h(EventLayerComponent) }));
14
+ return $this;
15
+ }
16
+ export {
17
+ component as default
18
+ };
@@ -0,0 +1,95 @@
1
+ import { MapClass } from "./index3.js";
2
+ function prepareTiledPhysicsData(mapData, map) {
3
+ if (!mapData?.parsedMap) {
4
+ return;
5
+ }
6
+ const tiledMap = new MapClass(mapData.parsedMap);
7
+ map.tiled = tiledMap;
8
+ mapData.hitboxes = mapData.hitboxes || [];
9
+ mapData.width = tiledMap.widthPx;
10
+ mapData.height = tiledMap.heightPx;
11
+ map._tiledTileWidth = tiledMap.tilewidth;
12
+ map._tiledTileHeight = tiledMap.tileheight;
13
+ map._blockedTiles = collectBlockedTiles(tiledMap);
14
+ }
15
+ function attachTiledCollisionToEntity(owner, map) {
16
+ if (!owner?.id || !map?._blockedTiles) {
17
+ return;
18
+ }
19
+ const entity = map.physic?.getEntityByUUID(owner.id);
20
+ if (!entity || typeof entity.canEnterTile !== "function") {
21
+ return;
22
+ }
23
+ const unsubscribers = ensureUnsubscribers(map);
24
+ const previousUnsubscribe = unsubscribers.get(owner.id);
25
+ if (previousUnsubscribe) {
26
+ previousUnsubscribe();
27
+ unsubscribers.delete(owner.id);
28
+ }
29
+ const blockedTiles = map._blockedTiles;
30
+ const tiledTileWidth = map._tiledTileWidth ?? 32;
31
+ const tiledTileHeight = map._tiledTileHeight ?? 32;
32
+ const physicsTileWidth = 32;
33
+ const physicsTileHeight = 32;
34
+ const unsubscribe = entity.canEnterTile(({ x, y }) => {
35
+ const tiledX = Math.floor(x * physicsTileWidth / tiledTileWidth);
36
+ const tiledY = Math.floor(y * physicsTileHeight / tiledTileHeight);
37
+ return !blockedTiles.has(`${tiledX},${tiledY}`);
38
+ });
39
+ unsubscribers.set(owner.id, unsubscribe);
40
+ }
41
+ function detachTiledCollisionFromEntity(owner, map) {
42
+ if (!owner?.id) {
43
+ return;
44
+ }
45
+ const unsubscribers = map._tiledCollisionUnsubscribers;
46
+ if (!unsubscribers) {
47
+ return;
48
+ }
49
+ const unsubscribe = unsubscribers.get(owner.id);
50
+ if (!unsubscribe) {
51
+ return;
52
+ }
53
+ unsubscribe();
54
+ unsubscribers.delete(owner.id);
55
+ }
56
+ function resetTiledCollisionHandlers(map) {
57
+ const unsubscribers = map._tiledCollisionUnsubscribers;
58
+ if (unsubscribers) {
59
+ for (const unsubscribe of unsubscribers.values()) {
60
+ unsubscribe();
61
+ }
62
+ unsubscribers.clear();
63
+ }
64
+ map._blockedTiles = void 0;
65
+ map._tiledTileWidth = void 0;
66
+ map._tiledTileHeight = void 0;
67
+ }
68
+ function collectBlockedTiles(tiledMap) {
69
+ const blockedTiles = /* @__PURE__ */ new Set();
70
+ const mapWidth = tiledMap.width;
71
+ const mapHeight = tiledMap.height;
72
+ const tileWidth = tiledMap.tilewidth;
73
+ const tileHeight = tiledMap.tileheight;
74
+ for (let y = 0; y < mapHeight; y++) {
75
+ for (let x = 0; x < mapWidth; x++) {
76
+ const tileInfo = tiledMap.getTileByPosition(x * tileWidth, y * tileHeight, [0, 0], {
77
+ populateTiles: true
78
+ });
79
+ if (tileInfo.hasCollision) {
80
+ blockedTiles.add(`${x},${y}`);
81
+ }
82
+ }
83
+ }
84
+ return blockedTiles;
85
+ }
86
+ function ensureUnsubscribers(map) {
87
+ map._tiledCollisionUnsubscribers = map._tiledCollisionUnsubscribers || /* @__PURE__ */ new Map();
88
+ return map._tiledCollisionUnsubscribers;
89
+ }
90
+ export {
91
+ attachTiledCollisionToEntity,
92
+ detachTiledCollisionFromEntity,
93
+ prepareTiledPhysicsData,
94
+ resetTiledCollisionHandlers
95
+ };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export declare function provideTiledMap(options: {
2
2
  basePath: string;
3
+ onLoadMap?: (map: string) => Promise<void>;
3
4
  }): any;
@@ -0,0 +1,17 @@
1
+ import { MapClass } from '@canvasengine/tiled';
2
+ type AnyMap = {
3
+ tiled?: MapClass;
4
+ physic?: {
5
+ getEntityByUUID(id: string): any;
6
+ };
7
+ _blockedTiles?: Set<string>;
8
+ _tiledTileWidth?: number;
9
+ _tiledTileHeight?: number;
10
+ _tiledCollisionUnsubscribers?: Map<string, () => void>;
11
+ };
12
+ export declare function prepareTiledPhysicsData(mapData: any, map: AnyMap): void;
13
+ export declare function applyTiledPointEvents(mapData: any): void;
14
+ export declare function attachTiledCollisionToEntity(owner: any, map: AnyMap): void;
15
+ export declare function detachTiledCollisionFromEntity(owner: any, map: AnyMap): void;
16
+ export declare function resetTiledCollisionHandlers(map: AnyMap): void;
17
+ export {};
@@ -1,6 +1,6 @@
1
1
  import server from "./index2.js";
2
2
  import { createModule } from "@rpgjs/common";
3
- import "@rpgjs/tiled";
3
+ import "./index3.js";
4
4
  const client = null;
5
5
  const provideLoadMap = null;
6
6
  function provideTiledMap(options) {
@@ -9,7 +9,7 @@ function provideTiledMap(options) {
9
9
  server,
10
10
  client
11
11
  },
12
- provideLoadMap == null ? void 0 : provideLoadMap()
12
+ provideLoadMap?.()
13
13
  ]);
14
14
  }
15
15
  export {
@@ -1,92 +1,25 @@
1
- import { MapClass } from "@rpgjs/tiled";
2
1
  import { defineModule } from "@rpgjs/common";
2
+ import { resetTiledCollisionHandlers, detachTiledCollisionFromEntity, attachTiledCollisionToEntity, prepareTiledPhysicsData, applyTiledPointEvents } from "./index4.js";
3
3
  const server = defineModule({
4
4
  map: {
5
- /**
6
- * Hook called before map update
7
- *
8
- * @description Parses Tiled data and creates collision hitboxes
9
- * automatically by iterating through all tiles on the map.
10
- *
11
- * This method:
12
- * 1. Parses TMX data with TiledParser
13
- * 2. Creates a MapClass instance with parsed data
14
- * 3. Attaches the Tiled instance to the RpgMap
15
- * 4. Scans all tiles to detect collisions
16
- * 5. Automatically creates hitboxes for each collision tile
17
- *
18
- * @param mapData - Map data containing TMX information
19
- * @param map - RpgMap instance to extend
20
- * @returns The modified map instance with tiled property
21
- *
22
- * @example
23
- * ```ts
24
- * // Created hitboxes will have this structure:
25
- * {
26
- * id: 'collision_x_y', // Unique identifier
27
- * x: x * tileWidth, // X position in pixels
28
- * y: y * tileHeight, // Y position in pixels
29
- * width: tileWidth, // Tile width
30
- * height: tileHeight, // Tile height
31
- * properties: {
32
- * type: 'collision', // Hitbox type
33
- * tileX: x, // X position in tiles
34
- * tileY: y, // Y position in tiles
35
- * tileIndex: tileIndex // Tile index
36
- * }
37
- * }
38
- * ```
39
- */
40
5
  onBeforeUpdate(mapData, map) {
41
- const tiledMap = new MapClass(mapData.parsedMap);
42
- map.tiled = tiledMap;
43
- mapData.hitboxes = mapData.hitboxes || [];
44
- mapData.width = tiledMap.widthPx;
45
- mapData.height = tiledMap.heightPx;
46
- const mapWidth = tiledMap.width;
47
- const mapHeight = tiledMap.height;
48
- const tileWidth = tiledMap.tilewidth;
49
- const tileHeight = tiledMap.tileheight;
50
- for (let y = 0; y < mapHeight; y++) {
51
- for (let x = 0; x < mapWidth; x++) {
52
- const pixelX = x * tileWidth;
53
- const pixelY = y * tileHeight;
54
- const tileInfo = tiledMap.getTileByPosition(pixelX, pixelY, [0, 0], {
55
- populateTiles: true
56
- });
57
- if (tileInfo.hasCollision) {
58
- const hitbox = {
59
- id: `collision_${x}_${y}`,
60
- x: pixelX,
61
- y: pixelY,
62
- width: tileWidth,
63
- height: tileHeight,
64
- properties: {
65
- type: "collision",
66
- tileX: x,
67
- tileY: y,
68
- tileIndex: tileInfo.tileIndex
69
- }
70
- };
71
- mapData.hitboxes.push(hitbox);
72
- }
73
- }
74
- }
75
- for (let obj of mapData.parsedMap.objects) {
76
- if (obj.point) {
77
- mapData.events = mapData.events.map((e) => {
78
- if (e.name === obj.name) {
79
- return {
80
- event: e,
81
- x: obj.x,
82
- y: obj.y
83
- };
84
- }
85
- return e;
86
- }).filter((e) => e !== null);
87
- }
88
- }
6
+ prepareTiledPhysicsData(mapData, map);
7
+ applyTiledPointEvents(mapData);
89
8
  return map;
9
+ },
10
+ onPhysicsInit(map, context) {
11
+ if (!map?._blockedTiles || !map?.tiled) {
12
+ prepareTiledPhysicsData(context?.mapData, map);
13
+ }
14
+ },
15
+ onPhysicsEntityAdd(map, context) {
16
+ attachTiledCollisionToEntity(context?.owner, map);
17
+ },
18
+ onPhysicsEntityRemove(map, context) {
19
+ detachTiledCollisionFromEntity(context?.owner, map);
20
+ },
21
+ onPhysicsReset(map) {
22
+ resetTiledCollisionHandlers(map);
90
23
  }
91
24
  }
92
25
  });