@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.
- package/dist/client/index.js +12 -7
- package/dist/client/index2.js +16 -1
- package/dist/client/index3.js +5218 -12
- package/dist/client/index4.js +18 -0
- package/dist/client/index5.js +95 -0
- package/dist/index.d.ts +1 -0
- package/dist/physics.d.ts +17 -0
- package/dist/server/index.js +2 -2
- package/dist/server/index2.js +17 -84
- package/dist/server/index3.js +4943 -0
- package/dist/server/index4.js +117 -0
- package/dist/server.d.ts +1 -54
- package/package.json +13 -11
- package/src/client.ts +23 -3
- package/src/index.ts +27 -18
- package/src/physics.ts +143 -0
- package/src/server.ts +24 -156
- package/src/tiled.ce +8 -3
|
@@ -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
|
@@ -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 {};
|
package/dist/server/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import server from "./index2.js";
|
|
2
2
|
import { createModule } from "@rpgjs/common";
|
|
3
|
-
import "
|
|
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
|
|
12
|
+
provideLoadMap?.()
|
|
13
13
|
]);
|
|
14
14
|
}
|
|
15
15
|
export {
|
package/dist/server/index2.js
CHANGED
|
@@ -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
|
-
|
|
42
|
-
|
|
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
|
});
|