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

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
+ };
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;
@@ -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,19 +1,24 @@
1
- import { MapClass } from "@rpgjs/tiled";
1
+ import { MapClass } from "./index3.js";
2
2
  import { defineModule } from "@rpgjs/common";
3
3
  const server = defineModule({
4
4
  map: {
5
5
  /**
6
6
  * Hook called before map update
7
7
  *
8
- * @description Parses Tiled data and creates collision hitboxes
9
- * automatically by iterating through all tiles on the map.
8
+ * @description Parses Tiled data and sets up tile-based collision detection
9
+ * using the physics engine's tile grid system instead of individual hitboxes.
10
10
  *
11
11
  * This method:
12
12
  * 1. Parses TMX data with TiledParser
13
13
  * 2. Creates a MapClass instance with parsed data
14
14
  * 3. Attaches the Tiled instance to the RpgMap
15
15
  * 4. Scans all tiles to detect collisions
16
- * 5. Automatically creates hitboxes for each collision tile
16
+ * 5. Stores blocked tiles in a Set for use with the physics engine tile grid
17
+ * 6. Configures tile dimensions for proper coordinate conversion
18
+ *
19
+ * The blocked tiles are used by the physics engine's `canEnterTile` hook
20
+ * to prevent entities from entering collision tiles, which is more efficient
21
+ * than creating individual hitboxes for each tile.
17
22
  *
18
23
  * @param mapData - Map data containing TMX information
19
24
  * @param map - RpgMap instance to extend
@@ -21,20 +26,9 @@ const server = defineModule({
21
26
  *
22
27
  * @example
23
28
  * ```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
- * }
29
+ * // Blocked tiles are stored as a Set with keys "x,y" (tile coordinates)
30
+ * // The physics engine will automatically check these tiles when entities
31
+ * // try to move, using the canEnterTile hook applied to all entities
38
32
  * ```
39
33
  */
40
34
  onBeforeUpdate(mapData, map) {
@@ -43,10 +37,13 @@ const server = defineModule({
43
37
  mapData.hitboxes = mapData.hitboxes || [];
44
38
  mapData.width = tiledMap.widthPx;
45
39
  mapData.height = tiledMap.heightPx;
46
- const mapWidth = tiledMap.width;
47
- const mapHeight = tiledMap.height;
48
40
  const tileWidth = tiledMap.tilewidth;
49
41
  const tileHeight = tiledMap.tileheight;
42
+ map._tiledTileWidth = tileWidth;
43
+ map._tiledTileHeight = tileHeight;
44
+ const blockedTiles = /* @__PURE__ */ new Set();
45
+ const mapWidth = tiledMap.width;
46
+ const mapHeight = tiledMap.height;
50
47
  for (let y = 0; y < mapHeight; y++) {
51
48
  for (let x = 0; x < mapWidth; x++) {
52
49
  const pixelX = x * tileWidth;
@@ -55,23 +52,11 @@ const server = defineModule({
55
52
  populateTiles: true
56
53
  });
57
54
  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);
55
+ blockedTiles.add(`${x},${y}`);
72
56
  }
73
57
  }
74
58
  }
59
+ map._blockedTiles = blockedTiles;
75
60
  for (let obj of mapData.parsedMap.objects) {
76
61
  if (obj.point) {
77
62
  mapData.events = mapData.events.map((e) => {
@@ -86,10 +71,79 @@ const server = defineModule({
86
71
  }).filter((e) => e !== null);
87
72
  }
88
73
  }
74
+ setTimeout(() => {
75
+ applyTileCollisionToEntities(map);
76
+ }, 0);
89
77
  return map;
90
78
  }
79
+ },
80
+ player: {
81
+ /**
82
+ * Hook called when a player joins a map
83
+ *
84
+ * @description Applies tile-based collision detection to the player's physics entity
85
+ * using the blocked tiles stored on the map
86
+ *
87
+ * @param player - The player instance
88
+ * @param map - The map instance
89
+ */
90
+ onJoinMap(player, map) {
91
+ setTimeout(() => {
92
+ applyTileCollisionToEntity(player, map);
93
+ }, 0);
94
+ }
91
95
  }
92
96
  });
97
+ function applyTileCollisionToEntity(owner, map) {
98
+ if (!owner?.id || !map?._blockedTiles) {
99
+ return;
100
+ }
101
+ const entity = map.physic?.getEntityByUUID(owner.id);
102
+ if (!entity) {
103
+ return;
104
+ }
105
+ const blockedTiles = map._blockedTiles;
106
+ const tiledTileWidth = map._tiledTileWidth ?? 32;
107
+ const tiledTileHeight = map._tiledTileHeight ?? 32;
108
+ const physicsTileWidth = 32;
109
+ const physicsTileHeight = 32;
110
+ entity.canEnterTile(({ x, y }) => {
111
+ const tiledX = Math.floor(x * physicsTileWidth / tiledTileWidth);
112
+ const tiledY = Math.floor(y * physicsTileHeight / tiledTileHeight);
113
+ const tileKey = `${tiledX},${tiledY}`;
114
+ if (blockedTiles.has(tileKey)) {
115
+ return false;
116
+ }
117
+ return true;
118
+ });
119
+ }
120
+ function applyTileCollisionToEntities(map) {
121
+ if (!map?._blockedTiles) {
122
+ return;
123
+ }
124
+ if (map.players && typeof map.players === "function") {
125
+ const players = map.players();
126
+ if (players && typeof players === "object") {
127
+ for (const playerId in players) {
128
+ const player = players[playerId];
129
+ if (player) {
130
+ applyTileCollisionToEntity(player, map);
131
+ }
132
+ }
133
+ }
134
+ }
135
+ if (map.events && typeof map.events === "function") {
136
+ const events = map.events();
137
+ if (events && typeof events === "object") {
138
+ for (const eventId in events) {
139
+ const event = events[eventId];
140
+ if (event) {
141
+ applyTileCollisionToEntity(event, map);
142
+ }
143
+ }
144
+ }
145
+ }
146
+ }
93
147
  export {
94
148
  server as default
95
149
  };