kaplay-plugin-tiled 0.0.0 → 1.1.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/LICENSE +22 -0
- package/README.md +106 -0
- package/dist/plugin.cjs +2 -0
- package/dist/plugin.cjs.map +1 -0
- package/dist/plugin.d.cts +176 -0
- package/dist/plugin.d.mts +176 -0
- package/dist/plugin.d.ts +176 -0
- package/dist/plugin.mjs +265 -0
- package/dist/plugin.mjs.map +1 -0
- package/dist/plugin.umd.js +2 -0
- package/dist/plugin.umd.js.map +1 -0
- package/global.d.ts +7 -0
- package/global.js +1 -0
- package/package.json +98 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Menglin "Mark" Xu <mark@remarkablemark.org>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# kaplay-plugin-tiled
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/kaplay-plugin-tiled)
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/kaplay-plugin-tiled)
|
|
6
|
+
[](https://github.com/remarkablegames/kaplay-plugin-tiled/actions/workflows/build.yml)
|
|
7
|
+
[](https://codecov.io/gh/remarkablegames/kaplay-plugin-tiled)
|
|
8
|
+
|
|
9
|
+
[KAPLAY](https://kaplayjs.com/) plugin for loading finite orthogonal [Tiled](https://www.mapeditor.org/) JSON maps.
|
|
10
|
+
|
|
11
|
+
## Prerequisites
|
|
12
|
+
|
|
13
|
+
Install [kaplay](https://www.npmjs.com/package/kaplay):
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
npm install kaplay
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Install
|
|
20
|
+
|
|
21
|
+
[NPM](https://www.npmjs.com/package/kaplay-plugin-tiled):
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
npm install kaplay-plugin-tiled
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
[CDN](https://unpkg.com/browse/kaplay-plugin-tiled/):
|
|
28
|
+
|
|
29
|
+
```html
|
|
30
|
+
<script src="https://unpkg.com/kaplay-plugin-tiled@latest/dist/plugin.umd.js"></script>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Usage
|
|
34
|
+
|
|
35
|
+
Import the plugin:
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import kaplay from 'kaplay';
|
|
39
|
+
import { tiledPlugin } from 'kaplay-plugin-tiled';
|
|
40
|
+
|
|
41
|
+
const k = kaplay({
|
|
42
|
+
plugins: [tiledPlugin],
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Use the plugin:
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
import level from './level.json';
|
|
50
|
+
import tilesetUrl from './tileset.png';
|
|
51
|
+
|
|
52
|
+
k.loadSprite('tileset', tilesetUrl);
|
|
53
|
+
|
|
54
|
+
k.onLoad(() => {
|
|
55
|
+
k.addTiledMap(level, {
|
|
56
|
+
sprite: 'tileset',
|
|
57
|
+
objects: [
|
|
58
|
+
{
|
|
59
|
+
match: { properties: { collides: true } },
|
|
60
|
+
comps: ({ objectSize }) => [
|
|
61
|
+
k.area({
|
|
62
|
+
shape: new k.Rect(k.vec2(), objectSize.width, objectSize.height),
|
|
63
|
+
}),
|
|
64
|
+
k.body({ isStatic: true }),
|
|
65
|
+
],
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
If you use KAPLAY globals, load the ambient types explicitly:
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
import 'kaplay/global';
|
|
76
|
+
import 'kaplay-plugin-tiled/global';
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
This adds the ambient type for `addTiledMap(...)`. The runtime global still depends on KAPLAY's global setup.
|
|
80
|
+
|
|
81
|
+
The current implementation is intentionally small:
|
|
82
|
+
|
|
83
|
+
- finite orthogonal Tiled JSON only
|
|
84
|
+
- 1 tileset per map
|
|
85
|
+
- visible tile layers plus optional `tiles` and `objects` matchers for extra spawned components
|
|
86
|
+
|
|
87
|
+
To load the plugin using a script:
|
|
88
|
+
|
|
89
|
+
```html
|
|
90
|
+
<script src="https://unpkg.com/kaplay@latest/dist/kaplay.js"></script>
|
|
91
|
+
<script src="https://unpkg.com/kaplay-plugin-tiled@latest/dist/plugin.umd.js"></script>
|
|
92
|
+
|
|
93
|
+
<script>
|
|
94
|
+
const k = kaplay({
|
|
95
|
+
plugins: [KaplayPluginTiled.tiledPlugin],
|
|
96
|
+
});
|
|
97
|
+
</script>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Release
|
|
101
|
+
|
|
102
|
+
Release is automated with [Release Please](https://github.com/googleapis/release-please).
|
|
103
|
+
|
|
104
|
+
## License
|
|
105
|
+
|
|
106
|
+
[MIT](https://github.com/remarkablegames/kaplay-plugin-tiled/blob/master/LICENSE)
|
package/dist/plugin.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=2147483648,t=1073741824,n=536870912,r=t|-1610612736;function i(e,t){if(typeof t!=`string`)return t;let n=e.getAsset(t);if(!n)throw Error(`Tiled map asset "${t}" is not loaded.`);if(!n.data)throw Error(`Tiled map asset "${t}" is not ready yet.`);return n.data}function a(e){let t={};return e?.forEach(e=>{t[e.name]=e.value}),t}function o(e){return e.type===`objectgroup`}function s(e){return e.type===`tilelayer`}function c(e){return{data:e.data,height:e.height,name:e.name,opacity:e.opacity??1,type:`tilelayer`,visible:e.visible??!0,width:e.width,x:e.x??0,y:e.y??0,zIndex:0}}function l(e){return{name:e.name,objects:e.objects,type:`objectgroup`,visible:e.visible??!0,zIndex:0}}function u(i){return i===0?null:{gid:(i&~r)>>>0,flip:{diagonal:(i&n)!==0,horizontal:(i&e)!==0,vertical:(i&t)!==0}}}function d(e){return e.diagonal?e.horizontal&&e.vertical?{angle:270,flipX:!0,flipY:!1}:e.horizontal?{angle:270,flipX:!1,flipY:!1}:e.vertical?{angle:90,flipX:!1,flipY:!1}:{angle:270,flipX:!1,flipY:!0}:{angle:0,flipX:e.horizontal,flipY:e.vertical}}function f(e,t,n){let r=n-t.tileset.firstGid,i=r%t.tileset.columns,a=Math.floor(r/t.tileset.columns),o=t.tileset.margin+i*(t.tileset.tileWidth+t.tileset.spacing),s=t.tileset.margin+a*(t.tileset.tileHeight+t.tileset.spacing);return e.quad(o/t.tileset.imageWidth,s/t.tileset.imageHeight,t.tileset.tileWidth/t.tileset.imageWidth,t.tileset.tileHeight/t.tileset.imageHeight)}function p(e){return e.layerNames?.length?new Set(e.layerNames):null}function m(e,t){return e.tileset.tiles[t]}function h(e,t){return e?Object.entries(e).every(([e,n])=>t[e]===n):!0}function g(e,t){return e.gid!==void 0&&e.gid!==t.gid||e.tileId!==void 0&&e.tileId!==t.tileId||e.layer!==void 0&&e.layer!==t.layer?!1:h(e.properties,t.properties)}function _(e,t){return e.layer!==void 0&&e.layer!==t.layer||e.name!==void 0&&e.name!==t.name||e.type!==void 0&&e.type!==t.type?!1:h(e.properties,t.properties)}function v(e,t,n,r){return e.add([e.pos(0,0),e.z(t.zIndex),{draw:()=>{t.data.forEach((i,a)=>{let o=u(i);if(!o)return;let s=a%t.width,c=Math.floor(a/t.width),l=d(o.flip);e.drawSprite({anchor:`center`,angle:l.angle,flipX:l.flipX,flipY:l.flipY,opacity:t.opacity,pos:e.vec2((s+t.x)*n.tileWidth+n.tileset.tileWidth/2,(c+t.y)*n.tileHeight+n.tileset.tileHeight/2),quad:f(e,n,o.gid),sprite:r})})},id:`tiled-layer`}])}function y(e,t,n,r){let i=r.tiles;if(!i?.length)return[];let a=[];return t.data.forEach((r,o)=>{let s=u(r);if(!s)return;let c=m(n,s.gid),l=o%t.width,d=Math.floor(o/t.width),f={flip:s.flip,gid:s.gid,layer:t.name,pos:{x:(l+t.x)*n.tileWidth,y:(d+t.y)*n.tileHeight},properties:c?.properties??{},tileSize:{height:n.tileHeight,width:n.tileWidth},tileId:c?.tileId??s.gid-n.tileset.firstGid,tilePos:{x:l+t.x,y:d+t.y}};i.forEach(n=>{g(n.match,f)&&a.push(e.add([e.pos(f.pos.x,f.pos.y),e.anchor(`topleft`),e.z(t.zIndex),...n.comps(f)]))})}),a}function b(e,t,n){let r=n.objects;if(!r?.length)return[];let i=[];return t.visible&&t.objects.forEach(n=>{if(!n.visible)return;let o={id:n.id,layer:t.name,name:n.name,objectSize:{height:n.height,width:n.width},point:n.point??!1,pos:{x:n.x,y:n.y},properties:a(n.properties),rotation:n.rotation,type:n.type};r.forEach(n=>{_(n.match,o)&&i.push(e.add([e.pos(o.pos.x,o.pos.y),e.anchor(`topleft`),e.z(t.zIndex),...n.comps(o)]))})}),i}function x(e){if(e.orientation!==`orthogonal`)throw Error(`Unsupported Tiled orientation "${e.orientation}". Expected "orthogonal".`);if(e.infinite)throw Error(`Infinite Tiled maps are not supported.`);if(e.tilesets.length!==1)throw Error(`Exactly one Tiled tileset is required.`);let[t]=e.tilesets;if(t.columns<=0)throw Error(`Tiled tileset columns must be greater than 0.`);let n=e.layers.map((e,t)=>{if(s(e)){if(e.data.length!==e.width*e.height)throw Error(`Layer "${e.name}" data length does not match its dimensions.`);return{...c(e),zIndex:t}}if(o(e))return{...l(e),zIndex:t};throw Error(`Unsupported Tiled layer type.`)});return{height:e.height,layers:n,orientation:`orthogonal`,tileHeight:e.tileheight,tileWidth:e.tilewidth,tileset:{columns:t.columns,firstGid:t.firstgid,image:t.image,imageHeight:t.imageheight,imageWidth:t.imagewidth,lastGid:t.firstgid+t.tilecount-1,margin:t.margin??0,name:t.name,spacing:t.spacing??0,tileCount:t.tilecount,tileHeight:t.tileheight,tiles:Object.fromEntries((t.tiles??[]).map(e=>[e.id+t.firstgid,{gid:e.id+t.firstgid,properties:a(e.properties),tileId:e.id}])),tileWidth:t.tilewidth},width:e.width}}function S(e,t,n){let r=x(i(e,t)),a=p(n);r.layers.forEach(t=>{if(t.visible&&!(a&&!a.has(t.name))){if(t.type===`tilelayer`){t.data.forEach(e=>{let t=u(e);if(t&&(t.gid<r.tileset.firstGid||t.gid>r.tileset.lastGid))throw Error(`Tile gid ${String(e)} is outside the supported tileset range.`)}),v(e,t,r,n.sprite),y(e,t,r,n);return}b(e,t,n)}})}function C(e){return{addTiledMap(t,n){S(e,t,n)}}}exports.tiledPlugin=C;
|
|
2
|
+
//# sourceMappingURL=plugin.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.cjs","names":[],"sources":["../src/utils.ts","../src/plugin.ts"],"sourcesContent":["import type { CompList, GameObj, KAPLAYCtx, Quad } from 'kaplay';\n\nimport type {\n ParsedTiledLayer,\n ParsedTiledMap,\n ParsedTiledObjectLayer,\n ParsedTiledTile,\n ParsedTiledTileLayer,\n TiledLayer,\n TiledLayerComp,\n TiledMap,\n TiledMapData,\n TiledMapOpt,\n TiledObjectContext,\n TiledObjectLayer,\n TiledObjectMatch,\n TiledProperty,\n TiledPropertyValue,\n TiledTileContext,\n TiledTileLayer,\n TiledTileMatch,\n} from './types';\n\nconst FLIPPED_HORIZONTALLY_FLAG = 0x80000000;\nconst FLIPPED_VERTICALLY_FLAG = 0x40000000;\nconst FLIPPED_DIAGONALLY_FLAG = 0x20000000;\nconst FLIP_FLAGS =\n FLIPPED_HORIZONTALLY_FLAG | FLIPPED_VERTICALLY_FLAG | FLIPPED_DIAGONALLY_FLAG;\n\ninterface ParsedTileGid {\n gid: number;\n flip: {\n diagonal: boolean;\n horizontal: boolean;\n vertical: boolean;\n };\n}\n\nexport function resolveTiledMap(k: KAPLAYCtx, map: TiledMap): TiledMapData {\n if (typeof map !== 'string') {\n return map;\n }\n\n const asset = k.getAsset(map);\n\n if (!asset) {\n throw new Error(`Tiled map asset \"${map}\" is not loaded.`);\n }\n\n if (!asset.data) {\n throw new Error(`Tiled map asset \"${map}\" is not ready yet.`);\n }\n\n return asset.data as TiledMapData;\n}\n\nfunction getPropertyRecord(\n properties: TiledProperty[] | undefined,\n): Record<string, TiledPropertyValue> {\n const record: Record<string, TiledPropertyValue> = {};\n\n properties?.forEach((property) => {\n record[property.name] = property.value;\n });\n\n return record;\n}\n\nfunction isObjectLayer(layer: TiledLayer): layer is TiledObjectLayer {\n return layer.type === 'objectgroup';\n}\n\nfunction isTileLayer(layer: TiledLayer): layer is TiledTileLayer {\n return layer.type === 'tilelayer';\n}\n\nfunction normalizeTileLayer(layer: TiledTileLayer): ParsedTiledLayer {\n return {\n data: layer.data,\n height: layer.height,\n name: layer.name,\n opacity: layer.opacity ?? 1,\n type: 'tilelayer',\n visible: layer.visible ?? true,\n width: layer.width,\n x: layer.x ?? 0,\n y: layer.y ?? 0,\n zIndex: 0,\n };\n}\n\nfunction normalizeObjectLayer(layer: TiledObjectLayer): ParsedTiledObjectLayer {\n return {\n name: layer.name,\n objects: layer.objects,\n type: 'objectgroup',\n visible: layer.visible ?? true,\n zIndex: 0,\n };\n}\n\nexport function parseTileGid(rawGid: number): ParsedTileGid | null {\n if (rawGid === 0) {\n return null;\n }\n\n return {\n gid: (rawGid & ~FLIP_FLAGS) >>> 0,\n flip: {\n diagonal: (rawGid & FLIPPED_DIAGONALLY_FLAG) !== 0,\n horizontal: (rawGid & FLIPPED_HORIZONTALLY_FLAG) !== 0,\n vertical: (rawGid & FLIPPED_VERTICALLY_FLAG) !== 0,\n },\n };\n}\n\nfunction getTileDrawTransform(flip: ParsedTileGid['flip']): {\n angle: number;\n flipX: boolean;\n flipY: boolean;\n} {\n if (!flip.diagonal) {\n return {\n angle: 0,\n flipX: flip.horizontal,\n flipY: flip.vertical,\n };\n }\n\n if (flip.horizontal && flip.vertical) {\n return {\n angle: 270,\n flipX: true,\n flipY: false,\n };\n }\n\n if (flip.horizontal) {\n return {\n angle: 270,\n flipX: false,\n flipY: false,\n };\n }\n\n if (flip.vertical) {\n return {\n angle: 90,\n flipX: false,\n flipY: false,\n };\n }\n\n return {\n angle: 270,\n flipX: false,\n flipY: true,\n };\n}\n\nfunction getTileQuad(k: KAPLAYCtx, map: ParsedTiledMap, gid: number): Quad {\n const localTileId = gid - map.tileset.firstGid;\n const column = localTileId % map.tileset.columns;\n const row = Math.floor(localTileId / map.tileset.columns);\n const x =\n map.tileset.margin + column * (map.tileset.tileWidth + map.tileset.spacing);\n const y =\n map.tileset.margin + row * (map.tileset.tileHeight + map.tileset.spacing);\n\n return k.quad(\n x / map.tileset.imageWidth,\n y / map.tileset.imageHeight,\n map.tileset.tileWidth / map.tileset.imageWidth,\n map.tileset.tileHeight / map.tileset.imageHeight,\n );\n}\n\nexport function getLayerNames(options: TiledMapOpt): Set<string> | null {\n if (!options.layerNames?.length) {\n return null;\n }\n\n return new Set(options.layerNames);\n}\n\nfunction getParsedTile(\n map: ParsedTiledMap,\n gid: number,\n): ParsedTiledTile | undefined {\n return map.tileset.tiles[gid];\n}\n\nfunction matchesProperties(\n expected: Record<string, TiledPropertyValue> | undefined,\n actual: Record<string, TiledPropertyValue>,\n): boolean {\n if (!expected) {\n return true;\n }\n\n return Object.entries(expected).every(\n ([name, value]) => actual[name] === value,\n );\n}\n\nfunction matchesTileRule(\n match: TiledTileMatch,\n tile: TiledTileContext,\n): boolean {\n if (match.gid !== undefined && match.gid !== tile.gid) {\n return false;\n }\n\n if (match.tileId !== undefined && match.tileId !== tile.tileId) {\n return false;\n }\n\n if (match.layer !== undefined && match.layer !== tile.layer) {\n return false;\n }\n\n return matchesProperties(match.properties, tile.properties);\n}\n\nfunction matchesObjectRule(\n match: TiledObjectMatch,\n object: TiledObjectContext,\n): boolean {\n if (match.layer !== undefined && match.layer !== object.layer) {\n return false;\n }\n\n if (match.name !== undefined && match.name !== object.name) {\n return false;\n }\n\n if (match.type !== undefined && match.type !== object.type) {\n return false;\n }\n\n return matchesProperties(match.properties, object.properties);\n}\n\nexport function createLayerRenderer(\n k: KAPLAYCtx,\n layer: ParsedTiledTileLayer,\n map: ParsedTiledMap,\n sprite: string,\n): GameObj {\n return k.add([\n k.pos(0, 0),\n k.z(layer.zIndex),\n {\n draw: () => {\n layer.data.forEach((rawGid, index) => {\n const parsedGid = parseTileGid(rawGid);\n\n if (!parsedGid) {\n return;\n }\n\n const column = index % layer.width;\n const row = Math.floor(index / layer.width);\n const drawTransform = getTileDrawTransform(parsedGid.flip);\n\n k.drawSprite({\n anchor: 'center',\n angle: drawTransform.angle,\n flipX: drawTransform.flipX,\n flipY: drawTransform.flipY,\n opacity: layer.opacity,\n pos: k.vec2(\n (column + layer.x) * map.tileWidth + map.tileset.tileWidth / 2,\n (row + layer.y) * map.tileHeight + map.tileset.tileHeight / 2,\n ),\n quad: getTileQuad(k, map, parsedGid.gid),\n sprite,\n });\n });\n },\n id: 'tiled-layer',\n },\n ] as CompList<TiledLayerComp>);\n}\n\nexport function createMatchedTileObjects(\n k: KAPLAYCtx,\n layer: ParsedTiledTileLayer,\n map: ParsedTiledMap,\n options: TiledMapOpt,\n): GameObj[] {\n const rules = options.tiles;\n\n if (!rules?.length) {\n return [];\n }\n\n const tiles: GameObj[] = [];\n\n layer.data.forEach((rawGid, index) => {\n const parsedGid = parseTileGid(rawGid);\n\n if (!parsedGid) {\n return;\n }\n\n const parsedTile = getParsedTile(map, parsedGid.gid);\n const column = index % layer.width;\n const row = Math.floor(index / layer.width);\n const tile = {\n flip: parsedGid.flip,\n gid: parsedGid.gid,\n layer: layer.name,\n pos: {\n x: (column + layer.x) * map.tileWidth,\n y: (row + layer.y) * map.tileHeight,\n },\n properties: parsedTile?.properties ?? {},\n tileSize: {\n height: map.tileHeight,\n width: map.tileWidth,\n },\n tileId: parsedTile?.tileId ?? parsedGid.gid - map.tileset.firstGid,\n tilePos: {\n x: column + layer.x,\n y: row + layer.y,\n },\n };\n\n rules.forEach((rule) => {\n if (!matchesTileRule(rule.match, tile)) {\n return;\n }\n\n tiles.push(\n k.add([\n k.pos(tile.pos.x, tile.pos.y),\n k.anchor('topleft'),\n k.z(layer.zIndex),\n ...rule.comps(tile),\n ] as CompList<unknown>),\n );\n });\n });\n\n return tiles;\n}\n\nexport function createMatchedObjectObjects(\n k: KAPLAYCtx,\n layer: ParsedTiledObjectLayer,\n options: TiledMapOpt,\n): GameObj[] {\n const rules = options.objects;\n\n if (!rules?.length) {\n return [];\n }\n\n const objects: GameObj[] = [];\n\n if (!layer.visible) {\n return objects;\n }\n\n layer.objects.forEach((object) => {\n if (!object.visible) {\n return;\n }\n\n const context: TiledObjectContext = {\n id: object.id,\n layer: layer.name,\n name: object.name,\n objectSize: {\n height: object.height,\n width: object.width,\n },\n point: object.point ?? false,\n pos: {\n x: object.x,\n y: object.y,\n },\n properties: getPropertyRecord(object.properties),\n rotation: object.rotation,\n type: object.type,\n };\n\n rules.forEach((rule) => {\n if (!matchesObjectRule(rule.match, context)) {\n return;\n }\n\n objects.push(\n k.add([\n k.pos(context.pos.x, context.pos.y),\n k.anchor('topleft'),\n k.z(layer.zIndex),\n ...rule.comps(context),\n ] as CompList<unknown>),\n );\n });\n });\n\n return objects;\n}\n\nexport function parseTiledMap(data: TiledMapData): ParsedTiledMap {\n if (data.orientation !== 'orthogonal') {\n throw new Error(\n `Unsupported Tiled orientation \"${data.orientation}\". Expected \"orthogonal\".`,\n );\n }\n\n if (data.infinite) {\n throw new Error('Infinite Tiled maps are not supported.');\n }\n\n if (data.tilesets.length !== 1) {\n throw new Error('Exactly one Tiled tileset is required.');\n }\n\n const [tileset] = data.tilesets;\n\n if (tileset.columns <= 0) {\n throw new Error('Tiled tileset columns must be greater than 0.');\n }\n\n const layers = data.layers.map((layer, zIndex) => {\n if (isTileLayer(layer)) {\n if (layer.data.length !== layer.width * layer.height) {\n throw new Error(\n `Layer \"${layer.name}\" data length does not match its dimensions.`,\n );\n }\n\n return {\n ...normalizeTileLayer(layer),\n zIndex,\n };\n }\n\n if (isObjectLayer(layer)) {\n return {\n ...normalizeObjectLayer(layer),\n zIndex,\n };\n }\n\n throw new Error('Unsupported Tiled layer type.');\n });\n\n return {\n height: data.height,\n layers,\n orientation: 'orthogonal',\n tileHeight: data.tileheight,\n tileWidth: data.tilewidth,\n tileset: {\n columns: tileset.columns,\n firstGid: tileset.firstgid,\n image: tileset.image,\n imageHeight: tileset.imageheight,\n imageWidth: tileset.imagewidth,\n lastGid: tileset.firstgid + tileset.tilecount - 1,\n margin: tileset.margin ?? 0,\n name: tileset.name,\n spacing: tileset.spacing ?? 0,\n tileCount: tileset.tilecount,\n tileHeight: tileset.tileheight,\n tiles: Object.fromEntries(\n (tileset.tiles ?? []).map((tile) => [\n tile.id + tileset.firstgid,\n {\n gid: tile.id + tileset.firstgid,\n properties: getPropertyRecord(tile.properties),\n tileId: tile.id,\n },\n ]),\n ),\n tileWidth: tileset.tilewidth,\n },\n width: data.width,\n };\n}\n","import type { KAPLAYCtx } from 'kaplay';\n\nimport type { TiledMap, TiledMapOpt } from './types';\nimport {\n createLayerRenderer,\n createMatchedObjectObjects,\n createMatchedTileObjects,\n getLayerNames,\n parseTiledMap,\n parseTileGid,\n resolveTiledMap,\n} from './utils';\n\nexport type { TiledMap, TiledMapOpt } from './types';\n\ndeclare module 'kaplay' {\n interface KAPLAYCtx {\n addTiledMap: (map: TiledMap, options: TiledMapOpt) => void;\n }\n}\n\n/**\n * Add a Tiled map to the current KAPLAY context.\n *\n * The `map` argument can either be:\n * - parsed map JSON, or\n * - the asset key of a map loaded with `loadJSON()`.\n *\n * @param k - The active KAPLAY context.\n * @param map - The Tiled map data.\n * @param opt - The Tiled map options.\n */\nfunction addTiledMap(k: KAPLAYCtx, map: TiledMap, opt: TiledMapOpt): void {\n const parsedMap = parseTiledMap(resolveTiledMap(k, map));\n const allowedLayerNames = getLayerNames(opt);\n\n parsedMap.layers.forEach((layer) => {\n if (!layer.visible) {\n return;\n }\n\n if (allowedLayerNames && !allowedLayerNames.has(layer.name)) {\n return;\n }\n\n if (layer.type === 'tilelayer') {\n layer.data.forEach((rawGid) => {\n const parsedGid = parseTileGid(rawGid);\n\n if (\n parsedGid &&\n (parsedGid.gid < parsedMap.tileset.firstGid ||\n parsedGid.gid > parsedMap.tileset.lastGid)\n ) {\n throw new Error(\n `Tile gid ${String(rawGid)} is outside the supported tileset range.`,\n );\n }\n });\n\n createLayerRenderer(k, layer, parsedMap, opt.sprite);\n createMatchedTileObjects(k, layer, parsedMap, opt);\n return;\n }\n\n createMatchedObjectObjects(k, layer, opt);\n });\n}\n\n/**\n * KAPLAY plugin that adds `addTiledMap()` to the context.\n *\n * @param k - The active KAPLAY context.\n * @returns - The plugin API.\n */\nexport function tiledPlugin(k: KAPLAYCtx) {\n return {\n addTiledMap(map: TiledMap, options: TiledMapOpt) {\n addTiledMap(k, map, options);\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { CompList } from 'kaplay';
|
|
2
|
+
import { KAPLAYCtx } from 'kaplay';
|
|
3
|
+
|
|
4
|
+
declare type TiledLayer = TiledObjectLayer | TiledTileLayer;
|
|
5
|
+
|
|
6
|
+
export declare type TiledMap = TiledMapData | string;
|
|
7
|
+
|
|
8
|
+
declare interface TiledMapData {
|
|
9
|
+
height: number;
|
|
10
|
+
infinite: boolean;
|
|
11
|
+
layers: TiledLayer[];
|
|
12
|
+
orientation: string;
|
|
13
|
+
renderorder?: string;
|
|
14
|
+
tileheight: number;
|
|
15
|
+
tilesets: TiledTileset[];
|
|
16
|
+
tilewidth: number;
|
|
17
|
+
width: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export declare interface TiledMapOpt {
|
|
21
|
+
layerNames?: string[];
|
|
22
|
+
objects?: TiledObjectRule[];
|
|
23
|
+
sprite: string;
|
|
24
|
+
tiles?: TiledTileRule[];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
declare interface TiledObject {
|
|
28
|
+
height: number;
|
|
29
|
+
id: number;
|
|
30
|
+
name: string;
|
|
31
|
+
point?: boolean;
|
|
32
|
+
properties?: TiledProperty[];
|
|
33
|
+
rotation: number;
|
|
34
|
+
type: string;
|
|
35
|
+
visible: boolean;
|
|
36
|
+
width: number;
|
|
37
|
+
x: number;
|
|
38
|
+
y: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
declare interface TiledObjectContext {
|
|
42
|
+
id: number;
|
|
43
|
+
layer: string;
|
|
44
|
+
name: string;
|
|
45
|
+
objectSize: {
|
|
46
|
+
height: number;
|
|
47
|
+
width: number;
|
|
48
|
+
};
|
|
49
|
+
point: boolean;
|
|
50
|
+
pos: {
|
|
51
|
+
x: number;
|
|
52
|
+
y: number;
|
|
53
|
+
};
|
|
54
|
+
properties: Record<string, TiledPropertyValue>;
|
|
55
|
+
rotation: number;
|
|
56
|
+
type: string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
declare interface TiledObjectLayer {
|
|
60
|
+
draworder?: string;
|
|
61
|
+
id: number;
|
|
62
|
+
name: string;
|
|
63
|
+
objects: TiledObject[];
|
|
64
|
+
opacity?: number;
|
|
65
|
+
type: string;
|
|
66
|
+
visible?: boolean;
|
|
67
|
+
x?: number;
|
|
68
|
+
y?: number;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
declare interface TiledObjectMatch {
|
|
72
|
+
layer?: string;
|
|
73
|
+
name?: string;
|
|
74
|
+
properties?: Record<string, TiledPropertyValue>;
|
|
75
|
+
type?: string;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
declare interface TiledObjectRule {
|
|
79
|
+
comps: (object: TiledObjectContext) => CompList<unknown>;
|
|
80
|
+
match: TiledObjectMatch;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* KAPLAY plugin that adds `addTiledMap()` to the context.
|
|
85
|
+
*
|
|
86
|
+
* @param k - The active KAPLAY context.
|
|
87
|
+
* @returns - The plugin API.
|
|
88
|
+
*/
|
|
89
|
+
export declare function tiledPlugin(k: KAPLAYCtx): {
|
|
90
|
+
addTiledMap(map: TiledMap, options: TiledMapOpt): void;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
declare interface TiledProperty {
|
|
94
|
+
name: string;
|
|
95
|
+
type?: string;
|
|
96
|
+
value: TiledPropertyValue;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
declare type TiledPropertyValue = boolean | number | string;
|
|
100
|
+
|
|
101
|
+
declare interface TiledTileContext {
|
|
102
|
+
flip: {
|
|
103
|
+
diagonal: boolean;
|
|
104
|
+
horizontal: boolean;
|
|
105
|
+
vertical: boolean;
|
|
106
|
+
};
|
|
107
|
+
gid: number;
|
|
108
|
+
layer: string;
|
|
109
|
+
pos: {
|
|
110
|
+
x: number;
|
|
111
|
+
y: number;
|
|
112
|
+
};
|
|
113
|
+
properties: Record<string, TiledPropertyValue>;
|
|
114
|
+
tileSize: {
|
|
115
|
+
height: number;
|
|
116
|
+
width: number;
|
|
117
|
+
};
|
|
118
|
+
tileId: number;
|
|
119
|
+
tilePos: {
|
|
120
|
+
x: number;
|
|
121
|
+
y: number;
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
declare interface TiledTileDefinition {
|
|
126
|
+
id: number;
|
|
127
|
+
properties?: TiledProperty[];
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
declare interface TiledTileLayer {
|
|
131
|
+
data: number[];
|
|
132
|
+
height: number;
|
|
133
|
+
name: string;
|
|
134
|
+
opacity?: number;
|
|
135
|
+
type: string;
|
|
136
|
+
visible?: boolean;
|
|
137
|
+
width: number;
|
|
138
|
+
x?: number;
|
|
139
|
+
y?: number;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
declare interface TiledTileMatch {
|
|
143
|
+
gid?: number;
|
|
144
|
+
layer?: string;
|
|
145
|
+
properties?: Record<string, TiledPropertyValue>;
|
|
146
|
+
tileId?: number;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
declare interface TiledTileRule {
|
|
150
|
+
comps: (tile: TiledTileContext) => CompList<unknown>;
|
|
151
|
+
match: TiledTileMatch;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
declare interface TiledTileset {
|
|
155
|
+
columns: number;
|
|
156
|
+
firstgid: number;
|
|
157
|
+
image: string;
|
|
158
|
+
imageheight: number;
|
|
159
|
+
imagewidth: number;
|
|
160
|
+
margin?: number;
|
|
161
|
+
name: string;
|
|
162
|
+
spacing?: number;
|
|
163
|
+
tilecount: number;
|
|
164
|
+
tileheight: number;
|
|
165
|
+
tiles?: TiledTileDefinition[];
|
|
166
|
+
tilewidth: number;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export { }
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
declare module 'kaplay' {
|
|
173
|
+
interface KAPLAYCtx {
|
|
174
|
+
addTiledMap: (map: TiledMap, options: TiledMapOpt) => void;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { CompList } from 'kaplay';
|
|
2
|
+
import { KAPLAYCtx } from 'kaplay';
|
|
3
|
+
|
|
4
|
+
declare type TiledLayer = TiledObjectLayer | TiledTileLayer;
|
|
5
|
+
|
|
6
|
+
export declare type TiledMap = TiledMapData | string;
|
|
7
|
+
|
|
8
|
+
declare interface TiledMapData {
|
|
9
|
+
height: number;
|
|
10
|
+
infinite: boolean;
|
|
11
|
+
layers: TiledLayer[];
|
|
12
|
+
orientation: string;
|
|
13
|
+
renderorder?: string;
|
|
14
|
+
tileheight: number;
|
|
15
|
+
tilesets: TiledTileset[];
|
|
16
|
+
tilewidth: number;
|
|
17
|
+
width: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export declare interface TiledMapOpt {
|
|
21
|
+
layerNames?: string[];
|
|
22
|
+
objects?: TiledObjectRule[];
|
|
23
|
+
sprite: string;
|
|
24
|
+
tiles?: TiledTileRule[];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
declare interface TiledObject {
|
|
28
|
+
height: number;
|
|
29
|
+
id: number;
|
|
30
|
+
name: string;
|
|
31
|
+
point?: boolean;
|
|
32
|
+
properties?: TiledProperty[];
|
|
33
|
+
rotation: number;
|
|
34
|
+
type: string;
|
|
35
|
+
visible: boolean;
|
|
36
|
+
width: number;
|
|
37
|
+
x: number;
|
|
38
|
+
y: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
declare interface TiledObjectContext {
|
|
42
|
+
id: number;
|
|
43
|
+
layer: string;
|
|
44
|
+
name: string;
|
|
45
|
+
objectSize: {
|
|
46
|
+
height: number;
|
|
47
|
+
width: number;
|
|
48
|
+
};
|
|
49
|
+
point: boolean;
|
|
50
|
+
pos: {
|
|
51
|
+
x: number;
|
|
52
|
+
y: number;
|
|
53
|
+
};
|
|
54
|
+
properties: Record<string, TiledPropertyValue>;
|
|
55
|
+
rotation: number;
|
|
56
|
+
type: string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
declare interface TiledObjectLayer {
|
|
60
|
+
draworder?: string;
|
|
61
|
+
id: number;
|
|
62
|
+
name: string;
|
|
63
|
+
objects: TiledObject[];
|
|
64
|
+
opacity?: number;
|
|
65
|
+
type: string;
|
|
66
|
+
visible?: boolean;
|
|
67
|
+
x?: number;
|
|
68
|
+
y?: number;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
declare interface TiledObjectMatch {
|
|
72
|
+
layer?: string;
|
|
73
|
+
name?: string;
|
|
74
|
+
properties?: Record<string, TiledPropertyValue>;
|
|
75
|
+
type?: string;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
declare interface TiledObjectRule {
|
|
79
|
+
comps: (object: TiledObjectContext) => CompList<unknown>;
|
|
80
|
+
match: TiledObjectMatch;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* KAPLAY plugin that adds `addTiledMap()` to the context.
|
|
85
|
+
*
|
|
86
|
+
* @param k - The active KAPLAY context.
|
|
87
|
+
* @returns - The plugin API.
|
|
88
|
+
*/
|
|
89
|
+
export declare function tiledPlugin(k: KAPLAYCtx): {
|
|
90
|
+
addTiledMap(map: TiledMap, options: TiledMapOpt): void;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
declare interface TiledProperty {
|
|
94
|
+
name: string;
|
|
95
|
+
type?: string;
|
|
96
|
+
value: TiledPropertyValue;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
declare type TiledPropertyValue = boolean | number | string;
|
|
100
|
+
|
|
101
|
+
declare interface TiledTileContext {
|
|
102
|
+
flip: {
|
|
103
|
+
diagonal: boolean;
|
|
104
|
+
horizontal: boolean;
|
|
105
|
+
vertical: boolean;
|
|
106
|
+
};
|
|
107
|
+
gid: number;
|
|
108
|
+
layer: string;
|
|
109
|
+
pos: {
|
|
110
|
+
x: number;
|
|
111
|
+
y: number;
|
|
112
|
+
};
|
|
113
|
+
properties: Record<string, TiledPropertyValue>;
|
|
114
|
+
tileSize: {
|
|
115
|
+
height: number;
|
|
116
|
+
width: number;
|
|
117
|
+
};
|
|
118
|
+
tileId: number;
|
|
119
|
+
tilePos: {
|
|
120
|
+
x: number;
|
|
121
|
+
y: number;
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
declare interface TiledTileDefinition {
|
|
126
|
+
id: number;
|
|
127
|
+
properties?: TiledProperty[];
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
declare interface TiledTileLayer {
|
|
131
|
+
data: number[];
|
|
132
|
+
height: number;
|
|
133
|
+
name: string;
|
|
134
|
+
opacity?: number;
|
|
135
|
+
type: string;
|
|
136
|
+
visible?: boolean;
|
|
137
|
+
width: number;
|
|
138
|
+
x?: number;
|
|
139
|
+
y?: number;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
declare interface TiledTileMatch {
|
|
143
|
+
gid?: number;
|
|
144
|
+
layer?: string;
|
|
145
|
+
properties?: Record<string, TiledPropertyValue>;
|
|
146
|
+
tileId?: number;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
declare interface TiledTileRule {
|
|
150
|
+
comps: (tile: TiledTileContext) => CompList<unknown>;
|
|
151
|
+
match: TiledTileMatch;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
declare interface TiledTileset {
|
|
155
|
+
columns: number;
|
|
156
|
+
firstgid: number;
|
|
157
|
+
image: string;
|
|
158
|
+
imageheight: number;
|
|
159
|
+
imagewidth: number;
|
|
160
|
+
margin?: number;
|
|
161
|
+
name: string;
|
|
162
|
+
spacing?: number;
|
|
163
|
+
tilecount: number;
|
|
164
|
+
tileheight: number;
|
|
165
|
+
tiles?: TiledTileDefinition[];
|
|
166
|
+
tilewidth: number;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export { }
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
declare module 'kaplay' {
|
|
173
|
+
interface KAPLAYCtx {
|
|
174
|
+
addTiledMap: (map: TiledMap, options: TiledMapOpt) => void;
|
|
175
|
+
}
|
|
176
|
+
}
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { CompList } from 'kaplay';
|
|
2
|
+
import { KAPLAYCtx } from 'kaplay';
|
|
3
|
+
|
|
4
|
+
declare type TiledLayer = TiledObjectLayer | TiledTileLayer;
|
|
5
|
+
|
|
6
|
+
export declare type TiledMap = TiledMapData | string;
|
|
7
|
+
|
|
8
|
+
declare interface TiledMapData {
|
|
9
|
+
height: number;
|
|
10
|
+
infinite: boolean;
|
|
11
|
+
layers: TiledLayer[];
|
|
12
|
+
orientation: string;
|
|
13
|
+
renderorder?: string;
|
|
14
|
+
tileheight: number;
|
|
15
|
+
tilesets: TiledTileset[];
|
|
16
|
+
tilewidth: number;
|
|
17
|
+
width: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export declare interface TiledMapOpt {
|
|
21
|
+
layerNames?: string[];
|
|
22
|
+
objects?: TiledObjectRule[];
|
|
23
|
+
sprite: string;
|
|
24
|
+
tiles?: TiledTileRule[];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
declare interface TiledObject {
|
|
28
|
+
height: number;
|
|
29
|
+
id: number;
|
|
30
|
+
name: string;
|
|
31
|
+
point?: boolean;
|
|
32
|
+
properties?: TiledProperty[];
|
|
33
|
+
rotation: number;
|
|
34
|
+
type: string;
|
|
35
|
+
visible: boolean;
|
|
36
|
+
width: number;
|
|
37
|
+
x: number;
|
|
38
|
+
y: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
declare interface TiledObjectContext {
|
|
42
|
+
id: number;
|
|
43
|
+
layer: string;
|
|
44
|
+
name: string;
|
|
45
|
+
objectSize: {
|
|
46
|
+
height: number;
|
|
47
|
+
width: number;
|
|
48
|
+
};
|
|
49
|
+
point: boolean;
|
|
50
|
+
pos: {
|
|
51
|
+
x: number;
|
|
52
|
+
y: number;
|
|
53
|
+
};
|
|
54
|
+
properties: Record<string, TiledPropertyValue>;
|
|
55
|
+
rotation: number;
|
|
56
|
+
type: string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
declare interface TiledObjectLayer {
|
|
60
|
+
draworder?: string;
|
|
61
|
+
id: number;
|
|
62
|
+
name: string;
|
|
63
|
+
objects: TiledObject[];
|
|
64
|
+
opacity?: number;
|
|
65
|
+
type: string;
|
|
66
|
+
visible?: boolean;
|
|
67
|
+
x?: number;
|
|
68
|
+
y?: number;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
declare interface TiledObjectMatch {
|
|
72
|
+
layer?: string;
|
|
73
|
+
name?: string;
|
|
74
|
+
properties?: Record<string, TiledPropertyValue>;
|
|
75
|
+
type?: string;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
declare interface TiledObjectRule {
|
|
79
|
+
comps: (object: TiledObjectContext) => CompList<unknown>;
|
|
80
|
+
match: TiledObjectMatch;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* KAPLAY plugin that adds `addTiledMap()` to the context.
|
|
85
|
+
*
|
|
86
|
+
* @param k - The active KAPLAY context.
|
|
87
|
+
* @returns - The plugin API.
|
|
88
|
+
*/
|
|
89
|
+
export declare function tiledPlugin(k: KAPLAYCtx): {
|
|
90
|
+
addTiledMap(map: TiledMap, options: TiledMapOpt): void;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
declare interface TiledProperty {
|
|
94
|
+
name: string;
|
|
95
|
+
type?: string;
|
|
96
|
+
value: TiledPropertyValue;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
declare type TiledPropertyValue = boolean | number | string;
|
|
100
|
+
|
|
101
|
+
declare interface TiledTileContext {
|
|
102
|
+
flip: {
|
|
103
|
+
diagonal: boolean;
|
|
104
|
+
horizontal: boolean;
|
|
105
|
+
vertical: boolean;
|
|
106
|
+
};
|
|
107
|
+
gid: number;
|
|
108
|
+
layer: string;
|
|
109
|
+
pos: {
|
|
110
|
+
x: number;
|
|
111
|
+
y: number;
|
|
112
|
+
};
|
|
113
|
+
properties: Record<string, TiledPropertyValue>;
|
|
114
|
+
tileSize: {
|
|
115
|
+
height: number;
|
|
116
|
+
width: number;
|
|
117
|
+
};
|
|
118
|
+
tileId: number;
|
|
119
|
+
tilePos: {
|
|
120
|
+
x: number;
|
|
121
|
+
y: number;
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
declare interface TiledTileDefinition {
|
|
126
|
+
id: number;
|
|
127
|
+
properties?: TiledProperty[];
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
declare interface TiledTileLayer {
|
|
131
|
+
data: number[];
|
|
132
|
+
height: number;
|
|
133
|
+
name: string;
|
|
134
|
+
opacity?: number;
|
|
135
|
+
type: string;
|
|
136
|
+
visible?: boolean;
|
|
137
|
+
width: number;
|
|
138
|
+
x?: number;
|
|
139
|
+
y?: number;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
declare interface TiledTileMatch {
|
|
143
|
+
gid?: number;
|
|
144
|
+
layer?: string;
|
|
145
|
+
properties?: Record<string, TiledPropertyValue>;
|
|
146
|
+
tileId?: number;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
declare interface TiledTileRule {
|
|
150
|
+
comps: (tile: TiledTileContext) => CompList<unknown>;
|
|
151
|
+
match: TiledTileMatch;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
declare interface TiledTileset {
|
|
155
|
+
columns: number;
|
|
156
|
+
firstgid: number;
|
|
157
|
+
image: string;
|
|
158
|
+
imageheight: number;
|
|
159
|
+
imagewidth: number;
|
|
160
|
+
margin?: number;
|
|
161
|
+
name: string;
|
|
162
|
+
spacing?: number;
|
|
163
|
+
tilecount: number;
|
|
164
|
+
tileheight: number;
|
|
165
|
+
tiles?: TiledTileDefinition[];
|
|
166
|
+
tilewidth: number;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export { }
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
declare module 'kaplay' {
|
|
173
|
+
interface KAPLAYCtx {
|
|
174
|
+
addTiledMap: (map: TiledMap, options: TiledMapOpt) => void;
|
|
175
|
+
}
|
|
176
|
+
}
|
package/dist/plugin.mjs
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
//#region src/utils.ts
|
|
2
|
+
var e = 2147483648, t = 1073741824, n = 536870912, r = t | -1610612736;
|
|
3
|
+
function i(e, t) {
|
|
4
|
+
if (typeof t != "string") return t;
|
|
5
|
+
let n = e.getAsset(t);
|
|
6
|
+
if (!n) throw Error(`Tiled map asset "${t}" is not loaded.`);
|
|
7
|
+
if (!n.data) throw Error(`Tiled map asset "${t}" is not ready yet.`);
|
|
8
|
+
return n.data;
|
|
9
|
+
}
|
|
10
|
+
function a(e) {
|
|
11
|
+
let t = {};
|
|
12
|
+
return e?.forEach((e) => {
|
|
13
|
+
t[e.name] = e.value;
|
|
14
|
+
}), t;
|
|
15
|
+
}
|
|
16
|
+
function o(e) {
|
|
17
|
+
return e.type === "objectgroup";
|
|
18
|
+
}
|
|
19
|
+
function s(e) {
|
|
20
|
+
return e.type === "tilelayer";
|
|
21
|
+
}
|
|
22
|
+
function c(e) {
|
|
23
|
+
return {
|
|
24
|
+
data: e.data,
|
|
25
|
+
height: e.height,
|
|
26
|
+
name: e.name,
|
|
27
|
+
opacity: e.opacity ?? 1,
|
|
28
|
+
type: "tilelayer",
|
|
29
|
+
visible: e.visible ?? !0,
|
|
30
|
+
width: e.width,
|
|
31
|
+
x: e.x ?? 0,
|
|
32
|
+
y: e.y ?? 0,
|
|
33
|
+
zIndex: 0
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function l(e) {
|
|
37
|
+
return {
|
|
38
|
+
name: e.name,
|
|
39
|
+
objects: e.objects,
|
|
40
|
+
type: "objectgroup",
|
|
41
|
+
visible: e.visible ?? !0,
|
|
42
|
+
zIndex: 0
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function u(i) {
|
|
46
|
+
return i === 0 ? null : {
|
|
47
|
+
gid: (i & ~r) >>> 0,
|
|
48
|
+
flip: {
|
|
49
|
+
diagonal: (i & n) !== 0,
|
|
50
|
+
horizontal: (i & e) !== 0,
|
|
51
|
+
vertical: (i & t) !== 0
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function d(e) {
|
|
56
|
+
return e.diagonal ? e.horizontal && e.vertical ? {
|
|
57
|
+
angle: 270,
|
|
58
|
+
flipX: !0,
|
|
59
|
+
flipY: !1
|
|
60
|
+
} : e.horizontal ? {
|
|
61
|
+
angle: 270,
|
|
62
|
+
flipX: !1,
|
|
63
|
+
flipY: !1
|
|
64
|
+
} : e.vertical ? {
|
|
65
|
+
angle: 90,
|
|
66
|
+
flipX: !1,
|
|
67
|
+
flipY: !1
|
|
68
|
+
} : {
|
|
69
|
+
angle: 270,
|
|
70
|
+
flipX: !1,
|
|
71
|
+
flipY: !0
|
|
72
|
+
} : {
|
|
73
|
+
angle: 0,
|
|
74
|
+
flipX: e.horizontal,
|
|
75
|
+
flipY: e.vertical
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function f(e, t, n) {
|
|
79
|
+
let r = n - t.tileset.firstGid, i = r % t.tileset.columns, a = Math.floor(r / t.tileset.columns), o = t.tileset.margin + i * (t.tileset.tileWidth + t.tileset.spacing), s = t.tileset.margin + a * (t.tileset.tileHeight + t.tileset.spacing);
|
|
80
|
+
return e.quad(o / t.tileset.imageWidth, s / t.tileset.imageHeight, t.tileset.tileWidth / t.tileset.imageWidth, t.tileset.tileHeight / t.tileset.imageHeight);
|
|
81
|
+
}
|
|
82
|
+
function p(e) {
|
|
83
|
+
return e.layerNames?.length ? new Set(e.layerNames) : null;
|
|
84
|
+
}
|
|
85
|
+
function m(e, t) {
|
|
86
|
+
return e.tileset.tiles[t];
|
|
87
|
+
}
|
|
88
|
+
function h(e, t) {
|
|
89
|
+
return e ? Object.entries(e).every(([e, n]) => t[e] === n) : !0;
|
|
90
|
+
}
|
|
91
|
+
function g(e, t) {
|
|
92
|
+
return e.gid !== void 0 && e.gid !== t.gid || e.tileId !== void 0 && e.tileId !== t.tileId || e.layer !== void 0 && e.layer !== t.layer ? !1 : h(e.properties, t.properties);
|
|
93
|
+
}
|
|
94
|
+
function _(e, t) {
|
|
95
|
+
return e.layer !== void 0 && e.layer !== t.layer || e.name !== void 0 && e.name !== t.name || e.type !== void 0 && e.type !== t.type ? !1 : h(e.properties, t.properties);
|
|
96
|
+
}
|
|
97
|
+
function v(e, t, n, r) {
|
|
98
|
+
return e.add([
|
|
99
|
+
e.pos(0, 0),
|
|
100
|
+
e.z(t.zIndex),
|
|
101
|
+
{
|
|
102
|
+
draw: () => {
|
|
103
|
+
t.data.forEach((i, a) => {
|
|
104
|
+
let o = u(i);
|
|
105
|
+
if (!o) return;
|
|
106
|
+
let s = a % t.width, c = Math.floor(a / t.width), l = d(o.flip);
|
|
107
|
+
e.drawSprite({
|
|
108
|
+
anchor: "center",
|
|
109
|
+
angle: l.angle,
|
|
110
|
+
flipX: l.flipX,
|
|
111
|
+
flipY: l.flipY,
|
|
112
|
+
opacity: t.opacity,
|
|
113
|
+
pos: e.vec2((s + t.x) * n.tileWidth + n.tileset.tileWidth / 2, (c + t.y) * n.tileHeight + n.tileset.tileHeight / 2),
|
|
114
|
+
quad: f(e, n, o.gid),
|
|
115
|
+
sprite: r
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
},
|
|
119
|
+
id: "tiled-layer"
|
|
120
|
+
}
|
|
121
|
+
]);
|
|
122
|
+
}
|
|
123
|
+
function y(e, t, n, r) {
|
|
124
|
+
let i = r.tiles;
|
|
125
|
+
if (!i?.length) return [];
|
|
126
|
+
let a = [];
|
|
127
|
+
return t.data.forEach((r, o) => {
|
|
128
|
+
let s = u(r);
|
|
129
|
+
if (!s) return;
|
|
130
|
+
let c = m(n, s.gid), l = o % t.width, d = Math.floor(o / t.width), f = {
|
|
131
|
+
flip: s.flip,
|
|
132
|
+
gid: s.gid,
|
|
133
|
+
layer: t.name,
|
|
134
|
+
pos: {
|
|
135
|
+
x: (l + t.x) * n.tileWidth,
|
|
136
|
+
y: (d + t.y) * n.tileHeight
|
|
137
|
+
},
|
|
138
|
+
properties: c?.properties ?? {},
|
|
139
|
+
tileSize: {
|
|
140
|
+
height: n.tileHeight,
|
|
141
|
+
width: n.tileWidth
|
|
142
|
+
},
|
|
143
|
+
tileId: c?.tileId ?? s.gid - n.tileset.firstGid,
|
|
144
|
+
tilePos: {
|
|
145
|
+
x: l + t.x,
|
|
146
|
+
y: d + t.y
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
i.forEach((n) => {
|
|
150
|
+
g(n.match, f) && a.push(e.add([
|
|
151
|
+
e.pos(f.pos.x, f.pos.y),
|
|
152
|
+
e.anchor("topleft"),
|
|
153
|
+
e.z(t.zIndex),
|
|
154
|
+
...n.comps(f)
|
|
155
|
+
]));
|
|
156
|
+
});
|
|
157
|
+
}), a;
|
|
158
|
+
}
|
|
159
|
+
function b(e, t, n) {
|
|
160
|
+
let r = n.objects;
|
|
161
|
+
if (!r?.length) return [];
|
|
162
|
+
let i = [];
|
|
163
|
+
return t.visible && t.objects.forEach((n) => {
|
|
164
|
+
if (!n.visible) return;
|
|
165
|
+
let o = {
|
|
166
|
+
id: n.id,
|
|
167
|
+
layer: t.name,
|
|
168
|
+
name: n.name,
|
|
169
|
+
objectSize: {
|
|
170
|
+
height: n.height,
|
|
171
|
+
width: n.width
|
|
172
|
+
},
|
|
173
|
+
point: n.point ?? !1,
|
|
174
|
+
pos: {
|
|
175
|
+
x: n.x,
|
|
176
|
+
y: n.y
|
|
177
|
+
},
|
|
178
|
+
properties: a(n.properties),
|
|
179
|
+
rotation: n.rotation,
|
|
180
|
+
type: n.type
|
|
181
|
+
};
|
|
182
|
+
r.forEach((n) => {
|
|
183
|
+
_(n.match, o) && i.push(e.add([
|
|
184
|
+
e.pos(o.pos.x, o.pos.y),
|
|
185
|
+
e.anchor("topleft"),
|
|
186
|
+
e.z(t.zIndex),
|
|
187
|
+
...n.comps(o)
|
|
188
|
+
]));
|
|
189
|
+
});
|
|
190
|
+
}), i;
|
|
191
|
+
}
|
|
192
|
+
function x(e) {
|
|
193
|
+
if (e.orientation !== "orthogonal") throw Error(`Unsupported Tiled orientation "${e.orientation}". Expected "orthogonal".`);
|
|
194
|
+
if (e.infinite) throw Error("Infinite Tiled maps are not supported.");
|
|
195
|
+
if (e.tilesets.length !== 1) throw Error("Exactly one Tiled tileset is required.");
|
|
196
|
+
let [t] = e.tilesets;
|
|
197
|
+
if (t.columns <= 0) throw Error("Tiled tileset columns must be greater than 0.");
|
|
198
|
+
let n = e.layers.map((e, t) => {
|
|
199
|
+
if (s(e)) {
|
|
200
|
+
if (e.data.length !== e.width * e.height) throw Error(`Layer "${e.name}" data length does not match its dimensions.`);
|
|
201
|
+
return {
|
|
202
|
+
...c(e),
|
|
203
|
+
zIndex: t
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
if (o(e)) return {
|
|
207
|
+
...l(e),
|
|
208
|
+
zIndex: t
|
|
209
|
+
};
|
|
210
|
+
throw Error("Unsupported Tiled layer type.");
|
|
211
|
+
});
|
|
212
|
+
return {
|
|
213
|
+
height: e.height,
|
|
214
|
+
layers: n,
|
|
215
|
+
orientation: "orthogonal",
|
|
216
|
+
tileHeight: e.tileheight,
|
|
217
|
+
tileWidth: e.tilewidth,
|
|
218
|
+
tileset: {
|
|
219
|
+
columns: t.columns,
|
|
220
|
+
firstGid: t.firstgid,
|
|
221
|
+
image: t.image,
|
|
222
|
+
imageHeight: t.imageheight,
|
|
223
|
+
imageWidth: t.imagewidth,
|
|
224
|
+
lastGid: t.firstgid + t.tilecount - 1,
|
|
225
|
+
margin: t.margin ?? 0,
|
|
226
|
+
name: t.name,
|
|
227
|
+
spacing: t.spacing ?? 0,
|
|
228
|
+
tileCount: t.tilecount,
|
|
229
|
+
tileHeight: t.tileheight,
|
|
230
|
+
tiles: Object.fromEntries((t.tiles ?? []).map((e) => [e.id + t.firstgid, {
|
|
231
|
+
gid: e.id + t.firstgid,
|
|
232
|
+
properties: a(e.properties),
|
|
233
|
+
tileId: e.id
|
|
234
|
+
}])),
|
|
235
|
+
tileWidth: t.tilewidth
|
|
236
|
+
},
|
|
237
|
+
width: e.width
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
//#endregion
|
|
241
|
+
//#region src/plugin.ts
|
|
242
|
+
function S(e, t, n) {
|
|
243
|
+
let r = x(i(e, t)), a = p(n);
|
|
244
|
+
r.layers.forEach((t) => {
|
|
245
|
+
if (t.visible && !(a && !a.has(t.name))) {
|
|
246
|
+
if (t.type === "tilelayer") {
|
|
247
|
+
t.data.forEach((e) => {
|
|
248
|
+
let t = u(e);
|
|
249
|
+
if (t && (t.gid < r.tileset.firstGid || t.gid > r.tileset.lastGid)) throw Error(`Tile gid ${String(e)} is outside the supported tileset range.`);
|
|
250
|
+
}), v(e, t, r, n.sprite), y(e, t, r, n);
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
b(e, t, n);
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
function C(e) {
|
|
258
|
+
return { addTiledMap(t, n) {
|
|
259
|
+
S(e, t, n);
|
|
260
|
+
} };
|
|
261
|
+
}
|
|
262
|
+
//#endregion
|
|
263
|
+
export { C as tiledPlugin };
|
|
264
|
+
|
|
265
|
+
//# sourceMappingURL=plugin.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.mjs","names":[],"sources":["../src/utils.ts","../src/plugin.ts"],"sourcesContent":["import type { CompList, GameObj, KAPLAYCtx, Quad } from 'kaplay';\n\nimport type {\n ParsedTiledLayer,\n ParsedTiledMap,\n ParsedTiledObjectLayer,\n ParsedTiledTile,\n ParsedTiledTileLayer,\n TiledLayer,\n TiledLayerComp,\n TiledMap,\n TiledMapData,\n TiledMapOpt,\n TiledObjectContext,\n TiledObjectLayer,\n TiledObjectMatch,\n TiledProperty,\n TiledPropertyValue,\n TiledTileContext,\n TiledTileLayer,\n TiledTileMatch,\n} from './types';\n\nconst FLIPPED_HORIZONTALLY_FLAG = 0x80000000;\nconst FLIPPED_VERTICALLY_FLAG = 0x40000000;\nconst FLIPPED_DIAGONALLY_FLAG = 0x20000000;\nconst FLIP_FLAGS =\n FLIPPED_HORIZONTALLY_FLAG | FLIPPED_VERTICALLY_FLAG | FLIPPED_DIAGONALLY_FLAG;\n\ninterface ParsedTileGid {\n gid: number;\n flip: {\n diagonal: boolean;\n horizontal: boolean;\n vertical: boolean;\n };\n}\n\nexport function resolveTiledMap(k: KAPLAYCtx, map: TiledMap): TiledMapData {\n if (typeof map !== 'string') {\n return map;\n }\n\n const asset = k.getAsset(map);\n\n if (!asset) {\n throw new Error(`Tiled map asset \"${map}\" is not loaded.`);\n }\n\n if (!asset.data) {\n throw new Error(`Tiled map asset \"${map}\" is not ready yet.`);\n }\n\n return asset.data as TiledMapData;\n}\n\nfunction getPropertyRecord(\n properties: TiledProperty[] | undefined,\n): Record<string, TiledPropertyValue> {\n const record: Record<string, TiledPropertyValue> = {};\n\n properties?.forEach((property) => {\n record[property.name] = property.value;\n });\n\n return record;\n}\n\nfunction isObjectLayer(layer: TiledLayer): layer is TiledObjectLayer {\n return layer.type === 'objectgroup';\n}\n\nfunction isTileLayer(layer: TiledLayer): layer is TiledTileLayer {\n return layer.type === 'tilelayer';\n}\n\nfunction normalizeTileLayer(layer: TiledTileLayer): ParsedTiledLayer {\n return {\n data: layer.data,\n height: layer.height,\n name: layer.name,\n opacity: layer.opacity ?? 1,\n type: 'tilelayer',\n visible: layer.visible ?? true,\n width: layer.width,\n x: layer.x ?? 0,\n y: layer.y ?? 0,\n zIndex: 0,\n };\n}\n\nfunction normalizeObjectLayer(layer: TiledObjectLayer): ParsedTiledObjectLayer {\n return {\n name: layer.name,\n objects: layer.objects,\n type: 'objectgroup',\n visible: layer.visible ?? true,\n zIndex: 0,\n };\n}\n\nexport function parseTileGid(rawGid: number): ParsedTileGid | null {\n if (rawGid === 0) {\n return null;\n }\n\n return {\n gid: (rawGid & ~FLIP_FLAGS) >>> 0,\n flip: {\n diagonal: (rawGid & FLIPPED_DIAGONALLY_FLAG) !== 0,\n horizontal: (rawGid & FLIPPED_HORIZONTALLY_FLAG) !== 0,\n vertical: (rawGid & FLIPPED_VERTICALLY_FLAG) !== 0,\n },\n };\n}\n\nfunction getTileDrawTransform(flip: ParsedTileGid['flip']): {\n angle: number;\n flipX: boolean;\n flipY: boolean;\n} {\n if (!flip.diagonal) {\n return {\n angle: 0,\n flipX: flip.horizontal,\n flipY: flip.vertical,\n };\n }\n\n if (flip.horizontal && flip.vertical) {\n return {\n angle: 270,\n flipX: true,\n flipY: false,\n };\n }\n\n if (flip.horizontal) {\n return {\n angle: 270,\n flipX: false,\n flipY: false,\n };\n }\n\n if (flip.vertical) {\n return {\n angle: 90,\n flipX: false,\n flipY: false,\n };\n }\n\n return {\n angle: 270,\n flipX: false,\n flipY: true,\n };\n}\n\nfunction getTileQuad(k: KAPLAYCtx, map: ParsedTiledMap, gid: number): Quad {\n const localTileId = gid - map.tileset.firstGid;\n const column = localTileId % map.tileset.columns;\n const row = Math.floor(localTileId / map.tileset.columns);\n const x =\n map.tileset.margin + column * (map.tileset.tileWidth + map.tileset.spacing);\n const y =\n map.tileset.margin + row * (map.tileset.tileHeight + map.tileset.spacing);\n\n return k.quad(\n x / map.tileset.imageWidth,\n y / map.tileset.imageHeight,\n map.tileset.tileWidth / map.tileset.imageWidth,\n map.tileset.tileHeight / map.tileset.imageHeight,\n );\n}\n\nexport function getLayerNames(options: TiledMapOpt): Set<string> | null {\n if (!options.layerNames?.length) {\n return null;\n }\n\n return new Set(options.layerNames);\n}\n\nfunction getParsedTile(\n map: ParsedTiledMap,\n gid: number,\n): ParsedTiledTile | undefined {\n return map.tileset.tiles[gid];\n}\n\nfunction matchesProperties(\n expected: Record<string, TiledPropertyValue> | undefined,\n actual: Record<string, TiledPropertyValue>,\n): boolean {\n if (!expected) {\n return true;\n }\n\n return Object.entries(expected).every(\n ([name, value]) => actual[name] === value,\n );\n}\n\nfunction matchesTileRule(\n match: TiledTileMatch,\n tile: TiledTileContext,\n): boolean {\n if (match.gid !== undefined && match.gid !== tile.gid) {\n return false;\n }\n\n if (match.tileId !== undefined && match.tileId !== tile.tileId) {\n return false;\n }\n\n if (match.layer !== undefined && match.layer !== tile.layer) {\n return false;\n }\n\n return matchesProperties(match.properties, tile.properties);\n}\n\nfunction matchesObjectRule(\n match: TiledObjectMatch,\n object: TiledObjectContext,\n): boolean {\n if (match.layer !== undefined && match.layer !== object.layer) {\n return false;\n }\n\n if (match.name !== undefined && match.name !== object.name) {\n return false;\n }\n\n if (match.type !== undefined && match.type !== object.type) {\n return false;\n }\n\n return matchesProperties(match.properties, object.properties);\n}\n\nexport function createLayerRenderer(\n k: KAPLAYCtx,\n layer: ParsedTiledTileLayer,\n map: ParsedTiledMap,\n sprite: string,\n): GameObj {\n return k.add([\n k.pos(0, 0),\n k.z(layer.zIndex),\n {\n draw: () => {\n layer.data.forEach((rawGid, index) => {\n const parsedGid = parseTileGid(rawGid);\n\n if (!parsedGid) {\n return;\n }\n\n const column = index % layer.width;\n const row = Math.floor(index / layer.width);\n const drawTransform = getTileDrawTransform(parsedGid.flip);\n\n k.drawSprite({\n anchor: 'center',\n angle: drawTransform.angle,\n flipX: drawTransform.flipX,\n flipY: drawTransform.flipY,\n opacity: layer.opacity,\n pos: k.vec2(\n (column + layer.x) * map.tileWidth + map.tileset.tileWidth / 2,\n (row + layer.y) * map.tileHeight + map.tileset.tileHeight / 2,\n ),\n quad: getTileQuad(k, map, parsedGid.gid),\n sprite,\n });\n });\n },\n id: 'tiled-layer',\n },\n ] as CompList<TiledLayerComp>);\n}\n\nexport function createMatchedTileObjects(\n k: KAPLAYCtx,\n layer: ParsedTiledTileLayer,\n map: ParsedTiledMap,\n options: TiledMapOpt,\n): GameObj[] {\n const rules = options.tiles;\n\n if (!rules?.length) {\n return [];\n }\n\n const tiles: GameObj[] = [];\n\n layer.data.forEach((rawGid, index) => {\n const parsedGid = parseTileGid(rawGid);\n\n if (!parsedGid) {\n return;\n }\n\n const parsedTile = getParsedTile(map, parsedGid.gid);\n const column = index % layer.width;\n const row = Math.floor(index / layer.width);\n const tile = {\n flip: parsedGid.flip,\n gid: parsedGid.gid,\n layer: layer.name,\n pos: {\n x: (column + layer.x) * map.tileWidth,\n y: (row + layer.y) * map.tileHeight,\n },\n properties: parsedTile?.properties ?? {},\n tileSize: {\n height: map.tileHeight,\n width: map.tileWidth,\n },\n tileId: parsedTile?.tileId ?? parsedGid.gid - map.tileset.firstGid,\n tilePos: {\n x: column + layer.x,\n y: row + layer.y,\n },\n };\n\n rules.forEach((rule) => {\n if (!matchesTileRule(rule.match, tile)) {\n return;\n }\n\n tiles.push(\n k.add([\n k.pos(tile.pos.x, tile.pos.y),\n k.anchor('topleft'),\n k.z(layer.zIndex),\n ...rule.comps(tile),\n ] as CompList<unknown>),\n );\n });\n });\n\n return tiles;\n}\n\nexport function createMatchedObjectObjects(\n k: KAPLAYCtx,\n layer: ParsedTiledObjectLayer,\n options: TiledMapOpt,\n): GameObj[] {\n const rules = options.objects;\n\n if (!rules?.length) {\n return [];\n }\n\n const objects: GameObj[] = [];\n\n if (!layer.visible) {\n return objects;\n }\n\n layer.objects.forEach((object) => {\n if (!object.visible) {\n return;\n }\n\n const context: TiledObjectContext = {\n id: object.id,\n layer: layer.name,\n name: object.name,\n objectSize: {\n height: object.height,\n width: object.width,\n },\n point: object.point ?? false,\n pos: {\n x: object.x,\n y: object.y,\n },\n properties: getPropertyRecord(object.properties),\n rotation: object.rotation,\n type: object.type,\n };\n\n rules.forEach((rule) => {\n if (!matchesObjectRule(rule.match, context)) {\n return;\n }\n\n objects.push(\n k.add([\n k.pos(context.pos.x, context.pos.y),\n k.anchor('topleft'),\n k.z(layer.zIndex),\n ...rule.comps(context),\n ] as CompList<unknown>),\n );\n });\n });\n\n return objects;\n}\n\nexport function parseTiledMap(data: TiledMapData): ParsedTiledMap {\n if (data.orientation !== 'orthogonal') {\n throw new Error(\n `Unsupported Tiled orientation \"${data.orientation}\". Expected \"orthogonal\".`,\n );\n }\n\n if (data.infinite) {\n throw new Error('Infinite Tiled maps are not supported.');\n }\n\n if (data.tilesets.length !== 1) {\n throw new Error('Exactly one Tiled tileset is required.');\n }\n\n const [tileset] = data.tilesets;\n\n if (tileset.columns <= 0) {\n throw new Error('Tiled tileset columns must be greater than 0.');\n }\n\n const layers = data.layers.map((layer, zIndex) => {\n if (isTileLayer(layer)) {\n if (layer.data.length !== layer.width * layer.height) {\n throw new Error(\n `Layer \"${layer.name}\" data length does not match its dimensions.`,\n );\n }\n\n return {\n ...normalizeTileLayer(layer),\n zIndex,\n };\n }\n\n if (isObjectLayer(layer)) {\n return {\n ...normalizeObjectLayer(layer),\n zIndex,\n };\n }\n\n throw new Error('Unsupported Tiled layer type.');\n });\n\n return {\n height: data.height,\n layers,\n orientation: 'orthogonal',\n tileHeight: data.tileheight,\n tileWidth: data.tilewidth,\n tileset: {\n columns: tileset.columns,\n firstGid: tileset.firstgid,\n image: tileset.image,\n imageHeight: tileset.imageheight,\n imageWidth: tileset.imagewidth,\n lastGid: tileset.firstgid + tileset.tilecount - 1,\n margin: tileset.margin ?? 0,\n name: tileset.name,\n spacing: tileset.spacing ?? 0,\n tileCount: tileset.tilecount,\n tileHeight: tileset.tileheight,\n tiles: Object.fromEntries(\n (tileset.tiles ?? []).map((tile) => [\n tile.id + tileset.firstgid,\n {\n gid: tile.id + tileset.firstgid,\n properties: getPropertyRecord(tile.properties),\n tileId: tile.id,\n },\n ]),\n ),\n tileWidth: tileset.tilewidth,\n },\n width: data.width,\n };\n}\n","import type { KAPLAYCtx } from 'kaplay';\n\nimport type { TiledMap, TiledMapOpt } from './types';\nimport {\n createLayerRenderer,\n createMatchedObjectObjects,\n createMatchedTileObjects,\n getLayerNames,\n parseTiledMap,\n parseTileGid,\n resolveTiledMap,\n} from './utils';\n\nexport type { TiledMap, TiledMapOpt } from './types';\n\ndeclare module 'kaplay' {\n interface KAPLAYCtx {\n addTiledMap: (map: TiledMap, options: TiledMapOpt) => void;\n }\n}\n\n/**\n * Add a Tiled map to the current KAPLAY context.\n *\n * The `map` argument can either be:\n * - parsed map JSON, or\n * - the asset key of a map loaded with `loadJSON()`.\n *\n * @param k - The active KAPLAY context.\n * @param map - The Tiled map data.\n * @param opt - The Tiled map options.\n */\nfunction addTiledMap(k: KAPLAYCtx, map: TiledMap, opt: TiledMapOpt): void {\n const parsedMap = parseTiledMap(resolveTiledMap(k, map));\n const allowedLayerNames = getLayerNames(opt);\n\n parsedMap.layers.forEach((layer) => {\n if (!layer.visible) {\n return;\n }\n\n if (allowedLayerNames && !allowedLayerNames.has(layer.name)) {\n return;\n }\n\n if (layer.type === 'tilelayer') {\n layer.data.forEach((rawGid) => {\n const parsedGid = parseTileGid(rawGid);\n\n if (\n parsedGid &&\n (parsedGid.gid < parsedMap.tileset.firstGid ||\n parsedGid.gid > parsedMap.tileset.lastGid)\n ) {\n throw new Error(\n `Tile gid ${String(rawGid)} is outside the supported tileset range.`,\n );\n }\n });\n\n createLayerRenderer(k, layer, parsedMap, opt.sprite);\n createMatchedTileObjects(k, layer, parsedMap, opt);\n return;\n }\n\n createMatchedObjectObjects(k, layer, opt);\n });\n}\n\n/**\n * KAPLAY plugin that adds `addTiledMap()` to the context.\n *\n * @param k - The active KAPLAY context.\n * @returns - The plugin API.\n */\nexport function tiledPlugin(k: KAPLAYCtx) {\n return {\n addTiledMap(map: TiledMap, options: TiledMapOpt) {\n addTiledMap(k, map, options);\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
(function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.KaplayPluginTiled={}))})(this,function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var t=2147483648,n=1073741824,r=536870912,i=n|-1610612736;function a(e,t){if(typeof t!=`string`)return t;let n=e.getAsset(t);if(!n)throw Error(`Tiled map asset "${t}" is not loaded.`);if(!n.data)throw Error(`Tiled map asset "${t}" is not ready yet.`);return n.data}function o(e){let t={};return e?.forEach(e=>{t[e.name]=e.value}),t}function s(e){return e.type===`objectgroup`}function c(e){return e.type===`tilelayer`}function l(e){return{data:e.data,height:e.height,name:e.name,opacity:e.opacity??1,type:`tilelayer`,visible:e.visible??!0,width:e.width,x:e.x??0,y:e.y??0,zIndex:0}}function u(e){return{name:e.name,objects:e.objects,type:`objectgroup`,visible:e.visible??!0,zIndex:0}}function d(e){return e===0?null:{gid:(e&~i)>>>0,flip:{diagonal:(e&r)!==0,horizontal:(e&t)!==0,vertical:(e&n)!==0}}}function f(e){return e.diagonal?e.horizontal&&e.vertical?{angle:270,flipX:!0,flipY:!1}:e.horizontal?{angle:270,flipX:!1,flipY:!1}:e.vertical?{angle:90,flipX:!1,flipY:!1}:{angle:270,flipX:!1,flipY:!0}:{angle:0,flipX:e.horizontal,flipY:e.vertical}}function p(e,t,n){let r=n-t.tileset.firstGid,i=r%t.tileset.columns,a=Math.floor(r/t.tileset.columns),o=t.tileset.margin+i*(t.tileset.tileWidth+t.tileset.spacing),s=t.tileset.margin+a*(t.tileset.tileHeight+t.tileset.spacing);return e.quad(o/t.tileset.imageWidth,s/t.tileset.imageHeight,t.tileset.tileWidth/t.tileset.imageWidth,t.tileset.tileHeight/t.tileset.imageHeight)}function m(e){return e.layerNames?.length?new Set(e.layerNames):null}function h(e,t){return e.tileset.tiles[t]}function g(e,t){return e?Object.entries(e).every(([e,n])=>t[e]===n):!0}function _(e,t){return e.gid!==void 0&&e.gid!==t.gid||e.tileId!==void 0&&e.tileId!==t.tileId||e.layer!==void 0&&e.layer!==t.layer?!1:g(e.properties,t.properties)}function v(e,t){return e.layer!==void 0&&e.layer!==t.layer||e.name!==void 0&&e.name!==t.name||e.type!==void 0&&e.type!==t.type?!1:g(e.properties,t.properties)}function y(e,t,n,r){return e.add([e.pos(0,0),e.z(t.zIndex),{draw:()=>{t.data.forEach((i,a)=>{let o=d(i);if(!o)return;let s=a%t.width,c=Math.floor(a/t.width),l=f(o.flip);e.drawSprite({anchor:`center`,angle:l.angle,flipX:l.flipX,flipY:l.flipY,opacity:t.opacity,pos:e.vec2((s+t.x)*n.tileWidth+n.tileset.tileWidth/2,(c+t.y)*n.tileHeight+n.tileset.tileHeight/2),quad:p(e,n,o.gid),sprite:r})})},id:`tiled-layer`}])}function b(e,t,n,r){let i=r.tiles;if(!i?.length)return[];let a=[];return t.data.forEach((r,o)=>{let s=d(r);if(!s)return;let c=h(n,s.gid),l=o%t.width,u=Math.floor(o/t.width),f={flip:s.flip,gid:s.gid,layer:t.name,pos:{x:(l+t.x)*n.tileWidth,y:(u+t.y)*n.tileHeight},properties:c?.properties??{},tileSize:{height:n.tileHeight,width:n.tileWidth},tileId:c?.tileId??s.gid-n.tileset.firstGid,tilePos:{x:l+t.x,y:u+t.y}};i.forEach(n=>{_(n.match,f)&&a.push(e.add([e.pos(f.pos.x,f.pos.y),e.anchor(`topleft`),e.z(t.zIndex),...n.comps(f)]))})}),a}function x(e,t,n){let r=n.objects;if(!r?.length)return[];let i=[];return t.visible&&t.objects.forEach(n=>{if(!n.visible)return;let a={id:n.id,layer:t.name,name:n.name,objectSize:{height:n.height,width:n.width},point:n.point??!1,pos:{x:n.x,y:n.y},properties:o(n.properties),rotation:n.rotation,type:n.type};r.forEach(n=>{v(n.match,a)&&i.push(e.add([e.pos(a.pos.x,a.pos.y),e.anchor(`topleft`),e.z(t.zIndex),...n.comps(a)]))})}),i}function S(e){if(e.orientation!==`orthogonal`)throw Error(`Unsupported Tiled orientation "${e.orientation}". Expected "orthogonal".`);if(e.infinite)throw Error(`Infinite Tiled maps are not supported.`);if(e.tilesets.length!==1)throw Error(`Exactly one Tiled tileset is required.`);let[t]=e.tilesets;if(t.columns<=0)throw Error(`Tiled tileset columns must be greater than 0.`);let n=e.layers.map((e,t)=>{if(c(e)){if(e.data.length!==e.width*e.height)throw Error(`Layer "${e.name}" data length does not match its dimensions.`);return{...l(e),zIndex:t}}if(s(e))return{...u(e),zIndex:t};throw Error(`Unsupported Tiled layer type.`)});return{height:e.height,layers:n,orientation:`orthogonal`,tileHeight:e.tileheight,tileWidth:e.tilewidth,tileset:{columns:t.columns,firstGid:t.firstgid,image:t.image,imageHeight:t.imageheight,imageWidth:t.imagewidth,lastGid:t.firstgid+t.tilecount-1,margin:t.margin??0,name:t.name,spacing:t.spacing??0,tileCount:t.tilecount,tileHeight:t.tileheight,tiles:Object.fromEntries((t.tiles??[]).map(e=>[e.id+t.firstgid,{gid:e.id+t.firstgid,properties:o(e.properties),tileId:e.id}])),tileWidth:t.tilewidth},width:e.width}}function C(e,t,n){let r=S(a(e,t)),i=m(n);r.layers.forEach(t=>{if(t.visible&&!(i&&!i.has(t.name))){if(t.type===`tilelayer`){t.data.forEach(e=>{let t=d(e);if(t&&(t.gid<r.tileset.firstGid||t.gid>r.tileset.lastGid))throw Error(`Tile gid ${String(e)} is outside the supported tileset range.`)}),y(e,t,r,n.sprite),b(e,t,r,n);return}x(e,t,n)}})}function w(e){return{addTiledMap(t,n){C(e,t,n)}}}e.tiledPlugin=w});
|
|
2
|
+
//# sourceMappingURL=plugin.umd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.umd.js","names":[],"sources":["../src/utils.ts","../src/plugin.ts"],"sourcesContent":["import type { CompList, GameObj, KAPLAYCtx, Quad } from 'kaplay';\n\nimport type {\n ParsedTiledLayer,\n ParsedTiledMap,\n ParsedTiledObjectLayer,\n ParsedTiledTile,\n ParsedTiledTileLayer,\n TiledLayer,\n TiledLayerComp,\n TiledMap,\n TiledMapData,\n TiledMapOpt,\n TiledObjectContext,\n TiledObjectLayer,\n TiledObjectMatch,\n TiledProperty,\n TiledPropertyValue,\n TiledTileContext,\n TiledTileLayer,\n TiledTileMatch,\n} from './types';\n\nconst FLIPPED_HORIZONTALLY_FLAG = 0x80000000;\nconst FLIPPED_VERTICALLY_FLAG = 0x40000000;\nconst FLIPPED_DIAGONALLY_FLAG = 0x20000000;\nconst FLIP_FLAGS =\n FLIPPED_HORIZONTALLY_FLAG | FLIPPED_VERTICALLY_FLAG | FLIPPED_DIAGONALLY_FLAG;\n\ninterface ParsedTileGid {\n gid: number;\n flip: {\n diagonal: boolean;\n horizontal: boolean;\n vertical: boolean;\n };\n}\n\nexport function resolveTiledMap(k: KAPLAYCtx, map: TiledMap): TiledMapData {\n if (typeof map !== 'string') {\n return map;\n }\n\n const asset = k.getAsset(map);\n\n if (!asset) {\n throw new Error(`Tiled map asset \"${map}\" is not loaded.`);\n }\n\n if (!asset.data) {\n throw new Error(`Tiled map asset \"${map}\" is not ready yet.`);\n }\n\n return asset.data as TiledMapData;\n}\n\nfunction getPropertyRecord(\n properties: TiledProperty[] | undefined,\n): Record<string, TiledPropertyValue> {\n const record: Record<string, TiledPropertyValue> = {};\n\n properties?.forEach((property) => {\n record[property.name] = property.value;\n });\n\n return record;\n}\n\nfunction isObjectLayer(layer: TiledLayer): layer is TiledObjectLayer {\n return layer.type === 'objectgroup';\n}\n\nfunction isTileLayer(layer: TiledLayer): layer is TiledTileLayer {\n return layer.type === 'tilelayer';\n}\n\nfunction normalizeTileLayer(layer: TiledTileLayer): ParsedTiledLayer {\n return {\n data: layer.data,\n height: layer.height,\n name: layer.name,\n opacity: layer.opacity ?? 1,\n type: 'tilelayer',\n visible: layer.visible ?? true,\n width: layer.width,\n x: layer.x ?? 0,\n y: layer.y ?? 0,\n zIndex: 0,\n };\n}\n\nfunction normalizeObjectLayer(layer: TiledObjectLayer): ParsedTiledObjectLayer {\n return {\n name: layer.name,\n objects: layer.objects,\n type: 'objectgroup',\n visible: layer.visible ?? true,\n zIndex: 0,\n };\n}\n\nexport function parseTileGid(rawGid: number): ParsedTileGid | null {\n if (rawGid === 0) {\n return null;\n }\n\n return {\n gid: (rawGid & ~FLIP_FLAGS) >>> 0,\n flip: {\n diagonal: (rawGid & FLIPPED_DIAGONALLY_FLAG) !== 0,\n horizontal: (rawGid & FLIPPED_HORIZONTALLY_FLAG) !== 0,\n vertical: (rawGid & FLIPPED_VERTICALLY_FLAG) !== 0,\n },\n };\n}\n\nfunction getTileDrawTransform(flip: ParsedTileGid['flip']): {\n angle: number;\n flipX: boolean;\n flipY: boolean;\n} {\n if (!flip.diagonal) {\n return {\n angle: 0,\n flipX: flip.horizontal,\n flipY: flip.vertical,\n };\n }\n\n if (flip.horizontal && flip.vertical) {\n return {\n angle: 270,\n flipX: true,\n flipY: false,\n };\n }\n\n if (flip.horizontal) {\n return {\n angle: 270,\n flipX: false,\n flipY: false,\n };\n }\n\n if (flip.vertical) {\n return {\n angle: 90,\n flipX: false,\n flipY: false,\n };\n }\n\n return {\n angle: 270,\n flipX: false,\n flipY: true,\n };\n}\n\nfunction getTileQuad(k: KAPLAYCtx, map: ParsedTiledMap, gid: number): Quad {\n const localTileId = gid - map.tileset.firstGid;\n const column = localTileId % map.tileset.columns;\n const row = Math.floor(localTileId / map.tileset.columns);\n const x =\n map.tileset.margin + column * (map.tileset.tileWidth + map.tileset.spacing);\n const y =\n map.tileset.margin + row * (map.tileset.tileHeight + map.tileset.spacing);\n\n return k.quad(\n x / map.tileset.imageWidth,\n y / map.tileset.imageHeight,\n map.tileset.tileWidth / map.tileset.imageWidth,\n map.tileset.tileHeight / map.tileset.imageHeight,\n );\n}\n\nexport function getLayerNames(options: TiledMapOpt): Set<string> | null {\n if (!options.layerNames?.length) {\n return null;\n }\n\n return new Set(options.layerNames);\n}\n\nfunction getParsedTile(\n map: ParsedTiledMap,\n gid: number,\n): ParsedTiledTile | undefined {\n return map.tileset.tiles[gid];\n}\n\nfunction matchesProperties(\n expected: Record<string, TiledPropertyValue> | undefined,\n actual: Record<string, TiledPropertyValue>,\n): boolean {\n if (!expected) {\n return true;\n }\n\n return Object.entries(expected).every(\n ([name, value]) => actual[name] === value,\n );\n}\n\nfunction matchesTileRule(\n match: TiledTileMatch,\n tile: TiledTileContext,\n): boolean {\n if (match.gid !== undefined && match.gid !== tile.gid) {\n return false;\n }\n\n if (match.tileId !== undefined && match.tileId !== tile.tileId) {\n return false;\n }\n\n if (match.layer !== undefined && match.layer !== tile.layer) {\n return false;\n }\n\n return matchesProperties(match.properties, tile.properties);\n}\n\nfunction matchesObjectRule(\n match: TiledObjectMatch,\n object: TiledObjectContext,\n): boolean {\n if (match.layer !== undefined && match.layer !== object.layer) {\n return false;\n }\n\n if (match.name !== undefined && match.name !== object.name) {\n return false;\n }\n\n if (match.type !== undefined && match.type !== object.type) {\n return false;\n }\n\n return matchesProperties(match.properties, object.properties);\n}\n\nexport function createLayerRenderer(\n k: KAPLAYCtx,\n layer: ParsedTiledTileLayer,\n map: ParsedTiledMap,\n sprite: string,\n): GameObj {\n return k.add([\n k.pos(0, 0),\n k.z(layer.zIndex),\n {\n draw: () => {\n layer.data.forEach((rawGid, index) => {\n const parsedGid = parseTileGid(rawGid);\n\n if (!parsedGid) {\n return;\n }\n\n const column = index % layer.width;\n const row = Math.floor(index / layer.width);\n const drawTransform = getTileDrawTransform(parsedGid.flip);\n\n k.drawSprite({\n anchor: 'center',\n angle: drawTransform.angle,\n flipX: drawTransform.flipX,\n flipY: drawTransform.flipY,\n opacity: layer.opacity,\n pos: k.vec2(\n (column + layer.x) * map.tileWidth + map.tileset.tileWidth / 2,\n (row + layer.y) * map.tileHeight + map.tileset.tileHeight / 2,\n ),\n quad: getTileQuad(k, map, parsedGid.gid),\n sprite,\n });\n });\n },\n id: 'tiled-layer',\n },\n ] as CompList<TiledLayerComp>);\n}\n\nexport function createMatchedTileObjects(\n k: KAPLAYCtx,\n layer: ParsedTiledTileLayer,\n map: ParsedTiledMap,\n options: TiledMapOpt,\n): GameObj[] {\n const rules = options.tiles;\n\n if (!rules?.length) {\n return [];\n }\n\n const tiles: GameObj[] = [];\n\n layer.data.forEach((rawGid, index) => {\n const parsedGid = parseTileGid(rawGid);\n\n if (!parsedGid) {\n return;\n }\n\n const parsedTile = getParsedTile(map, parsedGid.gid);\n const column = index % layer.width;\n const row = Math.floor(index / layer.width);\n const tile = {\n flip: parsedGid.flip,\n gid: parsedGid.gid,\n layer: layer.name,\n pos: {\n x: (column + layer.x) * map.tileWidth,\n y: (row + layer.y) * map.tileHeight,\n },\n properties: parsedTile?.properties ?? {},\n tileSize: {\n height: map.tileHeight,\n width: map.tileWidth,\n },\n tileId: parsedTile?.tileId ?? parsedGid.gid - map.tileset.firstGid,\n tilePos: {\n x: column + layer.x,\n y: row + layer.y,\n },\n };\n\n rules.forEach((rule) => {\n if (!matchesTileRule(rule.match, tile)) {\n return;\n }\n\n tiles.push(\n k.add([\n k.pos(tile.pos.x, tile.pos.y),\n k.anchor('topleft'),\n k.z(layer.zIndex),\n ...rule.comps(tile),\n ] as CompList<unknown>),\n );\n });\n });\n\n return tiles;\n}\n\nexport function createMatchedObjectObjects(\n k: KAPLAYCtx,\n layer: ParsedTiledObjectLayer,\n options: TiledMapOpt,\n): GameObj[] {\n const rules = options.objects;\n\n if (!rules?.length) {\n return [];\n }\n\n const objects: GameObj[] = [];\n\n if (!layer.visible) {\n return objects;\n }\n\n layer.objects.forEach((object) => {\n if (!object.visible) {\n return;\n }\n\n const context: TiledObjectContext = {\n id: object.id,\n layer: layer.name,\n name: object.name,\n objectSize: {\n height: object.height,\n width: object.width,\n },\n point: object.point ?? false,\n pos: {\n x: object.x,\n y: object.y,\n },\n properties: getPropertyRecord(object.properties),\n rotation: object.rotation,\n type: object.type,\n };\n\n rules.forEach((rule) => {\n if (!matchesObjectRule(rule.match, context)) {\n return;\n }\n\n objects.push(\n k.add([\n k.pos(context.pos.x, context.pos.y),\n k.anchor('topleft'),\n k.z(layer.zIndex),\n ...rule.comps(context),\n ] as CompList<unknown>),\n );\n });\n });\n\n return objects;\n}\n\nexport function parseTiledMap(data: TiledMapData): ParsedTiledMap {\n if (data.orientation !== 'orthogonal') {\n throw new Error(\n `Unsupported Tiled orientation \"${data.orientation}\". Expected \"orthogonal\".`,\n );\n }\n\n if (data.infinite) {\n throw new Error('Infinite Tiled maps are not supported.');\n }\n\n if (data.tilesets.length !== 1) {\n throw new Error('Exactly one Tiled tileset is required.');\n }\n\n const [tileset] = data.tilesets;\n\n if (tileset.columns <= 0) {\n throw new Error('Tiled tileset columns must be greater than 0.');\n }\n\n const layers = data.layers.map((layer, zIndex) => {\n if (isTileLayer(layer)) {\n if (layer.data.length !== layer.width * layer.height) {\n throw new Error(\n `Layer \"${layer.name}\" data length does not match its dimensions.`,\n );\n }\n\n return {\n ...normalizeTileLayer(layer),\n zIndex,\n };\n }\n\n if (isObjectLayer(layer)) {\n return {\n ...normalizeObjectLayer(layer),\n zIndex,\n };\n }\n\n throw new Error('Unsupported Tiled layer type.');\n });\n\n return {\n height: data.height,\n layers,\n orientation: 'orthogonal',\n tileHeight: data.tileheight,\n tileWidth: data.tilewidth,\n tileset: {\n columns: tileset.columns,\n firstGid: tileset.firstgid,\n image: tileset.image,\n imageHeight: tileset.imageheight,\n imageWidth: tileset.imagewidth,\n lastGid: tileset.firstgid + tileset.tilecount - 1,\n margin: tileset.margin ?? 0,\n name: tileset.name,\n spacing: tileset.spacing ?? 0,\n tileCount: tileset.tilecount,\n tileHeight: tileset.tileheight,\n tiles: Object.fromEntries(\n (tileset.tiles ?? []).map((tile) => [\n tile.id + tileset.firstgid,\n {\n gid: tile.id + tileset.firstgid,\n properties: getPropertyRecord(tile.properties),\n tileId: tile.id,\n },\n ]),\n ),\n tileWidth: tileset.tilewidth,\n },\n width: data.width,\n };\n}\n","import type { KAPLAYCtx } from 'kaplay';\n\nimport type { TiledMap, TiledMapOpt } from './types';\nimport {\n createLayerRenderer,\n createMatchedObjectObjects,\n createMatchedTileObjects,\n getLayerNames,\n parseTiledMap,\n parseTileGid,\n resolveTiledMap,\n} from './utils';\n\nexport type { TiledMap, TiledMapOpt } from './types';\n\ndeclare module 'kaplay' {\n interface KAPLAYCtx {\n addTiledMap: (map: TiledMap, options: TiledMapOpt) => void;\n }\n}\n\n/**\n * Add a Tiled map to the current KAPLAY context.\n *\n * The `map` argument can either be:\n * - parsed map JSON, or\n * - the asset key of a map loaded with `loadJSON()`.\n *\n * @param k - The active KAPLAY context.\n * @param map - The Tiled map data.\n * @param opt - The Tiled map options.\n */\nfunction addTiledMap(k: KAPLAYCtx, map: TiledMap, opt: TiledMapOpt): void {\n const parsedMap = parseTiledMap(resolveTiledMap(k, map));\n const allowedLayerNames = getLayerNames(opt);\n\n parsedMap.layers.forEach((layer) => {\n if (!layer.visible) {\n return;\n }\n\n if (allowedLayerNames && !allowedLayerNames.has(layer.name)) {\n return;\n }\n\n if (layer.type === 'tilelayer') {\n layer.data.forEach((rawGid) => {\n const parsedGid = parseTileGid(rawGid);\n\n if (\n parsedGid &&\n (parsedGid.gid < parsedMap.tileset.firstGid ||\n parsedGid.gid > parsedMap.tileset.lastGid)\n ) {\n throw new Error(\n `Tile gid ${String(rawGid)} is outside the supported tileset range.`,\n );\n }\n });\n\n createLayerRenderer(k, layer, parsedMap, opt.sprite);\n createMatchedTileObjects(k, layer, parsedMap, opt);\n return;\n }\n\n createMatchedObjectObjects(k, layer, opt);\n });\n}\n\n/**\n * KAPLAY plugin that adds `addTiledMap()` to the context.\n *\n * @param k - The active KAPLAY context.\n * @returns - The plugin API.\n */\nexport function tiledPlugin(k: KAPLAYCtx) {\n return {\n addTiledMap(map: TiledMap, options: TiledMapOpt) {\n addTiledMap(k, map, options);\n },\n };\n}\n"],"mappings":"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"}
|
package/global.d.ts
ADDED
package/global.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
package/package.json
CHANGED
|
@@ -1,4 +1,101 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kaplay-plugin-tiled",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "KAPLAY plugin for Tiled maps",
|
|
5
|
+
"author": "Mark <mark@remarkablemark.org> (https://remarkablemark.org)",
|
|
6
|
+
"main": "./dist/plugin.cjs",
|
|
7
|
+
"module": "./dist/plugin.mjs",
|
|
8
|
+
"types": "./dist/plugin.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./dist/plugin.d.mts",
|
|
13
|
+
"default": "./dist/plugin.mjs"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./dist/plugin.d.cts",
|
|
17
|
+
"default": "./dist/plugin.cjs"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"./global": {
|
|
21
|
+
"import": {
|
|
22
|
+
"types": "./global.d.ts",
|
|
23
|
+
"default": "./global.js"
|
|
24
|
+
},
|
|
25
|
+
"require": {
|
|
26
|
+
"types": "./global.d.ts",
|
|
27
|
+
"default": "./global.js"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "vite build",
|
|
33
|
+
"clean": "rm -rf coverage dist docs",
|
|
34
|
+
"docs": "typedoc",
|
|
35
|
+
"docs:watch": "npm run docs -- --watch",
|
|
36
|
+
"lint": "eslint .",
|
|
37
|
+
"lint:fix": "npm run lint -- --fix",
|
|
38
|
+
"lint:package": "publint",
|
|
39
|
+
"lint:tsc": "tsc",
|
|
40
|
+
"prepare": "husky",
|
|
41
|
+
"prepublishOnly": "npm run build && npm run lint && npm run lint:tsc && npm run test:ci",
|
|
42
|
+
"start": "vite --open",
|
|
43
|
+
"test": "vitest run",
|
|
44
|
+
"test:ci": "CI=true npm test -- --color",
|
|
45
|
+
"test:watch": "vitest --coverage.enabled=false"
|
|
46
|
+
},
|
|
47
|
+
"repository": {
|
|
48
|
+
"type": "git",
|
|
49
|
+
"url": "git+https://github.com/remarkablegames/kaplay-plugin-tiled.git"
|
|
50
|
+
},
|
|
51
|
+
"bugs": {
|
|
52
|
+
"url": "https://github.com/remarkablegames/kaplay-plugin-tiled/issues"
|
|
53
|
+
},
|
|
54
|
+
"keywords": [
|
|
55
|
+
"kaplay",
|
|
56
|
+
"plugin",
|
|
57
|
+
"tiled",
|
|
58
|
+
"map",
|
|
59
|
+
"json",
|
|
60
|
+
"game"
|
|
61
|
+
],
|
|
62
|
+
"peerDependencies": {
|
|
63
|
+
"kaplay": "*"
|
|
64
|
+
},
|
|
65
|
+
"devDependencies": {
|
|
66
|
+
"@commitlint/cli": "20.5.0",
|
|
67
|
+
"@commitlint/config-conventional": "20.5.0",
|
|
68
|
+
"@eslint/compat": "2.0.3",
|
|
69
|
+
"@eslint/js": "10.0.1",
|
|
70
|
+
"@types/node": "25.5.0",
|
|
71
|
+
"@vitest/coverage-v8": "4.1.0",
|
|
72
|
+
"eslint": "10.1.0",
|
|
73
|
+
"eslint-plugin-prettier": "5.5.5",
|
|
74
|
+
"eslint-plugin-simple-import-sort": "12.1.1",
|
|
75
|
+
"eslint-plugin-tsdoc": "0.5.2",
|
|
76
|
+
"globals": "17.4.0",
|
|
77
|
+
"husky": "9.1.7",
|
|
78
|
+
"kaplay": "3001.0.19",
|
|
79
|
+
"lint-staged": "16.4.0",
|
|
80
|
+
"prettier": "3.8.1",
|
|
81
|
+
"publint": "0.3.18",
|
|
82
|
+
"typedoc": "0.28.17",
|
|
83
|
+
"typescript": "5.9.3",
|
|
84
|
+
"typescript-eslint": "8.57.1",
|
|
85
|
+
"vite": "8.0.1",
|
|
86
|
+
"vite-plugin-dts": "4.5.4",
|
|
87
|
+
"vitest": "4.1.0"
|
|
88
|
+
},
|
|
89
|
+
"files": [
|
|
90
|
+
"dist/",
|
|
91
|
+
"global.d.ts",
|
|
92
|
+
"global.js"
|
|
93
|
+
],
|
|
94
|
+
"funding": [
|
|
95
|
+
{
|
|
96
|
+
"type": "github",
|
|
97
|
+
"url": "https://github.com/sponsors/remarkablemark"
|
|
98
|
+
}
|
|
99
|
+
],
|
|
100
|
+
"license": "MIT"
|
|
4
101
|
}
|