From 55c9e061f8b3a0514394c41bdad133187fac1a21 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Wed, 18 Sep 2019 15:54:20 +0200 Subject: [PATCH] added tiled map collisions --- MLEM.Extended/Tiled/TiledMapCollisions.cs | 81 +++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 MLEM.Extended/Tiled/TiledMapCollisions.cs diff --git a/MLEM.Extended/Tiled/TiledMapCollisions.cs b/MLEM.Extended/Tiled/TiledMapCollisions.cs new file mode 100644 index 0000000..a4fdc3d --- /dev/null +++ b/MLEM.Extended/Tiled/TiledMapCollisions.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using Microsoft.Xna.Framework; +using MLEM.Extensions; +using MonoGame.Extended; +using MonoGame.Extended.Tiled; + +namespace MLEM.Extended.Tiled { + public class TiledMapCollisions { + + private TiledMap map; + private TileCollisionInfo[,,] collisionInfos; + + public TiledMapCollisions(TiledMap map = null) { + if (map != null) + this.SetMap(map); + } + + public void SetMap(TiledMap map) { + if (this.map == map) + return; + this.map = map; + + this.collisionInfos = new TileCollisionInfo[map.Layers.Count, map.Width, map.Height]; + for (var i = 0; i < map.TileLayers.Count; i++) { + var layer = map.TileLayers[i]; + for (var x = 0; x < map.Width; x++) { + for (var y = 0; y < map.Height; y++) { + var tile = layer.GetTile((ushort) x, (ushort) y); + if (tile.IsBlank) + continue; + var tilesetTile = tile.GetTilesetTile(map); + if (tilesetTile == null) + continue; + this.collisionInfos[i, x, y] = new TileCollisionInfo(map, new Vector2(x, y), tile, tilesetTile); + } + } + } + } + + public IEnumerable GetCollidingTiles(RectangleF area, Func included = null) { + var inclusionFunc = included ?? (tile => tile.Collisions.Any(c => c.Intersects(area))); + for (var i = 0; i < this.map.TileLayers.Count; i++) { + for (var x = area.Left.Floor(); x <= area.Right; x++) { + for (var y = area.Top.Floor(); y <= area.Bottom; y++) { + var tile = this.collisionInfos[i, x, y]; + if (tile == null) + continue; + if (inclusionFunc(tile)) + yield return tile; + } + } + } + } + + public bool IsColliding(RectangleF area, Func included = null) { + return this.GetCollidingTiles(area, included).Any(); + } + + public class TileCollisionInfo { + + public readonly TiledMapTile Tile; + public readonly TiledMapTilesetTile TilesetTile; + public readonly ReadOnlyCollection Collisions; + + public TileCollisionInfo(TiledMap map, Vector2 position, TiledMapTile tile, TiledMapTilesetTile tilesetTile) { + this.TilesetTile = tilesetTile; + this.Tile = tile; + + var collisions = new List(); + foreach (var obj in tilesetTile.Objects) + collisions.Add(obj.GetArea(map, position)); + this.Collisions = collisions.AsReadOnly(); + } + + } + + } +} \ No newline at end of file