@rpgjs/tiledmap 5.0.0-alpha.14 → 5.0.0-alpha.16
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/client/index4.js +4 -1
- package/dist/server/index2.js +88 -33
- package/dist/server.d.ts +3 -3
- package/package.json +11 -11
- package/src/server.ts +154 -39
- package/src/tiled.ce +5 -1
package/dist/client/index4.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useProps, useDefineProps, signal, h, Container } from "canvasengine";
|
|
1
|
+
import { useProps, useDefineProps, signal, effect, h, Container } from "canvasengine";
|
|
2
2
|
import { EventLayerComponent } from "@rpgjs/client";
|
|
3
3
|
import { TiledMap } from "@canvasengine/presets";
|
|
4
4
|
function component($$props) {
|
|
@@ -7,6 +7,9 @@ function component($$props) {
|
|
|
7
7
|
var _a = defineProps(), data = _a.data, params = _a.params;
|
|
8
8
|
var map = signal(data());
|
|
9
9
|
var basePath = signal(params().basePath);
|
|
10
|
+
effect(function() {
|
|
11
|
+
map.set(data());
|
|
12
|
+
});
|
|
10
13
|
let $this = h(Container, null, h(TiledMap, { map, basePath, createLayersPerTilesZ: true, objectLayer: () => h(EventLayerComponent) }));
|
|
11
14
|
return $this;
|
|
12
15
|
}
|
package/dist/server/index2.js
CHANGED
|
@@ -5,15 +5,20 @@ const server = defineModule({
|
|
|
5
5
|
/**
|
|
6
6
|
* Hook called before map update
|
|
7
7
|
*
|
|
8
|
-
* @description Parses Tiled data and
|
|
9
|
-
*
|
|
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.
|
|
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
|
-
* //
|
|
25
|
-
*
|
|
26
|
-
*
|
|
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
|
-
|
|
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,80 @@ 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
|
+
var _a;
|
|
99
|
+
if (!(owner == null ? void 0 : owner.id) || !(map == null ? void 0 : map._blockedTiles)) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
const entity = (_a = map.physic) == null ? void 0 : _a.getEntityByUUID(owner.id);
|
|
103
|
+
if (!entity) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const blockedTiles = map._blockedTiles;
|
|
107
|
+
const tiledTileWidth = map._tiledTileWidth ?? 32;
|
|
108
|
+
const tiledTileHeight = map._tiledTileHeight ?? 32;
|
|
109
|
+
const physicsTileWidth = 32;
|
|
110
|
+
const physicsTileHeight = 32;
|
|
111
|
+
entity.canEnterTile(({ x, y }) => {
|
|
112
|
+
const tiledX = Math.floor(x * physicsTileWidth / tiledTileWidth);
|
|
113
|
+
const tiledY = Math.floor(y * physicsTileHeight / tiledTileHeight);
|
|
114
|
+
const tileKey = `${tiledX},${tiledY}`;
|
|
115
|
+
if (blockedTiles.has(tileKey)) {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
return true;
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
function applyTileCollisionToEntities(map) {
|
|
122
|
+
if (!(map == null ? void 0 : map._blockedTiles)) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if (map.players && typeof map.players === "function") {
|
|
126
|
+
const players = map.players();
|
|
127
|
+
if (players && typeof players === "object") {
|
|
128
|
+
for (const playerId in players) {
|
|
129
|
+
const player = players[playerId];
|
|
130
|
+
if (player) {
|
|
131
|
+
applyTileCollisionToEntity(player, map);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (map.events && typeof map.events === "function") {
|
|
137
|
+
const events = map.events();
|
|
138
|
+
if (events && typeof events === "object") {
|
|
139
|
+
for (const eventId in events) {
|
|
140
|
+
const event = events[eventId];
|
|
141
|
+
if (event) {
|
|
142
|
+
applyTileCollisionToEntity(event, map);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
93
148
|
export {
|
|
94
149
|
server as default
|
|
95
150
|
};
|
package/dist/server.d.ts
CHANGED
|
@@ -18,14 +18,14 @@ export interface RpgTiledMap extends RpgMap {
|
|
|
18
18
|
* Tiled Module for RPGJS
|
|
19
19
|
*
|
|
20
20
|
* @description This module extends RPGJS maps with Tiled functionality,
|
|
21
|
-
* allowing TMX map parsing and automatic
|
|
22
|
-
*
|
|
21
|
+
* allowing TMX map parsing and automatic tile-based collision detection
|
|
22
|
+
* using the physics engine's tile grid system
|
|
23
23
|
*
|
|
24
24
|
* ## Features
|
|
25
25
|
*
|
|
26
26
|
* - **Automatic parsing**: Parses TMX files from Tiled Map Editor
|
|
27
27
|
* - **Collision detection**: Scans all tiles to detect collisions
|
|
28
|
-
* - **
|
|
28
|
+
* - **Tile grid system**: Uses physics engine tile grid to block movement on collision tiles
|
|
29
29
|
* - **RpgMap extension**: Adds the `tiled` property to all RpgMap instances
|
|
30
30
|
*
|
|
31
31
|
* ## Usage
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rpgjs/tiledmap",
|
|
3
|
-
"version": "5.0.0-alpha.
|
|
3
|
+
"version": "5.0.0-alpha.16",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"exports": {
|
|
@@ -22,24 +22,24 @@
|
|
|
22
22
|
"license": "MIT",
|
|
23
23
|
"description": "RPGJS is a framework for creating RPG/MMORPG games",
|
|
24
24
|
"peerDependencies": {
|
|
25
|
-
"@canvasengine/presets": "2.0.0-beta.
|
|
26
|
-
"@rpgjs/client": "5.0.0-alpha.
|
|
27
|
-
"@rpgjs/common": "5.0.0-alpha.
|
|
28
|
-
"@rpgjs/server": "5.0.0-alpha.
|
|
29
|
-
"@rpgjs/vite": "5.0.0-alpha.
|
|
30
|
-
"canvasengine": "2.0.0-beta.
|
|
25
|
+
"@canvasengine/presets": "^2.0.0-beta.33",
|
|
26
|
+
"@rpgjs/client": "5.0.0-alpha.16",
|
|
27
|
+
"@rpgjs/common": "5.0.0-alpha.16",
|
|
28
|
+
"@rpgjs/server": "5.0.0-alpha.16",
|
|
29
|
+
"@rpgjs/vite": "5.0.0-alpha.16",
|
|
30
|
+
"canvasengine": "^2.0.0-beta.33"
|
|
31
31
|
},
|
|
32
32
|
"publishConfig": {
|
|
33
33
|
"access": "public"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@canvasengine/compiler": "2.0.0-beta.
|
|
37
|
-
"vite": "^
|
|
38
|
-
"vite-plugin-dts": "^4.5.
|
|
36
|
+
"@canvasengine/compiler": "^2.0.0-beta.33",
|
|
37
|
+
"vite": "^7.2.4",
|
|
38
|
+
"vite-plugin-dts": "^4.5.4"
|
|
39
39
|
},
|
|
40
40
|
"type": "module",
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@canvasengine/tiled": "2.0.0-beta.
|
|
42
|
+
"@canvasengine/tiled": "^2.0.0-beta.33"
|
|
43
43
|
},
|
|
44
44
|
"scripts": {
|
|
45
45
|
"dev": "vite build --watch",
|
package/src/server.ts
CHANGED
|
@@ -23,14 +23,14 @@ export interface RpgTiledMap extends RpgMap {
|
|
|
23
23
|
* Tiled Module for RPGJS
|
|
24
24
|
*
|
|
25
25
|
* @description This module extends RPGJS maps with Tiled functionality,
|
|
26
|
-
* allowing TMX map parsing and automatic
|
|
27
|
-
*
|
|
26
|
+
* allowing TMX map parsing and automatic tile-based collision detection
|
|
27
|
+
* using the physics engine's tile grid system
|
|
28
28
|
*
|
|
29
29
|
* ## Features
|
|
30
30
|
*
|
|
31
31
|
* - **Automatic parsing**: Parses TMX files from Tiled Map Editor
|
|
32
32
|
* - **Collision detection**: Scans all tiles to detect collisions
|
|
33
|
-
* - **
|
|
33
|
+
* - **Tile grid system**: Uses physics engine tile grid to block movement on collision tiles
|
|
34
34
|
* - **RpgMap extension**: Adds the `tiled` property to all RpgMap instances
|
|
35
35
|
*
|
|
36
36
|
* ## Usage
|
|
@@ -71,15 +71,20 @@ export default defineModule<RpgServer>({
|
|
|
71
71
|
/**
|
|
72
72
|
* Hook called before map update
|
|
73
73
|
*
|
|
74
|
-
* @description Parses Tiled data and
|
|
75
|
-
*
|
|
74
|
+
* @description Parses Tiled data and sets up tile-based collision detection
|
|
75
|
+
* using the physics engine's tile grid system instead of individual hitboxes.
|
|
76
76
|
*
|
|
77
77
|
* This method:
|
|
78
78
|
* 1. Parses TMX data with TiledParser
|
|
79
79
|
* 2. Creates a MapClass instance with parsed data
|
|
80
80
|
* 3. Attaches the Tiled instance to the RpgMap
|
|
81
81
|
* 4. Scans all tiles to detect collisions
|
|
82
|
-
* 5.
|
|
82
|
+
* 5. Stores blocked tiles in a Set for use with the physics engine tile grid
|
|
83
|
+
* 6. Configures tile dimensions for proper coordinate conversion
|
|
84
|
+
*
|
|
85
|
+
* The blocked tiles are used by the physics engine's `canEnterTile` hook
|
|
86
|
+
* to prevent entities from entering collision tiles, which is more efficient
|
|
87
|
+
* than creating individual hitboxes for each tile.
|
|
83
88
|
*
|
|
84
89
|
* @param mapData - Map data containing TMX information
|
|
85
90
|
* @param map - RpgMap instance to extend
|
|
@@ -87,20 +92,9 @@ export default defineModule<RpgServer>({
|
|
|
87
92
|
*
|
|
88
93
|
* @example
|
|
89
94
|
* ```ts
|
|
90
|
-
* //
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
* x: x * tileWidth, // X position in pixels
|
|
94
|
-
* y: y * tileHeight, // Y position in pixels
|
|
95
|
-
* width: tileWidth, // Tile width
|
|
96
|
-
* height: tileHeight, // Tile height
|
|
97
|
-
* properties: {
|
|
98
|
-
* type: 'collision', // Hitbox type
|
|
99
|
-
* tileX: x, // X position in tiles
|
|
100
|
-
* tileY: y, // Y position in tiles
|
|
101
|
-
* tileIndex: tileIndex // Tile index
|
|
102
|
-
* }
|
|
103
|
-
* }
|
|
95
|
+
* // Blocked tiles are stored as a Set with keys "x,y" (tile coordinates)
|
|
96
|
+
* // The physics engine will automatically check these tiles when entities
|
|
97
|
+
* // try to move, using the canEnterTile hook applied to all entities
|
|
104
98
|
* ```
|
|
105
99
|
*/
|
|
106
100
|
onBeforeUpdate<T = RpgMap>(mapData: any, map: T): T {
|
|
@@ -109,16 +103,24 @@ export default defineModule<RpgServer>({
|
|
|
109
103
|
// Attach Tiled instance to the map
|
|
110
104
|
(map as any).tiled = tiledMap;
|
|
111
105
|
|
|
112
|
-
// Initialize hitboxes array
|
|
106
|
+
// Initialize hitboxes array (for backward compatibility, but we won't populate it)
|
|
113
107
|
mapData.hitboxes = mapData.hitboxes || [];
|
|
114
108
|
mapData.width = tiledMap.widthPx;
|
|
115
109
|
mapData.height = tiledMap.heightPx;
|
|
116
110
|
|
|
111
|
+
// Store tile dimensions for coordinate conversion
|
|
112
|
+
const tileWidth = tiledMap.tilewidth;
|
|
113
|
+
const tileHeight = tiledMap.tileheight;
|
|
114
|
+
(map as any)._tiledTileWidth = tileWidth;
|
|
115
|
+
(map as any)._tiledTileHeight = tileHeight;
|
|
116
|
+
|
|
117
|
+
// Store blocked tiles in a Set for efficient lookup
|
|
118
|
+
// Key format: "x,y" where x and y are tile coordinates in Tiled's coordinate system
|
|
119
|
+
const blockedTiles = new Set<string>();
|
|
120
|
+
|
|
117
121
|
// Iterate through all map tiles to detect collisions
|
|
118
122
|
const mapWidth = tiledMap.width;
|
|
119
123
|
const mapHeight = tiledMap.height;
|
|
120
|
-
const tileWidth = tiledMap.tilewidth;
|
|
121
|
-
const tileHeight = tiledMap.tileheight;
|
|
122
124
|
|
|
123
125
|
// Iterate through each tile on the map
|
|
124
126
|
for (let y = 0; y < mapHeight; y++) {
|
|
@@ -130,27 +132,16 @@ export default defineModule<RpgServer>({
|
|
|
130
132
|
populateTiles: true,
|
|
131
133
|
});
|
|
132
134
|
|
|
133
|
-
// If tile has collision,
|
|
135
|
+
// If tile has collision, add it to the blocked tiles set
|
|
134
136
|
if (tileInfo.hasCollision) {
|
|
135
|
-
|
|
136
|
-
id: `collision_${x}_${y}`,
|
|
137
|
-
x: pixelX,
|
|
138
|
-
y: pixelY,
|
|
139
|
-
width: tileWidth,
|
|
140
|
-
height: tileHeight,
|
|
141
|
-
properties: {
|
|
142
|
-
type: "collision",
|
|
143
|
-
tileX: x,
|
|
144
|
-
tileY: y,
|
|
145
|
-
tileIndex: tileInfo.tileIndex,
|
|
146
|
-
},
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
mapData.hitboxes.push(hitbox);
|
|
137
|
+
blockedTiles.add(`${x},${y}`);
|
|
150
138
|
}
|
|
151
139
|
}
|
|
152
140
|
}
|
|
153
141
|
|
|
142
|
+
// Store blocked tiles on the map instance
|
|
143
|
+
(map as any)._blockedTiles = blockedTiles;
|
|
144
|
+
|
|
154
145
|
for (let obj of mapData.parsedMap.objects) {
|
|
155
146
|
if (obj.point) {
|
|
156
147
|
mapData.events = mapData.events
|
|
@@ -167,7 +158,131 @@ export default defineModule<RpgServer>({
|
|
|
167
158
|
.filter((e) => e !== null);
|
|
168
159
|
}
|
|
169
160
|
}
|
|
161
|
+
|
|
162
|
+
// Apply tile collision to all existing entities after a short delay
|
|
163
|
+
// to ensure physics entities are created
|
|
164
|
+
setTimeout(() => {
|
|
165
|
+
applyTileCollisionToEntities(map as any);
|
|
166
|
+
}, 0);
|
|
167
|
+
|
|
170
168
|
return map;
|
|
171
169
|
},
|
|
172
170
|
},
|
|
171
|
+
player: {
|
|
172
|
+
/**
|
|
173
|
+
* Hook called when a player joins a map
|
|
174
|
+
*
|
|
175
|
+
* @description Applies tile-based collision detection to the player's physics entity
|
|
176
|
+
* using the blocked tiles stored on the map
|
|
177
|
+
*
|
|
178
|
+
* @param player - The player instance
|
|
179
|
+
* @param map - The map instance
|
|
180
|
+
*/
|
|
181
|
+
onJoinMap(player: any, map: any) {
|
|
182
|
+
// Apply tile collision after a short delay to ensure physics entity is created
|
|
183
|
+
setTimeout(() => {
|
|
184
|
+
applyTileCollisionToEntity(player, map);
|
|
185
|
+
}, 0);
|
|
186
|
+
},
|
|
187
|
+
},
|
|
173
188
|
});
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Applies tile-based collision detection to a single entity
|
|
192
|
+
*
|
|
193
|
+
* @description This function sets up the `canEnterTile` hook on an entity's physics body
|
|
194
|
+
* to prevent movement into blocked tiles. It converts tile coordinates from the physics
|
|
195
|
+
* engine's coordinate system (based on default 32x32 tiles) to Tiled's coordinate system.
|
|
196
|
+
*
|
|
197
|
+
* @param owner - The owner object (player or event) that has a physics entity
|
|
198
|
+
* @param map - The map instance containing blocked tiles
|
|
199
|
+
*
|
|
200
|
+
* @example
|
|
201
|
+
* ```ts
|
|
202
|
+
* // This is called automatically when a player joins a map or an event is created
|
|
203
|
+
* // The function checks if the tile the entity is trying to enter is in the
|
|
204
|
+
* // blocked tiles set, converting coordinates as needed
|
|
205
|
+
* ```
|
|
206
|
+
*/
|
|
207
|
+
function applyTileCollisionToEntity(owner: any, map: any) {
|
|
208
|
+
if (!owner?.id || !map?._blockedTiles) {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const entity = map.physic?.getEntityByUUID(owner.id);
|
|
213
|
+
if (!entity) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const blockedTiles = map._blockedTiles as Set<string>;
|
|
218
|
+
const tiledTileWidth = map._tiledTileWidth ?? 32;
|
|
219
|
+
const tiledTileHeight = map._tiledTileHeight ?? 32;
|
|
220
|
+
|
|
221
|
+
// Physics engine uses default 32x32 tiles, but Tiled may have different dimensions
|
|
222
|
+
// We need to convert physics engine tile coordinates to Tiled tile coordinates
|
|
223
|
+
const physicsTileWidth = 32; // Default physics engine tile width
|
|
224
|
+
const physicsTileHeight = 32; // Default physics engine tile height
|
|
225
|
+
|
|
226
|
+
// Apply canEnterTile hook to the entity
|
|
227
|
+
entity.canEnterTile(({ x, y }) => {
|
|
228
|
+
// x, y are tile coordinates from the physics engine (based on 32x32 tiles)
|
|
229
|
+
// Convert to Tiled tile coordinates
|
|
230
|
+
const tiledX = Math.floor((x * physicsTileWidth) / tiledTileWidth);
|
|
231
|
+
const tiledY = Math.floor((y * physicsTileHeight) / tiledTileHeight);
|
|
232
|
+
|
|
233
|
+
// Check if this tile is blocked
|
|
234
|
+
const tileKey = `${tiledX},${tiledY}`;
|
|
235
|
+
if (blockedTiles.has(tileKey)) {
|
|
236
|
+
return false; // Block movement into this tile
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return true; // Allow movement
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Applies tile-based collision detection to all existing entities on a map
|
|
245
|
+
*
|
|
246
|
+
* @description This function iterates through all players and events on the map
|
|
247
|
+
* and applies the tile collision hook to each one's physics entity. This is useful
|
|
248
|
+
* when setting up the map for the first time or when entities already exist before
|
|
249
|
+
* the map is loaded.
|
|
250
|
+
*
|
|
251
|
+
* @param map - The map instance containing blocked tiles
|
|
252
|
+
*
|
|
253
|
+
* @example
|
|
254
|
+
* ```ts
|
|
255
|
+
* // Called automatically in onBeforeUpdate to apply collision to existing entities
|
|
256
|
+
* ```
|
|
257
|
+
*/
|
|
258
|
+
function applyTileCollisionToEntities(map: any) {
|
|
259
|
+
if (!map?._blockedTiles) {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Apply to all players
|
|
264
|
+
if (map.players && typeof map.players === 'function') {
|
|
265
|
+
const players = map.players();
|
|
266
|
+
if (players && typeof players === 'object') {
|
|
267
|
+
for (const playerId in players) {
|
|
268
|
+
const player = players[playerId];
|
|
269
|
+
if (player) {
|
|
270
|
+
applyTileCollisionToEntity(player, map);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Apply to all events
|
|
277
|
+
if (map.events && typeof map.events === 'function') {
|
|
278
|
+
const events = map.events();
|
|
279
|
+
if (events && typeof events === 'object') {
|
|
280
|
+
for (const eventId in events) {
|
|
281
|
+
const event = events[eventId];
|
|
282
|
+
if (event) {
|
|
283
|
+
applyTileCollisionToEntity(event, map);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
package/src/tiled.ce
CHANGED
|
@@ -5,10 +5,14 @@
|
|
|
5
5
|
<script>
|
|
6
6
|
import { EventLayerComponent } from "@rpgjs/client";
|
|
7
7
|
import { TiledMap } from "@canvasengine/presets";
|
|
8
|
-
import { signal } from "canvasengine";
|
|
8
|
+
import { signal, effect } from "canvasengine";
|
|
9
9
|
|
|
10
10
|
const { data, params } = defineProps()
|
|
11
11
|
|
|
12
12
|
const map = signal(data())
|
|
13
13
|
const basePath = signal(params().basePath)
|
|
14
|
+
|
|
15
|
+
effect(() => {
|
|
16
|
+
map.set(data())
|
|
17
|
+
})
|
|
14
18
|
</script>
|