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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,21 @@
1
1
  import { defineModule } from "@rpgjs/common";
2
+ import { resetTiledCollisionHandlers, detachTiledCollisionFromEntity, attachTiledCollisionToEntity, prepareTiledPhysicsData } from "./index5.js";
2
3
  const client = defineModule({
3
- componentAnimations: []
4
+ componentAnimations: [],
5
+ sceneMap: {
6
+ onPhysicsInit(map, context) {
7
+ prepareTiledPhysicsData(context?.mapData, map);
8
+ },
9
+ onPhysicsEntityAdd(map, context) {
10
+ attachTiledCollisionToEntity(context?.owner, map);
11
+ },
12
+ onPhysicsEntityRemove(map, context) {
13
+ detachTiledCollisionFromEntity(context?.owner, map);
14
+ },
15
+ onPhysicsReset(map) {
16
+ resetTiledCollisionHandlers(map);
17
+ }
18
+ }
4
19
  });
5
20
  export {
6
21
  client as default
@@ -1,3 +1,10 @@
1
+ var TiledLayerType = /* @__PURE__ */ ((TiledLayerType2) => {
2
+ TiledLayerType2["Tile"] = "tilelayer";
3
+ TiledLayerType2["ObjectGroup"] = "objectgroup";
4
+ TiledLayerType2["Image"] = "imagelayer";
5
+ TiledLayerType2["Group"] = "group";
6
+ return TiledLayerType2;
7
+ })(TiledLayerType || {});
1
8
  function joinPath(...segments) {
2
9
  return segments.filter((segment) => segment && segment.length > 0).join("/").replace(/\/+/g, "/");
3
10
  }
@@ -4636,6 +4643,579 @@ _TiledParser.propToBool = (obj, props) => {
4636
4643
  return obj;
4637
4644
  };
4638
4645
  let TiledParser = _TiledParser;
4646
+ class TiledProperties {
4647
+ constructor(data) {
4648
+ this.properties = {};
4649
+ this.properties = data?.properties ?? {};
4650
+ }
4651
+ getProperty(name, defaultValue) {
4652
+ const val = this.properties[name];
4653
+ if (val === void 0) {
4654
+ return defaultValue;
4655
+ }
4656
+ return val;
4657
+ }
4658
+ hasProperty(name) {
4659
+ return !!this.properties[name];
4660
+ }
4661
+ setProperty(name, value) {
4662
+ this.properties[name] = value;
4663
+ }
4664
+ getType() {
4665
+ return this.class || this["type"];
4666
+ }
4667
+ }
4668
+ const FLIPPED_HORIZONTALLY_FLAG = 2147483648;
4669
+ const FLIPPED_VERTICALLY_FLAG = 1073741824;
4670
+ const FLIPPED_DIAGONALLY_FLAG = 536870912;
4671
+ const ROTATED_HEXAGONAL_120_FLAG = 268435456;
4672
+ class TileGid extends TiledProperties {
4673
+ constructor(obj) {
4674
+ super(obj);
4675
+ this.obj = obj;
4676
+ this._gid = obj?.gid;
4677
+ }
4678
+ static getRealGid(gid) {
4679
+ return gid & 268435455;
4680
+ }
4681
+ get horizontalFlip() {
4682
+ return !!(this._gid & FLIPPED_HORIZONTALLY_FLAG);
4683
+ }
4684
+ get verticalFlip() {
4685
+ return !!(this._gid & FLIPPED_VERTICALLY_FLAG);
4686
+ }
4687
+ get diagonalFlip() {
4688
+ return !!(this._gid & FLIPPED_DIAGONALLY_FLAG);
4689
+ }
4690
+ get rotatedHex120() {
4691
+ return !!(this._gid & ROTATED_HEXAGONAL_120_FLAG);
4692
+ }
4693
+ get gid() {
4694
+ return TileGid.getRealGid(this._gid);
4695
+ }
4696
+ set gid(val) {
4697
+ this._gid = val;
4698
+ }
4699
+ }
4700
+ class Tile extends TileGid {
4701
+ constructor(tile) {
4702
+ super(tile);
4703
+ this.tile = tile;
4704
+ const preservedProperties = this.properties;
4705
+ Reflect.deleteProperty(tile, "gid");
4706
+ Object.assign(this, tile);
4707
+ if (preservedProperties && Object.keys(preservedProperties).length > 0) {
4708
+ this.properties = { ...preservedProperties, ...this.properties };
4709
+ }
4710
+ }
4711
+ }
4712
+ class TiledObjectClass extends TileGid {
4713
+ constructor(object) {
4714
+ super(object);
4715
+ this.layerName = "";
4716
+ Object.assign(this, object);
4717
+ if (object?.gid) {
4718
+ this.y -= this.height;
4719
+ }
4720
+ }
4721
+ }
4722
+ class Layer extends TiledProperties {
4723
+ constructor(layer, tilesets, parent) {
4724
+ super(layer);
4725
+ this.tilesets = tilesets;
4726
+ this.parent = parent;
4727
+ this.cacheTiles = false;
4728
+ this.tiles = [];
4729
+ Object.assign(this, layer);
4730
+ this.mapObjects();
4731
+ this.mergePropertiesWithParent();
4732
+ this.cacheTiles = this.getProperty("cache-tiles", false);
4733
+ if (this.cacheTiles) this.propertiesTiles();
4734
+ }
4735
+ get size() {
4736
+ return this.data.length;
4737
+ }
4738
+ createTile(gid, tileIndex, layerIndex) {
4739
+ if (gid == 0) {
4740
+ return;
4741
+ }
4742
+ const realGid = TileGid.getRealGid(gid);
4743
+ const tileset = Layer.findTileSet(realGid, this.tilesets);
4744
+ if (!tileset) {
4745
+ return void 0;
4746
+ }
4747
+ const tile = tileset.getTile(realGid - tileset.firstgid);
4748
+ if (tile) {
4749
+ return new Tile({
4750
+ ...tile.tile,
4751
+ gid,
4752
+ index: tileIndex,
4753
+ layerIndex
4754
+ });
4755
+ }
4756
+ return new Tile({
4757
+ gid,
4758
+ index: tileIndex,
4759
+ layerIndex
4760
+ });
4761
+ }
4762
+ mergePropertiesWithParent() {
4763
+ const parent = this.getLayerParent();
4764
+ if (!this.properties) this.properties = {};
4765
+ if (!parent) return;
4766
+ for (let key in parent.properties) {
4767
+ const val = parent.properties[key];
4768
+ const valChild = this.properties[key];
4769
+ if (valChild === void 0) {
4770
+ this.properties[key] = val;
4771
+ } else {
4772
+ if (key == "z") {
4773
+ this.properties[key] += val;
4774
+ } else {
4775
+ continue;
4776
+ }
4777
+ }
4778
+ }
4779
+ this.opacity = Math.round((parent.opacity ?? 1) * (this.opacity ?? 1) * 100) / 100;
4780
+ this.offsetx = (parent.offsetx ?? 0) + (this.offsetx ?? 0);
4781
+ this.offsety = (parent.offsety ?? 0) + (this.offsety ?? 0);
4782
+ this.locked = parent.locked ?? false;
4783
+ }
4784
+ propertiesTiles() {
4785
+ if (!this.data) return;
4786
+ const data = this.data;
4787
+ for (let i = 0; i < data.length; i++) {
4788
+ const id = data[i];
4789
+ this.tiles.push(this.createTile(id, i));
4790
+ }
4791
+ }
4792
+ mapObjects() {
4793
+ if (this.objects) {
4794
+ this.objects = this.objects.map((object) => {
4795
+ const obj = new TiledObjectClass(object);
4796
+ obj.layerName = this.name;
4797
+ return obj;
4798
+ });
4799
+ }
4800
+ }
4801
+ getTileByIndex(tileIndex) {
4802
+ if (this.cacheTiles) {
4803
+ return this.tiles[tileIndex];
4804
+ }
4805
+ return this.createTile(this.data[tileIndex], tileIndex);
4806
+ }
4807
+ static findTileSet(gid, tileSets) {
4808
+ let tileset;
4809
+ for (let i = tileSets.length - 1; i >= 0; i--) {
4810
+ tileset = tileSets[i];
4811
+ if (tileset.firstgid && tileset.firstgid <= gid) {
4812
+ break;
4813
+ }
4814
+ }
4815
+ return tileset;
4816
+ }
4817
+ getLayerParent() {
4818
+ return this.parent;
4819
+ }
4820
+ tilesForEach(cb) {
4821
+ for (let i = 0; i < this.data.length; i++) {
4822
+ if (this.cacheTiles) {
4823
+ cb(this.tiles[i], i);
4824
+ continue;
4825
+ }
4826
+ cb(this.createTile(this.data[i], i), i);
4827
+ }
4828
+ }
4829
+ setData(tileIndex, gid) {
4830
+ this.data[tileIndex] = gid;
4831
+ }
4832
+ }
4833
+ class Tileset extends TiledProperties {
4834
+ constructor(tileset) {
4835
+ super(tileset);
4836
+ this.tileset = tileset;
4837
+ this.cacheTileId = /* @__PURE__ */ new Map();
4838
+ Object.assign(this, tileset);
4839
+ this.margin = this.margin ?? 0;
4840
+ this.spacing = this.spacing ?? 0;
4841
+ const tilesArray = tileset.tiles || tileset.tile || [];
4842
+ for (let tile of tilesArray) {
4843
+ this.addTile(tile);
4844
+ }
4845
+ Reflect.deleteProperty(this, "tiles");
4846
+ Reflect.deleteProperty(this, "tile");
4847
+ }
4848
+ addTile(tileObj) {
4849
+ const tile = new Tile(tileObj);
4850
+ this.cacheTileId.set(tile.id, tile);
4851
+ return tile;
4852
+ }
4853
+ getTile(id) {
4854
+ return this.cacheTileId.get(+id);
4855
+ }
4856
+ }
4857
+ let bufferTilesets = {};
4858
+ class MapClass extends TiledProperties {
4859
+ constructor(map) {
4860
+ super(map ?? {});
4861
+ this.tilesets = [];
4862
+ this.layers = [];
4863
+ this.tmpLayers = [];
4864
+ this.tilesIndex = {};
4865
+ this.allocateMemory = 0;
4866
+ this.lowMemory = false;
4867
+ if (map) this.load(map);
4868
+ }
4869
+ load(map) {
4870
+ Object.assign(this, map);
4871
+ if (this.hasProperty("low-memory")) {
4872
+ this.lowMemory = this.getProperty("low-memory", false);
4873
+ }
4874
+ this.tmpLayers = [];
4875
+ this.mapTilesets();
4876
+ this.mapLayers(this.layers);
4877
+ this.layers = [...this.tmpLayers];
4878
+ Reflect.deleteProperty(this, "tmpLayers");
4879
+ this.setTilesIndex();
4880
+ this.data = map;
4881
+ }
4882
+ /**
4883
+ * @title Width of the map in pixels
4884
+ * @prop {number} [widthPx]
4885
+ * @readonly
4886
+ * @memberof Map
4887
+ * @memberof RpgSceneMap
4888
+ * */
4889
+ get widthPx() {
4890
+ return this.width * this.tilewidth;
4891
+ }
4892
+ /**
4893
+ * @title Height of the map in pixels
4894
+ * @prop {number} [heightPx]
4895
+ * @readonly
4896
+ * @memberof Map
4897
+ * @memberof RpgSceneMap
4898
+ * */
4899
+ get heightPx() {
4900
+ return this.height * this.tileheight;
4901
+ }
4902
+ /**
4903
+ * @title The depth of the map in pixels (this is the height of a tile ;))
4904
+ * @prop {number} map.zTileHeight
4905
+ * @readonly
4906
+ * @memberof Map
4907
+ * @memberof RpgSceneMap
4908
+ * */
4909
+ get zTileHeight() {
4910
+ return this.tileheight;
4911
+ }
4912
+ /**
4913
+ * Find a layer by name. Returns `undefined` is the layer is not found
4914
+
4915
+ * @title Get Layer by name
4916
+ * @method map.getLayerByName(name)
4917
+ * @param {string} name layer name
4918
+ * @returns {LayerInfo | undefined}
4919
+ * @example
4920
+ * ```ts
4921
+ * const tiles = map.getLayerByName(0, 0)
4922
+ * ```
4923
+ * @memberof Map
4924
+ * @memberof RpgSceneMap
4925
+ */
4926
+ getLayerByName(name) {
4927
+ return this.layers.find((layer) => layer.name == name);
4928
+ }
4929
+ /**
4930
+ * Get the tile index on the tileset
4931
+ *
4932
+ * @title Get index of tile
4933
+ * @method map.getTileIndex(x,y)
4934
+ * @param {number} x Position X
4935
+ * @param {number} x Position Y
4936
+ * @returns {number}
4937
+ * @memberof Map
4938
+ * @memberof RpgSceneMap
4939
+ */
4940
+ getTileIndex(x, y, [z] = [0]) {
4941
+ return this.width * Math.floor((y - z) / this.tileheight) + Math.floor(x / this.tilewidth);
4942
+ }
4943
+ getTilePosition(index) {
4944
+ return {
4945
+ y: Math.floor(index / this.width) * this.tileheight,
4946
+ x: index % this.width * this.tilewidth
4947
+ };
4948
+ }
4949
+ /**
4950
+ * Find the point of origin (top left) of a tile. Of course, its position depends on the size of the tile
4951
+
4952
+ * @title Get origin position of tile
4953
+ * @method map.getTileOriginPosition(x,y)
4954
+ * @param {number} x Position X
4955
+ * @param {number} x Position Y
4956
+ * @returns { {x: number, y: number }}
4957
+ * @example
4958
+ * ```ts
4959
+ * // If the size of a tile is 32x32px
4960
+ * const position = map.getTileOriginPosition(35, 12)
4961
+ * console.log(position) // { x: 32, y: 0 }
4962
+ * ```
4963
+ * @memberof Map
4964
+ * @memberof RpgSceneMap
4965
+ */
4966
+ getTileOriginPosition(x, y) {
4967
+ return {
4968
+ x: Math.floor(x / this.tilewidth) * this.tilewidth,
4969
+ y: Math.floor(y / this.tileheight) * this.tileheight
4970
+ };
4971
+ }
4972
+ /**
4973
+ * Recover tiles according to a position
4974
+
4975
+ * @title Get tile by position
4976
+ * @method map.getTileByPosition(x,y)
4977
+ * @param {number} x Position X
4978
+ * @param {number} x Position Y
4979
+ * @returns {TileInfo}
4980
+ * @example
4981
+ * ```ts
4982
+ * const tiles = map.getTileByPosition(0, 0)
4983
+ * ```
4984
+ * @memberof Map
4985
+ * @memberof RpgSceneMap
4986
+ */
4987
+ getTileByPosition(x, y, z = [0, 0], options = {}) {
4988
+ const tileIndex = this.getTileIndex(x, y, [z[0]]);
4989
+ return this.getTileByIndex(tileIndex, z, options);
4990
+ }
4991
+ /**
4992
+ * Retrieves tiles according to its index
4993
+
4994
+ * @title Get tile by index
4995
+ * @method map.getTileByIndex(tileIndex)
4996
+ * @param {number} tileIndex tile index
4997
+ * @returns {TileInfo}
4998
+ * @example
4999
+ * ```ts
5000
+ * const index = map.getTileIndex(0, 0)
5001
+ * const tiles = map.getTileByIndex(index)
5002
+ * ```
5003
+ * @memberof Map
5004
+ * @memberof RpgSceneMap
5005
+ */
5006
+ getTileByIndex(tileIndex, zPlayer = [0, 0], options = {
5007
+ populateTiles: true
5008
+ }) {
5009
+ const zA = Math.floor(zPlayer[0] / this.zTileHeight);
5010
+ Math.floor(zPlayer[1] / this.zTileHeight);
5011
+ const level = this.tilesIndex[zA];
5012
+ const obj = {
5013
+ tiles: [],
5014
+ hasCollision: false,
5015
+ isOverlay: false,
5016
+ objectGroups: [],
5017
+ tileIndex
5018
+ };
5019
+ if (!level) {
5020
+ return obj;
5021
+ }
5022
+ const [layer] = this.layers;
5023
+ const getTileByPointer = (pointer = 0) => {
5024
+ const pos = tileIndex * this.realAllocateMemory + pointer;
5025
+ const gid = level[pos];
5026
+ if (gid === 0) {
5027
+ return obj;
5028
+ }
5029
+ const tile2 = layer.createTile(gid, tileIndex, level[pos + 1]);
5030
+ if (tile2) obj.tiles.push(tile2);
5031
+ };
5032
+ if (options.populateTiles) {
5033
+ for (let i = 0; i < this.realAllocateMemory; i += 2) {
5034
+ getTileByPointer(i);
5035
+ }
5036
+ } else {
5037
+ getTileByPointer();
5038
+ }
5039
+ const [tile] = obj.tiles;
5040
+ if (tile) {
5041
+ obj.hasCollision = tile.getProperty("collision", false);
5042
+ obj.objectGroups = tile.objects ?? [];
5043
+ }
5044
+ return obj;
5045
+ }
5046
+ getAllObjects() {
5047
+ return this.layers.reduce((prev, current) => {
5048
+ if (!current.objects) return prev;
5049
+ return prev.concat(...current.objects);
5050
+ }, []);
5051
+ }
5052
+ getData() {
5053
+ return {
5054
+ ...this.data,
5055
+ layers: this.layers
5056
+ };
5057
+ }
5058
+ setTile(x, y, layerFilter, tileInfo) {
5059
+ if (this.lowMemory) {
5060
+ throw "Impossible to change a tile with the lowMemory option";
5061
+ }
5062
+ const tileIndex = this.getTileIndex(x, y);
5063
+ let fnFilter;
5064
+ let tilesEdited = {};
5065
+ if (typeof layerFilter == "string") {
5066
+ fnFilter = (layer) => layer.name == layerFilter;
5067
+ } else {
5068
+ fnFilter = layerFilter;
5069
+ }
5070
+ for (let i = 0; i < this.layers.length; i++) {
5071
+ const layer = this.layers[i];
5072
+ if (!fnFilter(layer)) continue;
5073
+ let tile;
5074
+ const oldTile = this.getTileByIndex(tileIndex);
5075
+ if (tileInfo.gid) {
5076
+ tile = layer.createTile(tileInfo.gid, tileIndex);
5077
+ }
5078
+ if (!tile) continue;
5079
+ for (let key in tileInfo) {
5080
+ if (key == "gid") continue;
5081
+ tile[key] = tileInfo[key];
5082
+ }
5083
+ tilesEdited[layer.name] = {
5084
+ gid: tile.gid,
5085
+ properties: tile.properties
5086
+ };
5087
+ this.setTileIndex(layer, oldTile.tiles[0], tile, tileIndex, i);
5088
+ layer.setData(tileIndex, tile.gid);
5089
+ }
5090
+ return {
5091
+ x,
5092
+ y,
5093
+ tiles: tilesEdited
5094
+ };
5095
+ }
5096
+ removeCacheTileset(name) {
5097
+ delete bufferTilesets[name];
5098
+ }
5099
+ clearCacheTilesets() {
5100
+ bufferTilesets = {};
5101
+ }
5102
+ mapTilesets() {
5103
+ this.tilesets = this.tilesets.map((tileset) => {
5104
+ if (bufferTilesets[tileset.name]) {
5105
+ const instance = bufferTilesets[tileset.name];
5106
+ instance.firstgid = tileset.firstgid;
5107
+ return instance;
5108
+ }
5109
+ const _tileset = new Tileset(tileset);
5110
+ bufferTilesets[_tileset.name] = _tileset;
5111
+ return _tileset;
5112
+ });
5113
+ }
5114
+ mapLayers(layers = [], parent) {
5115
+ for (let layer of layers) {
5116
+ const layerInstance = new Layer(layer, this.tilesets, parent);
5117
+ this.tmpLayers.push(layerInstance);
5118
+ if (layer.layers) {
5119
+ this.mapLayers(layer.layers, layerInstance);
5120
+ }
5121
+ }
5122
+ if (this.lowMemory) this.allocateMemory = 1;
5123
+ if (!this.allocateMemory) this.allocateMemory = this.layers.length;
5124
+ }
5125
+ setTileIndex(layer, oldTile, newTile, tileIndex, layerIndex) {
5126
+ const startPos = tileIndex * this.realAllocateMemory;
5127
+ let pointer = startPos + this.realAllocateMemory - 2;
5128
+ const zLayer = layer.getProperty("z", 0);
5129
+ const zTile = oldTile.getProperty("z", 0);
5130
+ let z = zLayer + zTile;
5131
+ while (pointer >= startPos) {
5132
+ const zlayer = this.tilesIndex[z];
5133
+ if (zlayer[pointer] === oldTile.gid && zlayer[pointer + 1] === layerIndex) {
5134
+ this.tilesIndex[z][pointer] = newTile.gid;
5135
+ }
5136
+ pointer -= 2;
5137
+ }
5138
+ }
5139
+ /**
5140
+ * We multiply by 2 because 2 entries are stored for a tile: its GID and the Layer Index
5141
+ *
5142
+ * Example If I have 3 layers, The array will have the following form
5143
+ *
5144
+ * [
5145
+ * GID of Layer 3,
5146
+ * Layer Index of Layer 3,
5147
+ * GID of Layer 2,
5148
+ * Layer Index of Layer 2,
5149
+ * GID of Layer 1,
5150
+ * Layer Index of Layer 1,
5151
+ * ... others tiles
5152
+ * ]
5153
+ *
5154
+ * The size in memory of the map is therefore:
5155
+ *
5156
+ * `(map width * map height * number of layers * 4) bytes`
5157
+ *
5158
+ * > We multiply by 4, because an element takes 2 bytes and has 2 elements for a tile is 4 bytes in all
5159
+ *
5160
+ * Example (a 100x100 map with 5 layers)
5161
+ *
5162
+ * `100 * 100 * 5 * 4 = 200000 bytes = ~195 Kb`
5163
+ *
5164
+ * If we define on lowMemory then the calculation is the following
5165
+ *
5166
+ * `(map width * map height * 4) bytes`
5167
+ *
5168
+ * Example
5169
+ *
5170
+ * `100 * 100 * 4 = 40000 bytes = ~39 Kb`
5171
+ */
5172
+ get realAllocateMemory() {
5173
+ return this.allocateMemory * 2;
5174
+ }
5175
+ /**
5176
+ * We keep each tile in memory classified by z value. The values are ordered from the end to the beginning so that the first element of the array (when retrieved with getTileByIndex() is the tile on the highest layer. This way, the tile search is very fast for collisions
5177
+ *
5178
+ */
5179
+ addTileIndex(layer, tile, tileIndex, layerIndex) {
5180
+ if (!tile || tile && tile.gid == 0) {
5181
+ return;
5182
+ }
5183
+ const zLayer = layer.getProperty("z", 0);
5184
+ const zTile = tile.getProperty("z", 0);
5185
+ let z = zLayer + zTile;
5186
+ if (!this.tilesIndex[z]) {
5187
+ const buffer2 = new ArrayBuffer(layer.size * this.realAllocateMemory * 2);
5188
+ this.tilesIndex[z] = new Uint16Array(buffer2);
5189
+ }
5190
+ const startPos = tileIndex * this.realAllocateMemory;
5191
+ let pointer = startPos + this.realAllocateMemory - 2;
5192
+ while (this.tilesIndex[z][pointer] !== 0 && pointer > startPos) {
5193
+ pointer -= 2;
5194
+ }
5195
+ this.tilesIndex[z][pointer] = tile.gid;
5196
+ this.tilesIndex[z][pointer + 1] = layerIndex;
5197
+ this.tilesIndex[z][startPos] = tile.gid;
5198
+ this.tilesIndex[z][startPos + 1] = layerIndex;
5199
+ }
5200
+ setTilesIndex() {
5201
+ for (let i = 0; i < this.layers.length; i++) {
5202
+ const layer = this.layers[i];
5203
+ if (layer.type != TiledLayerType.Tile) {
5204
+ continue;
5205
+ }
5206
+ layer.tilesForEach((tile, index) => {
5207
+ this.addTileIndex(layer, tile, index, i);
5208
+ });
5209
+ }
5210
+ }
5211
+ }
4639
5212
  export {
4640
- TiledParser
5213
+ Layer,
5214
+ MapClass,
5215
+ Tile,
5216
+ TiledLayerType,
5217
+ TiledObjectClass,
5218
+ TiledParser,
5219
+ TiledProperties,
5220
+ Tileset
4641
5221
  };
@@ -0,0 +1,95 @@
1
+ import { MapClass } from "./index3.js";
2
+ function prepareTiledPhysicsData(mapData, map) {
3
+ if (!mapData?.parsedMap) {
4
+ return;
5
+ }
6
+ const tiledMap = new MapClass(mapData.parsedMap);
7
+ map.tiled = tiledMap;
8
+ mapData.hitboxes = mapData.hitboxes || [];
9
+ mapData.width = tiledMap.widthPx;
10
+ mapData.height = tiledMap.heightPx;
11
+ map._tiledTileWidth = tiledMap.tilewidth;
12
+ map._tiledTileHeight = tiledMap.tileheight;
13
+ map._blockedTiles = collectBlockedTiles(tiledMap);
14
+ }
15
+ function attachTiledCollisionToEntity(owner, map) {
16
+ if (!owner?.id || !map?._blockedTiles) {
17
+ return;
18
+ }
19
+ const entity = map.physic?.getEntityByUUID(owner.id);
20
+ if (!entity || typeof entity.canEnterTile !== "function") {
21
+ return;
22
+ }
23
+ const unsubscribers = ensureUnsubscribers(map);
24
+ const previousUnsubscribe = unsubscribers.get(owner.id);
25
+ if (previousUnsubscribe) {
26
+ previousUnsubscribe();
27
+ unsubscribers.delete(owner.id);
28
+ }
29
+ const blockedTiles = map._blockedTiles;
30
+ const tiledTileWidth = map._tiledTileWidth ?? 32;
31
+ const tiledTileHeight = map._tiledTileHeight ?? 32;
32
+ const physicsTileWidth = 32;
33
+ const physicsTileHeight = 32;
34
+ const unsubscribe = entity.canEnterTile(({ x, y }) => {
35
+ const tiledX = Math.floor(x * physicsTileWidth / tiledTileWidth);
36
+ const tiledY = Math.floor(y * physicsTileHeight / tiledTileHeight);
37
+ return !blockedTiles.has(`${tiledX},${tiledY}`);
38
+ });
39
+ unsubscribers.set(owner.id, unsubscribe);
40
+ }
41
+ function detachTiledCollisionFromEntity(owner, map) {
42
+ if (!owner?.id) {
43
+ return;
44
+ }
45
+ const unsubscribers = map._tiledCollisionUnsubscribers;
46
+ if (!unsubscribers) {
47
+ return;
48
+ }
49
+ const unsubscribe = unsubscribers.get(owner.id);
50
+ if (!unsubscribe) {
51
+ return;
52
+ }
53
+ unsubscribe();
54
+ unsubscribers.delete(owner.id);
55
+ }
56
+ function resetTiledCollisionHandlers(map) {
57
+ const unsubscribers = map._tiledCollisionUnsubscribers;
58
+ if (unsubscribers) {
59
+ for (const unsubscribe of unsubscribers.values()) {
60
+ unsubscribe();
61
+ }
62
+ unsubscribers.clear();
63
+ }
64
+ map._blockedTiles = void 0;
65
+ map._tiledTileWidth = void 0;
66
+ map._tiledTileHeight = void 0;
67
+ }
68
+ function collectBlockedTiles(tiledMap) {
69
+ const blockedTiles = /* @__PURE__ */ new Set();
70
+ const mapWidth = tiledMap.width;
71
+ const mapHeight = tiledMap.height;
72
+ const tileWidth = tiledMap.tilewidth;
73
+ const tileHeight = tiledMap.tileheight;
74
+ for (let y = 0; y < mapHeight; y++) {
75
+ for (let x = 0; x < mapWidth; x++) {
76
+ const tileInfo = tiledMap.getTileByPosition(x * tileWidth, y * tileHeight, [0, 0], {
77
+ populateTiles: true
78
+ });
79
+ if (tileInfo.hasCollision) {
80
+ blockedTiles.add(`${x},${y}`);
81
+ }
82
+ }
83
+ }
84
+ return blockedTiles;
85
+ }
86
+ function ensureUnsubscribers(map) {
87
+ map._tiledCollisionUnsubscribers = map._tiledCollisionUnsubscribers || /* @__PURE__ */ new Map();
88
+ return map._tiledCollisionUnsubscribers;
89
+ }
90
+ export {
91
+ attachTiledCollisionToEntity,
92
+ detachTiledCollisionFromEntity,
93
+ prepareTiledPhysicsData,
94
+ resetTiledCollisionHandlers
95
+ };