@codexo/exojs-ldtk 0.15.3 → 0.16.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/README.md +38 -20
- package/dist/esm/LdtkData.d.ts +59 -14
- package/dist/esm/LdtkData.d.ts.map +1 -0
- package/dist/esm/LdtkData.js +8 -16
- package/dist/esm/LdtkData.js.map +1 -1
- package/dist/esm/LdtkMap.d.ts +25 -6
- package/dist/esm/LdtkMap.d.ts.map +1 -0
- package/dist/esm/LdtkMap.js +88 -63
- package/dist/esm/LdtkMap.js.map +1 -1
- package/dist/esm/LdtkProject.d.ts +107 -0
- package/dist/esm/LdtkProject.d.ts.map +1 -0
- package/dist/esm/LdtkProject.js +136 -0
- package/dist/esm/LdtkProject.js.map +1 -0
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +11 -7
- package/dist/esm/ldtkExtension.d.ts +9 -5
- package/dist/esm/ldtkExtension.d.ts.map +1 -0
- package/dist/esm/ldtkExtension.js +25 -22
- package/dist/esm/ldtkExtension.js.map +1 -1
- package/dist/esm/ldtkLevelEntries.d.ts +4 -3
- package/dist/esm/ldtkLevelEntries.d.ts.map +1 -0
- package/dist/esm/ldtkLevelEntries.js +30 -26
- package/dist/esm/ldtkLevelEntries.js.map +1 -1
- package/dist/esm/ldtkParallax.d.ts +22 -0
- package/dist/esm/ldtkParallax.d.ts.map +1 -0
- package/dist/esm/ldtkParallax.js +22 -0
- package/dist/esm/ldtkParallax.js.map +1 -0
- package/dist/esm/ldtkToMapWorld.d.ts +20 -0
- package/dist/esm/ldtkToMapWorld.d.ts.map +1 -0
- package/dist/esm/ldtkToMapWorld.js +76 -0
- package/dist/esm/ldtkToMapWorld.js.map +1 -0
- package/dist/esm/ldtkToTileMap.d.ts +48 -10
- package/dist/esm/ldtkToTileMap.d.ts.map +1 -0
- package/dist/esm/ldtkToTileMap.js +410 -387
- package/dist/esm/ldtkToTileMap.js.map +1 -1
- package/dist/esm/ldtkTypes.d.ts +47 -0
- package/dist/esm/ldtkTypes.d.ts.map +1 -0
- package/dist/esm/ldtkTypes.js +57 -0
- package/dist/esm/ldtkTypes.js.map +1 -0
- package/dist/esm/loadLdtkMap.d.ts +30 -5
- package/dist/esm/loadLdtkMap.d.ts.map +1 -0
- package/dist/esm/loadLdtkMap.js +139 -133
- package/dist/esm/loadLdtkMap.js.map +1 -1
- package/dist/esm/loadLdtkProject.d.ts +17 -0
- package/dist/esm/loadLdtkProject.d.ts.map +1 -0
- package/dist/esm/loadLdtkProject.js +31 -0
- package/dist/esm/loadLdtkProject.js.map +1 -0
- package/dist/esm/public.d.ts +24 -9
- package/dist/esm/public.d.ts.map +1 -0
- package/dist/esm/public.js +11 -0
- package/dist/esm/url.d.ts +16 -0
- package/dist/esm/url.d.ts.map +1 -0
- package/dist/esm/url.js +31 -0
- package/dist/esm/url.js.map +1 -0
- package/dist/esm/validate.d.ts +27 -0
- package/dist/esm/validate.d.ts.map +1 -0
- package/dist/esm/validate.js +327 -0
- package/dist/esm/validate.js.map +1 -0
- package/package.json +10 -18
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/ldtkBinding.d.ts +0 -22
- package/dist/esm/ldtkBinding.js +0 -31
- package/dist/esm/ldtkBinding.js.map +0 -1
- package/dist/esm/register.d.ts +0 -1
- package/dist/esm/register.js +0 -17
- package/dist/esm/register.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ldtkToTileMap.js","sources":["../../../src/ldtkToTileMap.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;AAyCA;;;;;;;;;;;;;;;;AAgBG;AACG,SAAU,aAAa,CAAC,IAAc,EAAE,OAA8B,EAAA;AAC1E,IAAA,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,EAAE;IACpC,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,IAAI,GAAG,EAAmB;AAEhE,IAAA,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,UAAU,KAC7D,YAAY,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,CAAC,CACtE;IAED,OAAO,IAAI,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC;AAC1C;AAEA;AAEA;AACA,SAAS,YAAY,CACnB,KAAgB,EAChB,QAA4B,EAC5B,UAAkB,EAClB,IAAc,EACd,QAAsC,EAAA;;AAGtC,IAAA,MAAM,QAAQ,GAAG,iBAAiB,CAAC,KAAK,EAAE,IAAI,CAAC,eAAe,IAAI,EAAE,CAAC;AACrE,IAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC;AAC/D,IAAA,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC;IAEhE,MAAM,eAAe,GAAc,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC;IACzD,MAAM,aAAa,GAAgB,EAAE;IACrC,MAAM,mBAAmB,GAAkB,EAAE;;AAG7C,IAAA,MAAM,cAAc,GAAG,KAAK,CAAC,cAAc,IAAI,EAAE;IACjD,IAAI,aAAa,GAAG,CAAC;AAErB,IAAA,KAAK,MAAM,SAAS,IAAI,cAAc,EAAE;AACtC,QAAA,MAAM,aAAa,GAAG,SAAS,CAAC,UAAU;;;AAG1C,QAAA,MAAM,OAAO,GAAG,SAAS,CAAC,WAAW;AAErC,QAAA,QAAQ,SAAS,CAAC,MAAM;AACtB,YAAA,KAAK,OAAO;YACZ,KAAK,WAAW,EAAE;gBAChB,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,EAAE,OAAO,EAAE,eAAe,CAAC;AACjE,gBAAA,MAAM,KAAK,GACT,SAAS,CAAC,MAAM,KAAK;AACnB,uBAAG,SAAS,CAAC,SAAS,IAAI,EAAE;uBACzB,SAAS,CAAC,cAAc,IAAI,EAAE,CAAC;AACtC,gBAAA,MAAM,KAAK,GAAG,SAAS,CAAC,eAAe;AACvC,gBAAA,IAAI,KAAK,KAAK,SAAS,EAAE;oBACvB,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC;AAC/B,oBAAA,IAAI,GAAG;wBAAE,iBAAiB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,aAAa,CAAC;gBAC/D;AACA,gBAAA,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;gBAC1B;YACF;YAEA,KAAK,SAAS,EAAE;gBACd,MAAM,iBAAiB,GAAG,sBAAsB,CAAC,SAAS,EAAE,IAAI,CAAC;AACjE,gBAAA,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,EAAE,OAAO,EAAE,eAAe,EAAE,iBAAiB,CAAC;;;;AAIpF,gBAAA,MAAM,SAAS,GAAG,SAAS,CAAC,cAAc,IAAI,EAAE;AAChD,gBAAA,MAAM,KAAK,GAAG,SAAS,CAAC,eAAe;gBACvC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,KAAK,SAAS,EAAE;oBAC/C,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC;AAC/B,oBAAA,IAAI,GAAG;wBAAE,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,aAAa,CAAC;gBACnE;AACA,gBAAA,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;gBAC1B;YACF;YAEA,KAAK,UAAU,EAAE;AACf,gBAAA,MAAM,OAAO,GAAG,kBAAkB,CAChC,SAAS,EACT,aAAa,EACb,UAAU,EACV,aAAa,CACd;gBACD,aAAa,IAAI,SAAS,CAAC,eAAe,EAAE,MAAM,IAAI,CAAC;AACvD,gBAAA,mBAAmB,CAAC,IAAI,CACtB,IAAI,WAAW,CAAC;AACd,oBAAA,EAAE,EAAE,OAAO;oBACX,IAAI,EAAE,SAAS,CAAC,YAAY;oBAC5B,OAAO,EAAE,SAAS,CAAC,OAAO;AAC1B,oBAAA,OAAO,EAAE,SAAS,CAAC,OAAO,IAAI,CAAC;AAC/B,oBAAA,OAAO,EAAE,SAAS,CAAC,SAAS,IAAI,CAAC;AACjC,oBAAA,OAAO,EAAE,SAAS,CAAC,SAAS,IAAI,CAAC;oBACjC,OAAO;AACR,iBAAA,CAAC,CACH;gBACD;YACF;;IAEJ;IAEA,OAAO,IAAI,OAAO,CAAC;QACjB,IAAI,EAAE,KAAK,CAAC,UAAU;AACtB,QAAA,KAAK,EAAE,QAAQ;AACf,QAAA,MAAM,EAAE,SAAS;AACjB,QAAA,SAAS,EAAE,QAAQ;AACnB,QAAA,UAAU,EAAE,QAAQ;AACpB,QAAA,QAAQ,EAAE,eAAe;AACzB,QAAA,MAAM,EAAE,aAAa;AACrB,QAAA,YAAY,EAAE,mBAAmB;;;;;;AAMjC,QAAA,UAAU,EAAE;AACV,YAAA,GAAG,qBAAqB,CAAC,KAAK,CAAC,cAAc,IAAI,EAAE,CAAC;YACpD,OAAO,EAAE,KAAK,CAAC,GAAG;YAClB,OAAO,EAAE,KAAK,CAAC,GAAG;YAClB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,IAAI,QAAQ,KAAK,SAAS,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC;AAC1D,SAAA;AACF,KAAA,CAAC;AACJ;AAEA;AAEA,SAAS,aAAa,CACpB,SAA4B,EAC5B,OAAe,EACf,QAA4B,EAC5B,UAA2B,EAAA;IAE3B,OAAO,IAAI,SAAS,CAAC;AACnB,QAAA,EAAE,EAAE,OAAO;QACX,IAAI,EAAE,SAAS,CAAC,YAAY;QAC5B,KAAK,EAAE,SAAS,CAAC,MAAM;QACvB,MAAM,EAAE,SAAS,CAAC,MAAM;QACxB,QAAQ;QACR,SAAS,EAAE,SAAS,CAAC,UAAU;QAC/B,UAAU,EAAE,SAAS,CAAC,UAAU;QAChC,OAAO,EAAE,SAAS,CAAC,OAAO;AAC1B,QAAA,OAAO,EAAE,SAAS,CAAC,OAAO,IAAI,CAAC;AAC/B,QAAA,OAAO,EAAE,SAAS,CAAC,SAAS,IAAI,CAAC;AACjC,QAAA,OAAO,EAAE,SAAS,CAAC,SAAS,IAAI,CAAC;AACjC,QAAA,IAAI,UAAU,IAAI,EAAE,UAAU,EAAE,CAAC;AAClC,KAAA,CAAC;AACJ;AAEA,SAAS,iBAAiB,CACxB,KAAgB,EAChB,KAA8B,EAC9B,OAAgB,EAChB,QAAgB,EAAA;AAEhB,IAAA,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;AACxB,QAAA,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;AAC5C,QAAA,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;QAC5C,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC;YAAE;AAE7B,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,CAAC;QAC1B,IAAI,WAAW,GAAG,CAAC,IAAI,WAAW,IAAI,OAAO,CAAC,SAAS;YAAE;AAEzD,QAAA,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;AAChB,QAAA,KAAK,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,EAAE;YACtB,OAAO;YACP,WAAW;AACX,YAAA,SAAS,EAAE;AACT,gBAAA,KAAK,EAAE,CAAC,CAAC,GAAG,SAAS,MAAM,CAAC;AAC5B,gBAAA,KAAK,EAAE,CAAC,CAAC,GAAG,SAAS,MAAM,CAAC;AAC5B,gBAAA,QAAQ,EAAE,KAAK;AAChB,aAAA;AACF,SAAA,CAAC;IACJ;AACF;AAEA;AAEA;;;;;AAKG;AACI,MAAM,sBAAsB,GAAG;AAEtC;;;;;;AAMG;AACI,MAAM,yBAAyB,GAAG;AAEzC;;;;;;;;;;AAUG;AACH,SAAS,sBAAsB,CAC7B,SAA4B,EAC5B,IAAc,EAAA;AAEd,IAAA,MAAM,GAAG,GAAG,SAAS,CAAC,UAAU;AAChC,IAAA,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;AAAE,QAAA,OAAO,SAAS;IAE9C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,KAAK,SAAS,CAAC,WAAW,CAAC;AAChF,IAAA,MAAM,MAAM,GAAG,QAAQ,EAAE,aAAa,IAAI,EAAE;IAE5C,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,CAAC,sBAAsB,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;QAC7C,CAAC,yBAAyB,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;AACpD,KAAA,CAAC;AACJ;AAQA;;;;;;;;;AASG;AACH,MAAM,YAAY,GAAG,IAAI,OAAO,EAAgC;AAEhE;;;;AAIG;AACH,SAAS,oBAAoB,CAAC,KAAgB,EAAA;IAC5C,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC;AACtC,IAAA,IAAI,MAAM;AAAE,QAAA,OAAO,MAAM;IAEzB,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,sBAAsB,CAAC;IACvD,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,CAAC,yBAAyB,CAAC;IAC7D,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAO,SAAS,KAAK,QAAQ;AAAE,QAAA,OAAO,SAAS;AAEjF,IAAA,MAAM,MAAM,GAAsB;AAChC,QAAA,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAsB;AAC5C,QAAA,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,CAAmC;KAChE;AACD,IAAA,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC;AAC/B,IAAA,OAAO,MAAM;AACf;AAEA;;;;;;;;;;;;AAYG;SACa,qBAAqB,CACnC,KAAgB,EAChB,CAAS,EACT,CAAS,EAAA;IAET,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC;AAAE,QAAA,OAAO,SAAS;AAE3C,IAAA,MAAM,MAAM,GAAG,oBAAoB,CAAC,KAAK,CAAC;AAC1C,IAAA,IAAI,CAAC,MAAM;AAAE,QAAA,OAAO,SAAS;AAE7B,IAAA,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC;AAC3C,IAAA,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,CAAC;AAAE,QAAA,OAAO,SAAS;AAEpD,IAAA,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,GAAG,CAAC;AACjD;AAEA;AAEA,SAAS,kBAAkB,CACzB,SAA4B,EAC5B,SAAiB,EACjB,UAAkB,EAClB,WAAmB,EAAA;AAEnB,IAAA,MAAM,SAAS,GAAG,SAAS,CAAC,eAAe,IAAI,EAAE;IACjD,MAAM,OAAO,GAAoB,EAAE;AAEnC,IAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACzC,QAAA,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;QAC3B,IAAI,MAAM,KAAK,SAAS;YAAE;;QAE1B,MAAM,EAAE,GAAG,UAAU,GAAG,SAAS,GAAG,WAAW,GAAG,CAAC;QACnD,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACzC;AAEA,IAAA,OAAO,OAAO;AAChB;AAEA,SAAS,aAAa,CAAC,MAA0B,EAAE,EAAU,EAAA;;;AAG3D,IAAA,MAAM,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;AACzD,IAAA,MAAM,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IAC1D,OAAO;AACL,QAAA,IAAI,EAAE,WAAW;QACjB,EAAE;QACF,IAAI,EAAE,MAAM,CAAC,YAAY;QACzB,IAAI,EAAE,MAAM,CAAC,YAAY;QACzB,CAAC;QACD,CAAC;QACD,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,MAAM,EAAE,MAAM,CAAC,MAAM;AACrB,QAAA,QAAQ,EAAE,CAAC;AACX,QAAA,OAAO,EAAE,IAAI;AACb,QAAA,UAAU,EAAE,qBAAqB,CAAC,MAAM,CAAC,cAAc,CAAC;KACzD;AACH;AAEA;;;;;;;;AAQG;AACH,SAAS,qBAAqB,CAAC,MAAoC,EAAA;AACjE,IAAA,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;AAAE,QAAA,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;IACjD,MAAM,GAAG,GAAsC,EAAE;AACjD,IAAA,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;AAC1B,QAAA,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC;AACjC,QAAA,IAAI,KAAK,KAAK,SAAS,EAAE;AACvB,YAAA,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,KAAK;QACjC;IACF;AACA,IAAA,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;AAC3B;AAEA;;;;AAIG;AACH,SAAS,gBAAgB,CACvB,KAAwB,EAAA;IAGxB,OAAO,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC;AAC1C;AAEA;AACA,SAAS,YAAY,CAAC,KAAwB,EAAA;AAC5C,IAAA,QAAQ,KAAK,CAAC,MAAM;AAClB,QAAA,KAAK,KAAK;AACV,QAAA,KAAK,OAAO;AACZ,QAAA,KAAK,MAAM;AACX,QAAA,KAAK,QAAQ;AACb,QAAA,KAAK,YAAY;AACjB,QAAA,KAAK,OAAO;AACZ,QAAA,KAAK,UAAU;AACf,QAAA,KAAK,MAAM;AACX,QAAA,KAAK,OAAO;AACZ,QAAA,KAAK,WAAW;AAChB,QAAA,KAAK,MAAM;YACT,OAAO,iBAAiB,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC;;AAMzD,IAAA,IAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE;AAC3B,QAAA,IAAI,KAAK,CAAC,OAAO,KAAK,IAAI;AAAE,YAAA,OAAO,SAAS;AAC5C,QAAA,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;QAC3D,MAAM,QAAQ,GAAwB,EAAE;AACxC,QAAA,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE;YAC/B,MAAM,SAAS,GAAG,iBAAiB,CAAC,WAAW,EAAE,GAAG,CAAC;YACrD,IAAI,SAAS,KAAK,SAAS;AAAE,gBAAA,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC;QACvD;AACA,QAAA,OAAO,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;IAChC;IAMA,MAAM,IAAI,KAAK,CAAC,CAAA,qDAAA,EAAyD,KAA2B,CAAC,MAAM,CAAA,EAAA,CAAI,CAAC;AAClH;AAEA;;;;;;AAMG;AACH,SAAS,iBAAiB,CAAC,QAAgB,EAAE,KAAc,EAAA;AACzD,IAAA,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;AAAE,QAAA,OAAO,SAAS;IAE3D,QAAQ,QAAQ;AACd,QAAA,KAAK,KAAK;AACV,QAAA,KAAK,OAAO;AACZ,QAAA,KAAK,MAAM;AACX,QAAA,KAAK,QAAQ;AACb,QAAA,KAAK,YAAY;AACjB,QAAA,KAAK,OAAO;AACZ,QAAA,KAAK,UAAU;AACf,QAAA,KAAK,MAAM;AACT,YAAA,OAAO,KAAkC;QAE3C,KAAK,OAAO,EAAE;YACZ,MAAM,CAAC,GAAG,KAAmC;AAC7C,YAAA,OAAO,EAAE,IAAI,EAAE,gBAAgB,CAAC,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE;QAC7D;QAEA,KAAK,WAAW,EAAE;YAChB,MAAM,CAAC,GAAG,KAAoF;YAC9F,OAAO;gBACL,IAAI,EAAE,gBAAgB,CAAC,SAAS;gBAChC,EAAE,EAAE,CAAC,CAAC,SAAS;gBACf,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,QAAQ,EAAE,CAAC,CAAC,QAAQ;aACrB;QACH;QAEA,KAAK,MAAM,EAAE;YACX,MAAM,CAAC,GAAG,KAA2E;AACrF,YAAA,OAAO,EAAE,IAAI,EAAE,gBAAgB,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;QACrG;AAEA,QAAA;;;;AAIE,YAAA,OAAO,SAAS;;AAEtB;AAEA;AAEA,SAAS,iBAAiB,CAAC,KAAgB,EAAE,QAAgB,EAAA;AAC3D,IAAA,MAAM,SAAS,GAAG,KAAK,CAAC,cAAc,IAAI,EAAE;AAC5C,IAAA,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE;AAC7B,QAAA,IAAI,KAAK,CAAC,MAAM,KAAK,UAAU,IAAI,KAAK,CAAC,UAAU,GAAG,CAAC,EAAE;YACvD,OAAO,KAAK,CAAC,UAAU;QACzB;IACF;AACA,IAAA,OAAO,QAAQ;AACjB;;;;"}
|
|
1
|
+
{"version":3,"file":"ldtkToTileMap.js","names":[],"sources":["../../src/ldtkToTileMap.ts"],"sourcesContent":["import type { TileCellSource, TileMapObject, TileProperties, TilePropertyValue, TileSet } from '@codexo/exojs-tilemap';\nimport { ObjectLayer, TILE_TRANSFORM_IDENTITY, TileLayer, TileMap, TilePropertyKind } from '@codexo/exojs-tilemap';\n\nimport type { LdtkData, LdtkEntityInstance, LdtkFieldInstance, LdtkIntGridValueDef, LdtkLayerInstance, LdtkLevel, LdtkTileData } from './LdtkData';\nimport { LDTK_FLIP_X, LDTK_FLIP_Y } from './LdtkData';\nimport { getLdtkLevelEntries } from './ldtkLevelEntries';\nimport { LdtkMap } from './LdtkMap';\nimport type { LdtkLayerParallax } from './ldtkParallax';\nimport { resolveLdtkLayerParallax } from './ldtkParallax';\n\n// ── Public API ────────────────────────────────────────────────────────────────\n\n/**\n * Options for {@link ldtkToTileMap}.\n */\nexport interface LdtkToTileMapOptions {\n /**\n * Source URL of the loaded `.ldtk` file, used as {@link LdtkMap.source}.\n * Defaults to an empty string when omitted (e.g. programmatic / test usage).\n */\n readonly source?: string;\n /**\n * Pre-loaded runtime {@link TileSet}s keyed by LDtk tileset UID.\n *\n * When provided, tile layers are populated with tile data from\n * `gridTiles` / `autoLayerTiles`. Without this map, tile layers are created\n * with the correct dimensions but no tiles are placed - only entity and\n * object layers carry data.\n *\n * Populate via {@link import('./loadLdtkMap').loadLdtkMap} for asset-loading\n * flows, or pass a hand-crafted map for testing.\n */\n readonly tilesets?: ReadonlyMap<number, TileSet>;\n}\n\n/**\n * Convert a raw {@link LdtkData} document into an {@link LdtkMap} containing\n * one runtime {@link TileMap} per LDtk level.\n *\n * Tile layers (`Tiles` / `AutoLayer`) become renderable `TileLayer`s. IntGrid\n * layers become dimension-correct `TileLayer`s - tile data is placed only when\n * the layer carries `autoLayerTiles`. Entity layers become data-only\n * `ObjectLayer`s with entity position, size, and scalar field properties.\n *\n * Pass `options.tilesets` to populate tile data; omit it for structure-only\n * conversion (useful in unit tests that do not need textures).\n *\n * Transparently handles both LDtk root shapes via {@link getLdtkLevelEntries}:\n * single-world (`data.levels`) and multi-world (`data.worlds[].levels`) - in\n * the latter case every converted level's `TileMap.properties` is additionally\n * tagged with its owning world's iid under the reserved `ldtkWorldIid` key.\n */\nexport const ldtkToTileMap = (data: LdtkData, options?: LdtkToTileMapOptions): LdtkMap => {\n const source = options?.source ?? '';\n const tilesets = options?.tilesets ?? new Map<number, TileSet>();\n\n const levels = getLdtkLevelEntries(data).map((entry, levelIndex) => convertLevel(entry.level, entry.worldIid, levelIndex, data, tilesets));\n\n return new LdtkMap(source, data, levels);\n};\n\n// ── Level conversion ──────────────────────────────────────────────────────────\n\n/**\n * Convert one already-resolved LDtk level into its runtime {@link TileMap}.\n *\n * `level.layerInstances` must be present: an externalized level has to have its\n * `.ldtkl` payload merged in first, or the result is an empty map.\n * @internal\n */\nexport const ldtkLevelToTileMap = (\n level: LdtkLevel,\n worldIid: string | undefined,\n levelIndex: number,\n data: LdtkData,\n tilesets: ReadonlyMap<number, TileSet>,\n): TileMap => convertLevel(level, worldIid, levelIndex, data, tilesets);\n\nconst convertLevel = (level: LdtkLevel, worldIid: string | undefined, levelIndex: number, data: LdtkData, tilesets: ReadonlyMap<number, TileSet>): TileMap => {\n // Derive map-level tile size from the first non-entity layer, or fall back.\n const gridSize = pickLevelGridSize(level, data.defaultGridSize ?? 16);\n const mapWidth = Math.max(1, Math.ceil(level.pxWid / gridSize));\n const mapHeight = Math.max(1, Math.ceil(level.pxHei / gridSize));\n\n const runtimeTilesets: TileSet[] = [...tilesets.values()];\n const runtimeLayers: TileLayer[] = [];\n const runtimeObjectLayers: ObjectLayer[] = [];\n\n // LDtk stores layers top-to-bottom (first = top-most); preserve that order.\n const layerInstances = level.layerInstances ?? [];\n let entityCounter = 0;\n\n for (const layerInst of layerInstances) {\n // Layer IDs must be unique within a TileMap (= one level).\n // Use layerDefUid directly - it is unique per layer definition in the file.\n const layerId = layerInst.layerDefUid;\n const parallax = resolveLdtkLayerParallax(data, layerInst);\n\n switch (layerInst.__type) {\n case 'Tiles':\n case 'AutoLayer':\n runtimeLayers.push(convertTilesOrAutoLayer(layerInst, layerId, runtimeTilesets, tilesets, parallax));\n break;\n\n case 'IntGrid':\n runtimeLayers.push(convertIntGridLayer(layerInst, layerId, runtimeTilesets, tilesets, data, parallax));\n break;\n\n case 'Entities':\n runtimeObjectLayers.push(convertEntitiesLayer(layerInst, layerId, levelIndex, entityCounter, parallax));\n entityCounter += layerInst.entityInstances?.length ?? 0;\n break;\n }\n }\n\n return new TileMap({\n name: level.identifier,\n width: mapWidth,\n height: mapHeight,\n tileWidth: gridSize,\n tileHeight: gridSize,\n tilesets: runtimeTilesets,\n layers: runtimeLayers,\n objectLayers: runtimeObjectLayers,\n properties: buildLdtkLevelProperties(level, worldIid),\n });\n};\n\n/**\n * The property bag a level contributes to its runtime representation - user\n * fields first, then the reserved LDtk keys, so a same-named user field can\n * never clobber them. `ldtkWorldIid` is added only for multi-world documents;\n * a single-world document's properties stay exactly as they were before\n * multi-world support existed.\n * @internal\n */\nexport const buildLdtkLevelProperties = (level: LdtkLevel, worldIid: string | undefined): TileProperties => ({\n ...convertFieldInstances(level.fieldInstances ?? []),\n ldtkUid: level.uid,\n ldtkIid: level.iid,\n worldX: level.worldX,\n worldY: level.worldY,\n ...(worldIid !== undefined && { ldtkWorldIid: worldIid }),\n});\n\n// ── Helpers: per-layer-type level conversion ─────────────────────────────────\n\n/** Convert a `Tiles`/`AutoLayer` LDtk layer instance into a runtime {@link TileLayer}. */\nconst convertTilesOrAutoLayer = (\n layerInst: LdtkLayerInstance,\n layerId: number,\n runtimeTilesets: readonly TileSet[],\n tilesets: ReadonlyMap<number, TileSet>,\n parallax: LdtkLayerParallax,\n): TileLayer => {\n const rLayer = makeTileLayer(layerInst, layerId, runtimeTilesets, parallax);\n const tiles = layerInst.__type === 'Tiles' ? (layerInst.gridTiles ?? []) : (layerInst.autoLayerTiles ?? []);\n const tsUid = layerInst.__tilesetDefUid;\n if (tsUid !== undefined && tsUid !== null) {\n const rts = tilesets.get(tsUid);\n if (rts) populateTileLayer(rLayer, tiles, rts, layerInst.__gridSize);\n }\n return rLayer;\n};\n\n/** Convert an `IntGrid` LDtk layer instance into a runtime {@link TileLayer}. */\nconst convertIntGridLayer = (\n layerInst: LdtkLayerInstance,\n layerId: number,\n runtimeTilesets: readonly TileSet[],\n tilesets: ReadonlyMap<number, TileSet>,\n data: LdtkData,\n parallax: LdtkLayerParallax,\n): TileLayer => {\n const intGridProperties = buildIntGridProperties(layerInst, data);\n const rLayer = makeTileLayer(layerInst, layerId, runtimeTilesets, parallax, intGridProperties);\n // IntGrid layers may carry auto-tiles when \"Auto-layer\" rules are\n // configured. Use those for rendering; raw intGridCsv is exposed as\n // data-only layer properties (see buildIntGridProperties).\n const autoTiles = layerInst.autoLayerTiles ?? [];\n const tsUid = layerInst.__tilesetDefUid;\n if (autoTiles.length > 0 && tsUid !== undefined && tsUid !== null) {\n const rts = tilesets.get(tsUid);\n if (rts) populateTileLayer(rLayer, autoTiles, rts, layerInst.__gridSize);\n }\n return rLayer;\n};\n\n/** Convert an `Entities` LDtk layer instance into a runtime {@link ObjectLayer}. */\nconst convertEntitiesLayer = (\n layerInst: LdtkLayerInstance,\n layerId: number,\n levelIndex: number,\n entityCounter: number,\n parallax: LdtkLayerParallax,\n): ObjectLayer => {\n const objects = convertEntityLayer(layerInst, layerInst.__gridSize, levelIndex, entityCounter);\n return new ObjectLayer({\n id: layerId,\n name: layerInst.__identifier,\n visible: layerInst.visible,\n opacity: layerInst.opacity ?? 1,\n offsetX: parallax.offsetX + (layerInst.pxOffsetX ?? 0),\n offsetY: parallax.offsetY + (layerInst.pxOffsetY ?? 0),\n parallaxX: parallax.parallaxX,\n parallaxY: parallax.parallaxY,\n parallaxScale: parallax.parallaxScale,\n objects,\n });\n};\n\n// ── Helpers: TileLayer ────────────────────────────────────────────────────────\n\nconst makeTileLayer = (\n layerInst: LdtkLayerInstance,\n layerId: number,\n tilesets: readonly TileSet[],\n parallax: LdtkLayerParallax,\n properties?: TileProperties,\n): TileLayer =>\n new TileLayer({\n id: layerId,\n name: layerInst.__identifier,\n width: layerInst.__cWid,\n height: layerInst.__cHei,\n tilesets,\n tileWidth: layerInst.__gridSize,\n tileHeight: layerInst.__gridSize,\n visible: layerInst.visible,\n opacity: layerInst.opacity ?? 1,\n offsetX: parallax.offsetX + (layerInst.pxOffsetX ?? 0),\n offsetY: parallax.offsetY + (layerInst.pxOffsetY ?? 0),\n parallaxX: parallax.parallaxX,\n parallaxY: parallax.parallaxY,\n parallaxScale: parallax.parallaxScale,\n ...(properties && { properties }),\n });\n\nconst populateTileLayer = (layer: TileLayer, tiles: readonly LdtkTileData[], tileset: TileSet, gridSize: number): void => {\n for (const tile of tiles) {\n const tx = Math.floor(tile.px[0] / gridSize);\n const ty = Math.floor(tile.px[1] / gridSize);\n if (!layer.inBounds(tx, ty)) continue;\n\n const localTileId = tile.t;\n if (localTileId < 0 || localTileId >= tileset.tileCount) continue;\n\n const f = tile.f;\n layer.setTileAt(tx, ty, {\n tileset,\n localTileId,\n transform: {\n flipX: (f & LDTK_FLIP_X) !== 0,\n flipY: (f & LDTK_FLIP_Y) !== 0,\n diagonal: false,\n },\n });\n }\n};\n\n// ── Helpers: IntGrid ──────────────────────────────────────────────────────────\n\n/**\n * Reserved {@link TileLayer.properties} key holding the JSON-encoded raw\n * IntGrid CSV array (`readonly number[]`) for a `TileLayer` converted from an\n * LDtk `IntGrid` layer instance. Index = `y * layer.width + x`; `0` = empty.\n * Prefer {@link getLdtkIntGridValueAt} over reading this directly.\n */\nexport const ldtkIntGridCsvProperty = 'ldtkIntGridCsv';\n\n/**\n * Reserved {@link TileLayer.properties} key holding the JSON-encoded\n * {@link LdtkIntGridValueDef} array for a `TileLayer` converted from an LDtk\n * `IntGrid` layer instance - the raw-int → named/coloured mapping declared on\n * the owning layer definition (`data.defs.layers[].intGridValues`).\n * Prefer {@link getLdtkIntGridValueAt} over reading this directly.\n */\nexport const ldtkIntGridValuesProperty = 'ldtkIntGridValues';\n\n/**\n * Build the reserved IntGrid properties for a `TileLayer` from an LDtk\n * `IntGrid` layer instance, or `undefined` when the layer carries no\n * `intGridCsv` data (nothing to expose).\n *\n * {@link TileLayer.properties} values are scalar-only, so the raw CSV array\n * and the value-definition mapping are JSON-encoded into two reserved string\n * properties rather than stored as nested structures - the same\n * `properties`-bag mechanism the Tiled adapter already uses for per-layer\n * metadata, just serialized to fit its scalar-only value type.\n */\nconst buildIntGridProperties = (layerInst: LdtkLayerInstance, data: LdtkData): TileProperties | undefined => {\n const csv = layerInst.intGridCsv;\n if (!csv || csv.length === 0) return undefined;\n\n const layerDef = data.defs.layers.find(def => def.uid === layerInst.layerDefUid);\n const values = layerDef?.intGridValues ?? [];\n\n return Object.freeze({\n [ldtkIntGridCsvProperty]: JSON.stringify(csv),\n [ldtkIntGridValuesProperty]: JSON.stringify(values),\n });\n};\n\n/** Parsed, cached form of a `TileLayer`'s {@link ldtkIntGridCsvProperty} / {@link ldtkIntGridValuesProperty}. */\ninterface ParsedIntGridData {\n readonly csv: readonly number[];\n readonly values: readonly LdtkIntGridValueDef[];\n}\n\n/**\n * Per-`TileLayer` cache of parsed IntGrid CSV/value-defs data, populated\n * lazily on first {@link getLdtkIntGridValueAt} lookup for a given layer.\n *\n * Keyed by the `TileLayer` instance itself (`WeakMap`), so an entry is\n * naturally garbage-collected once the layer it was derived from is no\n * longer referenced - no manual invalidation needed since\n * {@link TileLayer.properties} is frozen and copied at construction time and\n * can never change afterwards.\n */\nconst intGridCache = new WeakMap<TileLayer, ParsedIntGridData>();\n\n/**\n * Parse (or retrieve from {@link intGridCache}) the IntGrid CSV/value-defs\n * data attached to `layer`, or `undefined` when `layer` carries no such data\n * (not converted from an IntGrid layer instance).\n */\nconst getParsedIntGridData = (layer: TileLayer): ParsedIntGridData | undefined => {\n const cached = intGridCache.get(layer);\n if (cached) return cached;\n\n const csvRaw = layer.properties[ldtkIntGridCsvProperty];\n const valuesRaw = layer.properties[ldtkIntGridValuesProperty];\n if (typeof csvRaw !== 'string' || typeof valuesRaw !== 'string') return undefined;\n\n const parsed: ParsedIntGridData = {\n csv: JSON.parse(csvRaw) as readonly number[],\n values: JSON.parse(valuesRaw) as readonly LdtkIntGridValueDef[],\n };\n intGridCache.set(layer, parsed);\n return parsed;\n};\n\n/**\n * Look up the named/coloured {@link LdtkIntGridValueDef} at a tile coordinate\n * on a `TileLayer` converted from an LDtk `IntGrid` layer instance.\n *\n * Returns `undefined` when the coordinate is out of bounds, the cell's raw\n * value is `0` (empty), the raw value has no matching definition, or `layer`\n * was not converted from an IntGrid layer instance (no IntGrid data attached\n * via {@link ldtkIntGridCsvProperty} / {@link ldtkIntGridValuesProperty}).\n *\n * The underlying JSON-encoded CSV/value-defs properties are parsed once per\n * layer and cached (see {@link getParsedIntGridData}) - safe to call from a\n * hot path (e.g. per-cell or per-frame collision/classification checks).\n */\nexport const getLdtkIntGridValueAt = (layer: TileLayer, x: number, y: number): LdtkIntGridValueDef | undefined => {\n // `inBounds()` is unconditionally true for an unbounded layer (it has no\n // fixed grid to be out of), but the flat IntGrid CSV this function reads\n // is inherently a bounded-grid concept - LDtk itself only ever produces\n // bounded layers today, but `layer` is typed generically, so guard here\n // rather than let `layer.width` narrow away from `number | undefined`.\n if (!layer.inBounds(x, y) || layer.width === undefined) return undefined;\n\n const parsed = getParsedIntGridData(layer);\n if (!parsed) return undefined;\n\n const raw = parsed.csv[y * layer.width + x];\n if (raw === undefined || raw === 0) return undefined;\n\n return parsed.values.find(v => v.value === raw);\n};\n\n/**\n * Per-cell collision classification for a `TileLayer` converted from an LDtk\n * `IntGrid` layer instance, or `undefined` when the layer carries no IntGrid\n * data (not converted from an IntGrid layer instance, or unbounded).\n *\n * The classification is the value's LDtk-authored identifier, falling back to\n * the raw integer as a string when the value definition declares none. Cells\n * whose raw value is `0` (empty) classify as `null`. Distinct IntGrid values\n * stay distinct strings: what they mean - solid, water, hazard - is the\n * caller's to decide, and an unrecognised value is data, not an error.\n *\n * The result reads the layer's frozen IntGrid data, so it is stable for the\n * lifetime of the layer and safe to hand to a consumer that samples it while\n * building geometry.\n *\n * ```ts\n * const geometry = buildTileCollisionGeometry(layer, { cells: createLdtkIntGridCellSource(layer) });\n * ```\n */\nexport const createLdtkIntGridCellSource = (layer: TileLayer): TileCellSource | undefined => {\n const parsed = getParsedIntGridData(layer);\n const width = layer.width;\n\n // The flat IntGrid CSV is indexed by row stride, which an unbounded layer\n // has no value for; LDtk never produces one, but `layer` is typed generically.\n if (!parsed || width === undefined) return undefined;\n\n const identifiers = new Map<number, string>();\n\n for (const value of parsed.values) {\n identifiers.set(value.value, value.identifier ?? String(value.value));\n }\n\n return (tx, ty) => {\n if (!layer.inBounds(tx, ty)) return null;\n\n const raw = parsed.csv[ty * width + tx];\n\n if (raw === undefined || raw === 0) return null;\n\n return identifiers.get(raw) ?? String(raw);\n };\n};\n\n// ── Helpers: ObjectLayer ──────────────────────────────────────────────────────\n\nconst convertEntityLayer = (layerInst: LdtkLayerInstance, _gridSize: number, levelIndex: number, baseCounter: number): TileMapObject[] => {\n const instances = layerInst.entityInstances ?? [];\n const objects: TileMapObject[] = [];\n\n for (let i = 0; i < instances.length; i++) {\n const entity = instances[i];\n if (entity === undefined) continue;\n // Build a deterministic numeric id: (levelIndex * 1_000_000) + counter.\n const id = levelIndex * 1_000_000 + baseCounter + i;\n objects.push(convertEntity(entity, id));\n }\n\n return objects;\n};\n\nconst convertEntity = (entity: LdtkEntityInstance, id: number): TileMapObject => {\n // entity.px is the pivot-adjusted anchor, not the bounding box's top-left\n // corner - undo the pivot offset to recover the corner TileMapObject expects.\n const x = entity.px[0] - entity.width * entity.__pivot[0];\n const y = entity.px[1] - entity.height * entity.__pivot[1];\n return {\n kind: 'rectangle',\n id,\n // The iid is the only identity LDtk guarantees stable across re-export and\n // level re-ordering, which is what a spawn session and a savegame key on;\n // the numeric id above is derived from document position and is not.\n sourceId: entity.iid,\n name: entity.__identifier,\n type: entity.__identifier,\n x,\n y,\n width: entity.width,\n height: entity.height,\n rotation: 0,\n visible: true,\n properties: convertFieldInstances(entity.fieldInstances),\n source: entity,\n };\n};\n\n/**\n * Project LDtk field instances to a flat {@link TileProperties} bag.\n * Every LDtk field type maps to a canonical {@link TilePropertyValue}\n * (scalars pass through; `Point`/`EntityRef`/`Tile` become their tagged\n * structured variants; `Array<T>` fields recursively convert each element).\n * A field whose raw `__value` is `null` (LDtk's \"not set\" convention) is\n * omitted from the bag entirely, matching the property-absent case rather\n * than a present-but-null value.\n */\nconst convertFieldInstances = (fields: readonly LdtkFieldInstance[]): TileProperties => {\n if (fields.length === 0) return Object.freeze({});\n const out: Record<string, TilePropertyValue> = {};\n for (const field of fields) {\n const value = convertField(field);\n if (value !== undefined) {\n out[field.__identifier] = value;\n }\n }\n return Object.freeze(out);\n};\n\n/**\n * Type guard narrowing to the `Array<T>` member of {@link LdtkFieldInstance}.\n * `String.prototype.startsWith` alone does not narrow a template-literal\n * union member for the compiler; a predicate on `field` itself does.\n */\nconst isLdtkArrayField = (field: LdtkFieldInstance): field is Extract<LdtkFieldInstance, { readonly __type: `Array<${string}>` }> =>\n field.__type.startsWith('Array<');\n\n/** Convert one {@link LdtkFieldInstance} to its canonical {@link TilePropertyValue}, or `undefined` for a `null` (unset) field. */\nconst convertField = (field: LdtkFieldInstance): TilePropertyValue | undefined => {\n switch (field.__type) {\n case 'Int':\n case 'Float':\n case 'Bool':\n case 'String':\n case 'Multilines':\n case 'Color':\n case 'FilePath':\n case 'Enum':\n case 'Point':\n case 'EntityRef':\n case 'Tile':\n return mapLdtkFieldValue(field.__type, field.__value);\n\n default:\n break;\n }\n\n if (isLdtkArrayField(field)) {\n if (field.__value === null) return undefined;\n const elementType = field.__type.slice('Array<'.length, -1);\n const elements: TilePropertyValue[] = [];\n for (const raw of field.__value) {\n const converted = mapLdtkFieldValue(elementType, raw);\n if (converted !== undefined) elements.push(converted);\n }\n return Object.freeze(elements);\n }\n\n // Exhaustiveness check: if LDtk ever adds a new field type, `field` will\n // fail to narrow to `never` here and tsc will error.\n const _exhaustive: never = field;\n void _exhaustive;\n throw new Error(`convertFieldInstances: unrecognised LDtk field type \"${(field as LdtkFieldInstance).__type}\".`);\n};\n\n/**\n * Map a single raw LDtk field value (or array element) to its canonical\n * {@link TilePropertyValue}, given the LDtk type name it was declared with.\n * Shared by {@link convertField} (top-level fields) and array-element\n * conversion (`typeName` is the `T` extracted from an `Array<T>` field).\n * Returns `undefined` for a `null` value or an unrecognised `typeName`.\n */\nconst mapLdtkFieldValue = (typeName: string, value: unknown): TilePropertyValue | undefined => {\n if (value === null || value === undefined) return undefined;\n\n switch (typeName) {\n case 'Int':\n case 'Float':\n case 'Bool':\n case 'String':\n case 'Multilines':\n case 'Color':\n case 'FilePath':\n case 'Enum':\n return value as string | number | boolean;\n\n case 'Point': {\n const v = value as { cx: number; cy: number };\n return { kind: TilePropertyKind.Point, cx: v.cx, cy: v.cy };\n }\n\n case 'EntityRef': {\n const v = value as { entityIid: string; layerIid: string; levelIid: string; worldIid: string };\n return {\n kind: TilePropertyKind.ObjectRef,\n id: v.entityIid,\n layerIid: v.layerIid,\n levelIid: v.levelIid,\n worldIid: v.worldIid,\n };\n }\n\n case 'Tile': {\n const v = value as { tilesetUid: number; x: number; y: number; w: number; h: number };\n return { kind: TilePropertyKind.TileRef, tilesetUid: v.tilesetUid, x: v.x, y: v.y, w: v.w, h: v.h };\n }\n\n default:\n // Unknown/unsupported array element type (e.g. a future LDtk type\n // inside Array<T>) - skip rather than throw, since this path is not\n // compiler-exhaustive (element types are plain runtime strings).\n return undefined;\n }\n};\n\n// ── Helpers: grid size ────────────────────────────────────────────────────────\n\nconst pickLevelGridSize = (level: LdtkLevel, fallback: number): number => {\n const instances = level.layerInstances ?? [];\n for (const layer of instances) {\n if (layer.__type !== 'Entities' && layer.__gridSize > 0) {\n return layer.__gridSize;\n }\n }\n return fallback;\n};\n\n// Re-export identity transform constant for convenience (tree-shake friendly).\nexport { TILE_TRANSFORM_IDENTITY };\n"],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { AssetFactory } from '@codexo/exojs';
|
|
2
|
+
import { AssetType } from '@codexo/exojs';
|
|
3
|
+
import { LdtkMap } from './LdtkMap';
|
|
4
|
+
import { LdtkProject } from './LdtkProject';
|
|
5
|
+
/**
|
|
6
|
+
* A fully assembled LDtk world: every referenced tileset image loaded, every
|
|
7
|
+
* externalized `.ldtkl` level resolved, and one runtime
|
|
8
|
+
* {@link import('@codexo/exojs-tilemap').TileMap} per level.
|
|
9
|
+
*
|
|
10
|
+
* It claims the `.ldtk` suffix, so a bare `.ldtk` path on a loader that has
|
|
11
|
+
* this type installed resolves here rather than to {@link LdtkProjectAssetType}.
|
|
12
|
+
*/
|
|
13
|
+
export declare class LdtkMapAssetType extends AssetType<void, LdtkMap> {
|
|
14
|
+
readonly id = "ldtkMap";
|
|
15
|
+
readonly extensions: string[];
|
|
16
|
+
readonly _token: typeof LdtkMap;
|
|
17
|
+
/**
|
|
18
|
+
* The document is acquired as an ordinary JSON asset by the factory, so one
|
|
19
|
+
* `.ldtk` file is downloaded and cached once however many LDtk types read it.
|
|
20
|
+
*/
|
|
21
|
+
unacquiredSource(): {
|
|
22
|
+
source: void;
|
|
23
|
+
};
|
|
24
|
+
createFactory(): AssetFactory<void, LdtkMap>;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The streaming entry point: an LDtk world's layout and tileset atlases, with
|
|
28
|
+
* no level payload loaded.
|
|
29
|
+
*
|
|
30
|
+
* It claims no suffix, so a bare `.ldtk` path keeps resolving to the eager
|
|
31
|
+
* {@link LdtkMapAssetType} it always did. Both read the same URL, and loading
|
|
32
|
+
* one does not make the other resident. Levels are loaded and unloaded
|
|
33
|
+
* individually through {@link LdtkProject.createRuntime}.
|
|
34
|
+
*/
|
|
35
|
+
export declare class LdtkProjectAssetType extends AssetType<void, LdtkProject> {
|
|
36
|
+
readonly id = "ldtkProject";
|
|
37
|
+
readonly _token: typeof LdtkProject;
|
|
38
|
+
unacquiredSource(): {
|
|
39
|
+
source: void;
|
|
40
|
+
};
|
|
41
|
+
createFactory(): AssetFactory<void, LdtkProject>;
|
|
42
|
+
}
|
|
43
|
+
/** The eager LDtk world asset type. Install it through `ldtkExtension`. */
|
|
44
|
+
export declare const ldtkMapType: LdtkMapAssetType;
|
|
45
|
+
/** The streaming LDtk project asset type. Install it through `ldtkExtension`. */
|
|
46
|
+
export declare const ldtkProjectType: LdtkProjectAssetType;
|
|
47
|
+
//# sourceMappingURL=ldtkTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ldtkTypes.d.ts","sourceRoot":"","sources":["../../src/ldtkTypes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAI5C;;;;;;;GAOG;AACH,qBAAa,gBAAiB,SAAQ,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC;IAC5D,SAAgB,EAAE,aAAa;IAC/B,SAAyB,UAAU,WAAY;IAC/C,SAAyB,MAAM,iBAAW;IAE1C;;;OAGG;IACa,gBAAgB,IAAI;QAAE,MAAM,EAAE,IAAI,CAAA;KAAE;IAI7C,aAAa,IAAI,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC;CAGpD;AAED;;;;;;;;GAQG;AACH,qBAAa,oBAAqB,SAAQ,SAAS,CAAC,IAAI,EAAE,WAAW,CAAC;IACpE,SAAgB,EAAE,iBAAiB;IACnC,SAAyB,MAAM,qBAAe;IAE9B,gBAAgB,IAAI;QAAE,MAAM,EAAE,IAAI,CAAA;KAAE;IAI7C,aAAa,IAAI,YAAY,CAAC,IAAI,EAAE,WAAW,CAAC;CAGxD;AAED,2EAA2E;AAC3E,eAAO,MAAM,WAAW,kBAAyB,CAAC;AAClD,iFAAiF;AACjF,eAAO,MAAM,eAAe,sBAA6B,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { LdtkMap } from "./LdtkMap.js";
|
|
2
|
+
import { LdtkProject } from "./LdtkProject.js";
|
|
3
|
+
import { loadLdtkMap } from "./loadLdtkMap.js";
|
|
4
|
+
import { loadLdtkProject } from "./loadLdtkProject.js";
|
|
5
|
+
import { AssetType } from "@codexo/exojs";
|
|
6
|
+
|
|
7
|
+
//#region src/ldtkTypes.ts
|
|
8
|
+
/**
|
|
9
|
+
* A fully assembled LDtk world: every referenced tileset image loaded, every
|
|
10
|
+
* externalized `.ldtkl` level resolved, and one runtime
|
|
11
|
+
* {@link import('@codexo/exojs-tilemap').TileMap} per level.
|
|
12
|
+
*
|
|
13
|
+
* It claims the `.ldtk` suffix, so a bare `.ldtk` path on a loader that has
|
|
14
|
+
* this type installed resolves here rather than to {@link LdtkProjectAssetType}.
|
|
15
|
+
*/
|
|
16
|
+
var LdtkMapAssetType = class extends AssetType {
|
|
17
|
+
id = "ldtkMap";
|
|
18
|
+
extensions = ["ldtk"];
|
|
19
|
+
_token = LdtkMap;
|
|
20
|
+
/**
|
|
21
|
+
* The document is acquired as an ordinary JSON asset by the factory, so one
|
|
22
|
+
* `.ldtk` file is downloaded and cached once however many LDtk types read it.
|
|
23
|
+
*/
|
|
24
|
+
unacquiredSource() {
|
|
25
|
+
return { source: void 0 };
|
|
26
|
+
}
|
|
27
|
+
createFactory() {
|
|
28
|
+
return { create: (_source, context) => loadLdtkMap(context) };
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* The streaming entry point: an LDtk world's layout and tileset atlases, with
|
|
33
|
+
* no level payload loaded.
|
|
34
|
+
*
|
|
35
|
+
* It claims no suffix, so a bare `.ldtk` path keeps resolving to the eager
|
|
36
|
+
* {@link LdtkMapAssetType} it always did. Both read the same URL, and loading
|
|
37
|
+
* one does not make the other resident. Levels are loaded and unloaded
|
|
38
|
+
* individually through {@link LdtkProject.createRuntime}.
|
|
39
|
+
*/
|
|
40
|
+
var LdtkProjectAssetType = class extends AssetType {
|
|
41
|
+
id = "ldtkProject";
|
|
42
|
+
_token = LdtkProject;
|
|
43
|
+
unacquiredSource() {
|
|
44
|
+
return { source: void 0 };
|
|
45
|
+
}
|
|
46
|
+
createFactory() {
|
|
47
|
+
return { create: (_source, context) => loadLdtkProject(context) };
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
/** The eager LDtk world asset type. Install it through `ldtkExtension`. */
|
|
51
|
+
const ldtkMapType = new LdtkMapAssetType();
|
|
52
|
+
/** The streaming LDtk project asset type. Install it through `ldtkExtension`. */
|
|
53
|
+
const ldtkProjectType = new LdtkProjectAssetType();
|
|
54
|
+
|
|
55
|
+
//#endregion
|
|
56
|
+
export { LdtkMapAssetType, LdtkProjectAssetType, ldtkMapType, ldtkProjectType };
|
|
57
|
+
//# sourceMappingURL=ldtkTypes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ldtkTypes.js","names":[],"sources":["../../src/ldtkTypes.ts"],"sourcesContent":["import type { AssetFactory } from '@codexo/exojs';\nimport { AssetType } from '@codexo/exojs';\n\nimport { LdtkMap } from './LdtkMap';\nimport { LdtkProject } from './LdtkProject';\nimport { loadLdtkMap } from './loadLdtkMap';\nimport { loadLdtkProject } from './loadLdtkProject';\n\n/**\n * A fully assembled LDtk world: every referenced tileset image loaded, every\n * externalized `.ldtkl` level resolved, and one runtime\n * {@link import('@codexo/exojs-tilemap').TileMap} per level.\n *\n * It claims the `.ldtk` suffix, so a bare `.ldtk` path on a loader that has\n * this type installed resolves here rather than to {@link LdtkProjectAssetType}.\n */\nexport class LdtkMapAssetType extends AssetType<void, LdtkMap> {\n public readonly id = 'ldtkMap';\n public override readonly extensions = ['ldtk'];\n public override readonly _token = LdtkMap;\n\n /**\n * The document is acquired as an ordinary JSON asset by the factory, so one\n * `.ldtk` file is downloaded and cached once however many LDtk types read it.\n */\n public override unacquiredSource(): { source: void } {\n return { source: undefined };\n }\n\n public createFactory(): AssetFactory<void, LdtkMap> {\n return { create: (_source, context) => loadLdtkMap(context) };\n }\n}\n\n/**\n * The streaming entry point: an LDtk world's layout and tileset atlases, with\n * no level payload loaded.\n *\n * It claims no suffix, so a bare `.ldtk` path keeps resolving to the eager\n * {@link LdtkMapAssetType} it always did. Both read the same URL, and loading\n * one does not make the other resident. Levels are loaded and unloaded\n * individually through {@link LdtkProject.createRuntime}.\n */\nexport class LdtkProjectAssetType extends AssetType<void, LdtkProject> {\n public readonly id = 'ldtkProject';\n public override readonly _token = LdtkProject;\n\n public override unacquiredSource(): { source: void } {\n return { source: undefined };\n }\n\n public createFactory(): AssetFactory<void, LdtkProject> {\n return { create: (_source, context) => loadLdtkProject(context) };\n }\n}\n\n/** The eager LDtk world asset type. Install it through `ldtkExtension`. */\nexport const ldtkMapType = new LdtkMapAssetType();\n/** The streaming LDtk project asset type. Install it through `ldtkExtension`. */\nexport const ldtkProjectType = new LdtkProjectAssetType();\n"],"mappings":";;;;;;;;;;;;;;;AAgBA,IAAa,mBAAb,cAAsC,UAAyB;CAC7D,AAAgB,KAAK;CACrB,AAAyB,aAAa,CAAC,MAAM;CAC7C,AAAyB,SAAS;;;;;CAMlC,AAAgB,mBAAqC;EACnD,OAAO,EAAE,QAAQ,OAAU;CAC7B;CAEA,AAAO,gBAA6C;EAClD,OAAO,EAAE,SAAS,SAAS,YAAY,YAAY,OAAO,EAAE;CAC9D;AACF;;;;;;;;;;AAWA,IAAa,uBAAb,cAA0C,UAA6B;CACrE,AAAgB,KAAK;CACrB,AAAyB,SAAS;CAElC,AAAgB,mBAAqC;EACnD,OAAO,EAAE,QAAQ,OAAU;CAC7B;CAEA,AAAO,gBAAiD;EACtD,OAAO,EAAE,SAAS,SAAS,YAAY,gBAAgB,OAAO,EAAE;CAClE;AACF;;AAGA,MAAa,cAAc,IAAI,iBAAiB;;AAEhD,MAAa,kBAAkB,IAAI,qBAAqB"}
|
|
@@ -1,12 +1,37 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { AssetFactoryContext } from '@codexo/exojs';
|
|
2
|
+
import { TileSet } from '@codexo/exojs-tilemap';
|
|
3
|
+
import type { LdtkTilesetDef } from './LdtkData';
|
|
2
4
|
import type { LdtkMap } from './LdtkMap';
|
|
3
5
|
/**
|
|
4
|
-
*
|
|
6
|
+
* Load one LDtk tileset definition into a runtime {@link TileSet}.
|
|
7
|
+
*
|
|
8
|
+
* Returns `null` only for an embed-atlas tileset (`relPath` null or empty),
|
|
9
|
+
* whose image ships with the LDtk editor and cannot be resolved from the
|
|
10
|
+
* document - that case warns rather than passing unnoticed, because every tile
|
|
11
|
+
* drawn from it is missing from the runtime map.
|
|
12
|
+
*
|
|
13
|
+
* @throws {LdtkFormatError} when the tileset names an atlas that cannot yield a
|
|
14
|
+
* single tile (its declared size is smaller than one padded tile). Dropping it
|
|
15
|
+
* would make every cell and entity referencing it vanish without a diagnostic.
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
export declare const loadLdtkTileset: (def: LdtkTilesetDef, ldtkSource: string, context: AssetFactoryContext) => Promise<TileSet | null>;
|
|
19
|
+
/**
|
|
20
|
+
* Read a `.ldtk` document, load all referenced tileset images, resolve any
|
|
5
21
|
* externalized (`.ldtkl`) levels, and return a fully assembled {@link LdtkMap}
|
|
6
22
|
* with one runtime {@link import('@codexo/exojs-tilemap').TileMap} per level.
|
|
7
23
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
24
|
+
* The fetched document - and every external `.ldtkl` payload - is validated
|
|
25
|
+
* before use; a structural problem throws
|
|
26
|
+
* {@link import('./validate').LdtkFormatError} naming the file and the
|
|
27
|
+
* offending property path.
|
|
28
|
+
*
|
|
29
|
+
* A tileset whose declared atlas cannot hold a single tile is a
|
|
30
|
+
* {@link import('./validate').LdtkFormatError} too - dropping it would make
|
|
31
|
+
* every cell referencing it disappear without a diagnostic. An embed-atlas
|
|
32
|
+
* tileset (`relPath = null`) is the one case that is skipped rather than
|
|
33
|
+
* rejected, since its image lives inside the LDtk editor; that skip warns.
|
|
10
34
|
* @internal
|
|
11
35
|
*/
|
|
12
|
-
export declare
|
|
36
|
+
export declare const loadLdtkMap: (context: AssetFactoryContext) => Promise<LdtkMap>;
|
|
37
|
+
//# sourceMappingURL=loadLdtkMap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadLdtkMap.d.ts","sourceRoot":"","sources":["../../src/loadLdtkMap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEzD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD,OAAO,KAAK,EAAuB,cAAc,EAAE,MAAM,YAAY,CAAC;AAEtE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOzC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,eAAe,GAAU,KAAK,cAAc,EAAE,YAAY,MAAM,EAAE,SAAS,mBAAmB,KAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAoDnI,CAAC;AAgEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,WAAW,GAAU,SAAS,mBAAmB,KAAG,OAAO,CAAC,OAAO,CAwB/E,CAAC"}
|
package/dist/esm/loadLdtkMap.js
CHANGED
|
@@ -1,139 +1,145 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { getLdtkLevelEntries } from "./ldtkLevelEntries.js";
|
|
2
|
+
import { ldtkToTileMap } from "./ldtkToTileMap.js";
|
|
3
|
+
import { resolveLdtkUrl } from "./url.js";
|
|
4
|
+
import { LdtkFormatError, validateLdtkData, validateLdtkLevelData } from "./validate.js";
|
|
5
|
+
import { TileSet } from "@codexo/exojs-tilemap";
|
|
6
|
+
import { Asset, TextureRegion, logger } from "@codexo/exojs";
|
|
5
7
|
|
|
6
|
-
|
|
8
|
+
//#region src/loadLdtkMap.ts
|
|
7
9
|
/**
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
* Load one LDtk tileset definition into a runtime {@link TileSet}.
|
|
11
|
+
*
|
|
12
|
+
* Returns `null` only for an embed-atlas tileset (`relPath` null or empty),
|
|
13
|
+
* whose image ships with the LDtk editor and cannot be resolved from the
|
|
14
|
+
* document - that case warns rather than passing unnoticed, because every tile
|
|
15
|
+
* drawn from it is missing from the runtime map.
|
|
16
|
+
*
|
|
17
|
+
* @throws {LdtkFormatError} when the tileset names an atlas that cannot yield a
|
|
18
|
+
* single tile (its declared size is smaller than one padded tile). Dropping it
|
|
19
|
+
* would make every cell and entity referencing it vanish without a diagnostic.
|
|
20
|
+
* @internal
|
|
21
|
+
*/
|
|
22
|
+
const loadLdtkTileset = async (def, ldtkSource, context) => {
|
|
23
|
+
if (def.relPath === null || def.relPath === "") {
|
|
24
|
+
logger.warn(`LDtk: tileset "${def.identifier}" in "${ldtkSource}" has no atlas image (relPath is null) — it is an embed-atlas tileset whose image lives inside the LDtk editor. Every tile drawn from it is omitted from the runtime map. Re-export the tileset as a regular image atlas to render it.`, { source: "ldtk" });
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
const imageUrl = resolveLdtkUrl(def.relPath, ldtkSource);
|
|
28
|
+
const texture = await context.dependencies.load(Asset.type("texture", imageUrl));
|
|
29
|
+
const tileSize = def.tileGridSize;
|
|
30
|
+
const spacing = def.spacing ?? 0;
|
|
31
|
+
const margin = def.padding ?? 0;
|
|
32
|
+
const innerWidth = def.pxWid - margin * 2;
|
|
33
|
+
const innerHeight = def.pxHei - margin * 2;
|
|
34
|
+
const columns = Math.floor((innerWidth + spacing) / (tileSize + spacing));
|
|
35
|
+
const rows = Math.floor((innerHeight + spacing) / (tileSize + spacing));
|
|
36
|
+
if (columns <= 0 || rows <= 0) throw new LdtkFormatError(ldtkSource, `defs.tilesets/${def.identifier}`, `tileset "${def.identifier}" declares a ${def.pxWid}×${def.pxHei}px atlas with tileGridSize ${tileSize}, spacing ${spacing} and padding ${margin}, which does not fit a single tile`);
|
|
37
|
+
const tileCount = columns * rows;
|
|
38
|
+
const region = new TextureRegion(texture, {
|
|
39
|
+
x: 0,
|
|
40
|
+
y: 0,
|
|
41
|
+
width: def.pxWid,
|
|
42
|
+
height: def.pxHei
|
|
43
|
+
});
|
|
44
|
+
return new TileSet({
|
|
45
|
+
name: def.identifier,
|
|
46
|
+
texture: region,
|
|
47
|
+
tileWidth: tileSize,
|
|
48
|
+
tileHeight: tileSize,
|
|
49
|
+
tileCount,
|
|
50
|
+
columns,
|
|
51
|
+
spacing,
|
|
52
|
+
margin
|
|
53
|
+
});
|
|
54
|
+
};
|
|
15
55
|
/**
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
y: 0,
|
|
39
|
-
width: def.pxWid,
|
|
40
|
-
height: def.pxHei,
|
|
41
|
-
});
|
|
42
|
-
return new TileSet({
|
|
43
|
-
name: def.identifier,
|
|
44
|
-
texture: region,
|
|
45
|
-
tileWidth: tileSize,
|
|
46
|
-
tileHeight: tileSize,
|
|
47
|
-
tileCount,
|
|
48
|
-
columns,
|
|
49
|
-
spacing,
|
|
50
|
-
margin,
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
// ── External level loading ───────────────────────────────────────────────────
|
|
56
|
+
* Resolve a level's external `.ldtkl` payload and merge its layer/field data
|
|
57
|
+
* into the level record.
|
|
58
|
+
*
|
|
59
|
+
* LDtk's "Save levels to separate files" project option nulls out
|
|
60
|
+
* `layerInstances` on the root document; the real layer data lives in a
|
|
61
|
+
* sibling `<levelIdentifier>.ldtkl` file referenced by {@link LdtkLevel.externalRelPath}.
|
|
62
|
+
* That file also carries its own `fieldInstances`, which is authoritative -
|
|
63
|
+
* the root document's copy is typically stripped or stale for externalized
|
|
64
|
+
* levels. Levels that already carry `layerInstances` (not externalized) are
|
|
65
|
+
* returned unchanged.
|
|
66
|
+
*/
|
|
67
|
+
const loadExternalLevel = async (level, ldtkSource, context) => {
|
|
68
|
+
if (level.layerInstances !== null || level.externalRelPath === void 0 || level.externalRelPath === null || level.externalRelPath === "") return level;
|
|
69
|
+
const externalUrl = resolveLdtkUrl(level.externalRelPath, ldtkSource);
|
|
70
|
+
const external = validateLdtkLevelData(await context.dependencies.load(Asset.type("json", externalUrl)), externalUrl);
|
|
71
|
+
const fieldInstances = external.fieldInstances ?? level.fieldInstances;
|
|
72
|
+
return {
|
|
73
|
+
...level,
|
|
74
|
+
layerInstances: external.layerInstances,
|
|
75
|
+
...fieldInstances !== void 0 && { fieldInstances }
|
|
76
|
+
};
|
|
77
|
+
};
|
|
54
78
|
/**
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
79
|
+
* Rebuild an {@link LdtkData} document with its levels replaced by
|
|
80
|
+
* `resolvedLevels` (external `.ldtkl` payloads merged in via
|
|
81
|
+
* {@link loadExternalLevel}), preserving whichever root shape the source
|
|
82
|
+
* document used - single-world (`levels`) or multi-world (`worlds[].levels`).
|
|
83
|
+
*
|
|
84
|
+
* `resolvedLevels` must be in the same flattened order
|
|
85
|
+
* {@link getLdtkLevelEntries} produced for `data` - each world's slice is
|
|
86
|
+
* recovered by walking `data.worlds` in that same order, so a second pass
|
|
87
|
+
* through {@link getLdtkLevelEntries} (performed inside {@link ldtkToTileMap})
|
|
88
|
+
* reproduces an identical flattened list, now with external levels resolved.
|
|
89
|
+
*/
|
|
90
|
+
const withResolvedLevels = (data, resolvedLevels) => {
|
|
91
|
+
if (data.worlds && data.worlds.length > 0) {
|
|
92
|
+
let cursor = 0;
|
|
93
|
+
const worlds = data.worlds.map((world) => {
|
|
94
|
+
const levels = resolvedLevels.slice(cursor, cursor + world.levels.length);
|
|
95
|
+
cursor += world.levels.length;
|
|
96
|
+
return {
|
|
97
|
+
...world,
|
|
98
|
+
levels
|
|
99
|
+
};
|
|
100
|
+
});
|
|
101
|
+
return {
|
|
102
|
+
...data,
|
|
103
|
+
worlds
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
...data,
|
|
108
|
+
levels: resolvedLevels
|
|
109
|
+
};
|
|
110
|
+
};
|
|
80
111
|
/**
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
* their tiles will not appear in the rendered output.
|
|
112
|
-
* @internal
|
|
113
|
-
*/
|
|
114
|
-
async function loadLdtkMap(source, context) {
|
|
115
|
-
const raw = await context.fetchJson(source);
|
|
116
|
-
// Cast without deep validation — structural errors surface as runtime
|
|
117
|
-
// exceptions when we access fields during conversion.
|
|
118
|
-
const data = raw;
|
|
119
|
-
// Load all referenced tilesets and resolve externalized levels concurrently.
|
|
120
|
-
// Iterate the flattened level list (not raw data.levels) so multi-world
|
|
121
|
-
// documents — whose levels live under worlds[].levels, with an empty root
|
|
122
|
-
// levels[] — still get their external .ldtkl files resolved.
|
|
123
|
-
const [tilesetEntries, resolvedLevels] = await Promise.all([
|
|
124
|
-
Promise.all(data.defs.tilesets.map(async (def) => {
|
|
125
|
-
const ts = await loadLdtkTileset(def, source, context);
|
|
126
|
-
return [def.uid, ts];
|
|
127
|
-
})),
|
|
128
|
-
Promise.all(getLdtkLevelEntries(data).map((entry) => loadExternalLevel(entry.level, source, context))),
|
|
129
|
-
]);
|
|
130
|
-
const tilesets = new Map();
|
|
131
|
-
for (const [uid, ts] of tilesetEntries) {
|
|
132
|
-
if (ts !== null)
|
|
133
|
-
tilesets.set(uid, ts);
|
|
134
|
-
}
|
|
135
|
-
return ldtkToTileMap(withResolvedLevels(data, resolvedLevels), { source, tilesets });
|
|
136
|
-
}
|
|
112
|
+
* Read a `.ldtk` document, load all referenced tileset images, resolve any
|
|
113
|
+
* externalized (`.ldtkl`) levels, and return a fully assembled {@link LdtkMap}
|
|
114
|
+
* with one runtime {@link import('@codexo/exojs-tilemap').TileMap} per level.
|
|
115
|
+
*
|
|
116
|
+
* The fetched document - and every external `.ldtkl` payload - is validated
|
|
117
|
+
* before use; a structural problem throws
|
|
118
|
+
* {@link import('./validate').LdtkFormatError} naming the file and the
|
|
119
|
+
* offending property path.
|
|
120
|
+
*
|
|
121
|
+
* A tileset whose declared atlas cannot hold a single tile is a
|
|
122
|
+
* {@link import('./validate').LdtkFormatError} too - dropping it would make
|
|
123
|
+
* every cell referencing it disappear without a diagnostic. An embed-atlas
|
|
124
|
+
* tileset (`relPath = null`) is the one case that is skipped rather than
|
|
125
|
+
* rejected, since its image lives inside the LDtk editor; that skip warns.
|
|
126
|
+
* @internal
|
|
127
|
+
*/
|
|
128
|
+
const loadLdtkMap = async (context) => {
|
|
129
|
+
const source = context.source;
|
|
130
|
+
const data = validateLdtkData(await context.dependencies.load(Asset.type("json", source)), source);
|
|
131
|
+
const [tilesetEntries, resolvedLevels] = await Promise.all([Promise.all(data.defs.tilesets.map(async (def) => {
|
|
132
|
+
const ts = await loadLdtkTileset(def, source, context);
|
|
133
|
+
return [def.uid, ts];
|
|
134
|
+
})), Promise.all(getLdtkLevelEntries(data).map((entry) => loadExternalLevel(entry.level, source, context)))]);
|
|
135
|
+
const tilesets = /* @__PURE__ */ new Map();
|
|
136
|
+
for (const [uid, ts] of tilesetEntries) if (ts !== null) tilesets.set(uid, ts);
|
|
137
|
+
return ldtkToTileMap(withResolvedLevels(data, resolvedLevels), {
|
|
138
|
+
source,
|
|
139
|
+
tilesets
|
|
140
|
+
});
|
|
141
|
+
};
|
|
137
142
|
|
|
138
|
-
|
|
139
|
-
|
|
143
|
+
//#endregion
|
|
144
|
+
export { loadLdtkMap, loadLdtkTileset };
|
|
145
|
+
//# sourceMappingURL=loadLdtkMap.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loadLdtkMap.js","sources":["../../../src/loadLdtkMap.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"loadLdtkMap.js","names":[],"sources":["../../src/loadLdtkMap.ts"],"sourcesContent":["import type { AssetFactoryContext } from '@codexo/exojs';\nimport { Asset, logger, TextureRegion } from '@codexo/exojs';\nimport { TileSet } from '@codexo/exojs-tilemap';\n\nimport type { LdtkData, LdtkLevel, LdtkTilesetDef } from './LdtkData';\nimport { getLdtkLevelEntries } from './ldtkLevelEntries';\nimport type { LdtkMap } from './LdtkMap';\nimport { ldtkToTileMap } from './ldtkToTileMap';\nimport { resolveLdtkUrl } from './url';\nimport { LdtkFormatError, validateLdtkData, validateLdtkLevelData } from './validate';\n\n// ── Tileset loading ───────────────────────────────────────────────────────────\n\n/**\n * Load one LDtk tileset definition into a runtime {@link TileSet}.\n *\n * Returns `null` only for an embed-atlas tileset (`relPath` null or empty),\n * whose image ships with the LDtk editor and cannot be resolved from the\n * document - that case warns rather than passing unnoticed, because every tile\n * drawn from it is missing from the runtime map.\n *\n * @throws {LdtkFormatError} when the tileset names an atlas that cannot yield a\n * single tile (its declared size is smaller than one padded tile). Dropping it\n * would make every cell and entity referencing it vanish without a diagnostic.\n * @internal\n */\nexport const loadLdtkTileset = async (def: LdtkTilesetDef, ldtkSource: string, context: AssetFactoryContext): Promise<TileSet | null> => {\n if (def.relPath === null || def.relPath === '') {\n logger.warn(\n `LDtk: tileset \"${def.identifier}\" in \"${ldtkSource}\" has no atlas image (relPath is null) — it is an ` +\n 'embed-atlas tileset whose image lives inside the LDtk editor. Every tile drawn from it is omitted ' +\n 'from the runtime map. Re-export the tileset as a regular image atlas to render it.',\n { source: 'ldtk' },\n );\n\n return null;\n }\n\n const imageUrl = resolveLdtkUrl(def.relPath, ldtkSource);\n const texture = await context.dependencies.load(Asset.type('texture', imageUrl));\n\n const tileSize = def.tileGridSize;\n const spacing = def.spacing ?? 0;\n const margin = def.padding ?? 0;\n\n // Compute columns / tileCount from atlas dimensions.\n const innerWidth = def.pxWid - margin * 2;\n const innerHeight = def.pxHei - margin * 2;\n const columns = Math.floor((innerWidth + spacing) / (tileSize + spacing));\n const rows = Math.floor((innerHeight + spacing) / (tileSize + spacing));\n\n if (columns <= 0 || rows <= 0) {\n throw new LdtkFormatError(\n ldtkSource,\n `defs.tilesets/${def.identifier}`,\n `tileset \"${def.identifier}\" declares a ${def.pxWid}×${def.pxHei}px atlas with ` +\n `tileGridSize ${tileSize}, spacing ${spacing} and padding ${margin}, which does not fit a single tile`,\n );\n }\n\n const tileCount = columns * rows;\n const region = new TextureRegion(texture, {\n x: 0,\n y: 0,\n width: def.pxWid,\n height: def.pxHei,\n });\n\n return new TileSet({\n name: def.identifier,\n texture: region,\n tileWidth: tileSize,\n tileHeight: tileSize,\n tileCount,\n columns,\n spacing,\n margin,\n });\n};\n\n// ── External level loading ───────────────────────────────────────────────────\n\n/**\n * Resolve a level's external `.ldtkl` payload and merge its layer/field data\n * into the level record.\n *\n * LDtk's \"Save levels to separate files\" project option nulls out\n * `layerInstances` on the root document; the real layer data lives in a\n * sibling `<levelIdentifier>.ldtkl` file referenced by {@link LdtkLevel.externalRelPath}.\n * That file also carries its own `fieldInstances`, which is authoritative -\n * the root document's copy is typically stripped or stale for externalized\n * levels. Levels that already carry `layerInstances` (not externalized) are\n * returned unchanged.\n */\nconst loadExternalLevel = async (level: LdtkLevel, ldtkSource: string, context: AssetFactoryContext): Promise<LdtkLevel> => {\n // Already-inlined level, or no external file to fetch: return as-is.\n if (level.layerInstances !== null || level.externalRelPath === undefined || level.externalRelPath === null || level.externalRelPath === '') {\n return level;\n }\n\n const externalUrl = resolveLdtkUrl(level.externalRelPath, ldtkSource);\n // Validated against the same level shape as an inlined level, with the\n // `.ldtkl` file itself as the error source - a malformed external payload\n // must fail as loudly as a malformed root document.\n const external = validateLdtkLevelData(await context.dependencies.load(Asset.type('json', externalUrl)), externalUrl);\n const fieldInstances = external.fieldInstances ?? level.fieldInstances;\n\n return {\n ...level,\n layerInstances: external.layerInstances,\n ...(fieldInstances !== undefined && { fieldInstances }),\n };\n};\n\n/**\n * Rebuild an {@link LdtkData} document with its levels replaced by\n * `resolvedLevels` (external `.ldtkl` payloads merged in via\n * {@link loadExternalLevel}), preserving whichever root shape the source\n * document used - single-world (`levels`) or multi-world (`worlds[].levels`).\n *\n * `resolvedLevels` must be in the same flattened order\n * {@link getLdtkLevelEntries} produced for `data` - each world's slice is\n * recovered by walking `data.worlds` in that same order, so a second pass\n * through {@link getLdtkLevelEntries} (performed inside {@link ldtkToTileMap})\n * reproduces an identical flattened list, now with external levels resolved.\n */\nconst withResolvedLevels = (data: LdtkData, resolvedLevels: readonly LdtkLevel[]): LdtkData => {\n if (data.worlds && data.worlds.length > 0) {\n let cursor = 0;\n const worlds = data.worlds.map(world => {\n const levels = resolvedLevels.slice(cursor, cursor + world.levels.length);\n cursor += world.levels.length;\n return { ...world, levels };\n });\n return { ...data, worlds };\n }\n\n return { ...data, levels: resolvedLevels };\n};\n\n// ── Public loader ─────────────────────────────────────────────────────────────\n\n/**\n * Read a `.ldtk` document, load all referenced tileset images, resolve any\n * externalized (`.ldtkl`) levels, and return a fully assembled {@link LdtkMap}\n * with one runtime {@link import('@codexo/exojs-tilemap').TileMap} per level.\n *\n * The fetched document - and every external `.ldtkl` payload - is validated\n * before use; a structural problem throws\n * {@link import('./validate').LdtkFormatError} naming the file and the\n * offending property path.\n *\n * A tileset whose declared atlas cannot hold a single tile is a\n * {@link import('./validate').LdtkFormatError} too - dropping it would make\n * every cell referencing it disappear without a diagnostic. An embed-atlas\n * tileset (`relPath = null`) is the one case that is skipped rather than\n * rejected, since its image lives inside the LDtk editor; that skip warns.\n * @internal\n */\nexport const loadLdtkMap = async (context: AssetFactoryContext): Promise<LdtkMap> => {\n const source = context.source;\n const data = validateLdtkData(await context.dependencies.load(Asset.type('json', source)), source);\n\n // Load all referenced tilesets and resolve externalized levels concurrently.\n // Iterate the flattened level list (not raw data.levels) so multi-world\n // documents - whose levels live under worlds[].levels, with an empty root\n // levels[] - still get their external .ldtkl files resolved.\n const [tilesetEntries, resolvedLevels] = await Promise.all([\n Promise.all(\n data.defs.tilesets.map(async def => {\n const ts = await loadLdtkTileset(def, source, context);\n return [def.uid, ts] as const;\n }),\n ),\n Promise.all(getLdtkLevelEntries(data).map(entry => loadExternalLevel(entry.level, source, context))),\n ]);\n\n const tilesets = new Map<number, TileSet>();\n for (const [uid, ts] of tilesetEntries) {\n if (ts !== null) tilesets.set(uid, ts);\n }\n\n return ldtkToTileMap(withResolvedLevels(data, resolvedLevels), { source, tilesets });\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { AssetFactoryContext } from '@codexo/exojs';
|
|
2
|
+
import { LdtkProject } from './LdtkProject';
|
|
3
|
+
/**
|
|
4
|
+
* Read and validate a `.ldtk` document and load every tileset atlas it
|
|
5
|
+
* references, without touching any level payload.
|
|
6
|
+
*
|
|
7
|
+
* External `.ldtkl` levels are deliberately left unfetched - that is the whole
|
|
8
|
+
* point of {@link LdtkProject}: the world layout arrives, the levels arrive
|
|
9
|
+
* when a level runtime asks for them.
|
|
10
|
+
*
|
|
11
|
+
* @throws {import('./validate').LdtkFormatError} for a structurally invalid
|
|
12
|
+
* document, or a tileset whose declared atlas cannot hold a single tile. An
|
|
13
|
+
* embed-atlas tileset (`relPath = null`) is skipped with a warning instead.
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
export declare const loadLdtkProject: (context: AssetFactoryContext) => Promise<LdtkProject>;
|
|
17
|
+
//# sourceMappingURL=loadLdtkProject.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadLdtkProject.d.ts","sourceRoot":"","sources":["../../src/loadLdtkProject.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAIzD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAI5C;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,eAAe,GAAU,SAAS,mBAAmB,KAAG,OAAO,CAAC,WAAW,CAavF,CAAC"}
|