From cd46345dfb3e6d9878c1c312282f241570449a5b Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Wed, 18 Sep 2019 14:09:15 +0200 Subject: [PATCH] added some tiled stuff to extended --- MLEM.Extended/MLEM.Extended.csproj | 3 + .../Tiled/IndividualTiledMapRenderer.cs | 93 +++++++++++++++++++ MLEM.Extended/Tiled/TiledExtensions.cs | 62 +++++++++++++ 3 files changed, 158 insertions(+) create mode 100644 MLEM.Extended/Tiled/IndividualTiledMapRenderer.cs create mode 100644 MLEM.Extended/Tiled/TiledExtensions.cs diff --git a/MLEM.Extended/MLEM.Extended.csproj b/MLEM.Extended/MLEM.Extended.csproj index de09dc9..39eb0b8 100644 --- a/MLEM.Extended/MLEM.Extended.csproj +++ b/MLEM.Extended/MLEM.Extended.csproj @@ -17,6 +17,9 @@ all + + all + all diff --git a/MLEM.Extended/Tiled/IndividualTiledMapRenderer.cs b/MLEM.Extended/Tiled/IndividualTiledMapRenderer.cs new file mode 100644 index 0000000..ee83f62 --- /dev/null +++ b/MLEM.Extended/Tiled/IndividualTiledMapRenderer.cs @@ -0,0 +1,93 @@ +using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using MLEM.Extensions; +using MonoGame.Extended; +using MonoGame.Extended.Tiled; + +namespace MLEM.Extended.Tiled { + public class IndividualTiledMapRenderer { + + private TiledMap map; + private TileDrawInfo[,,] drawInfos; + public GetDepth DepthFunction = (tile, layer, layerIndex, position) => 0; + + public IndividualTiledMapRenderer(TiledMap map = null) { + if (map != null) + this.SetMap(map); + } + + public void SetMap(TiledMap map) { + if (this.map == map) + return; + this.map = map; + + this.drawInfos = new TileDrawInfo[map.TileLayers.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 tileset = tile.GetTileset(map); + var source = tileset.GetTileRegion(tile.GetLocalIdentifier(tileset, map)); + this.drawInfos[i, x, y] = new TileDrawInfo(this, tile, layer, i, tileset, new Point(x, y), source); + } + } + } + } + + public void Draw(SpriteBatch batch, RectangleF? frustum = null) { + for (var i = 0; i < this.map.TileLayers.Count; i++) { + this.DrawLayer(batch, i, frustum); + } + } + + public void DrawLayer(SpriteBatch batch, int layerIndex, RectangleF? frustum = null) { + var frust = frustum ?? new RectangleF(0, 0, float.MaxValue, float.MaxValue); + var minX = Math.Max(0, frust.Left / this.map.TileWidth).Floor(); + var minY = Math.Max(0, frust.Top / this.map.TileHeight).Floor(); + var maxX = Math.Min(this.map.Width, frust.Right / this.map.TileWidth).Ceil(); + var maxY = Math.Min(this.map.Height, frust.Bottom / this.map.TileHeight).Ceil(); + for (var x = minX; x < maxX; x++) { + for (var y = minY; y < maxY; y++) { + var info = this.drawInfos[layerIndex, x, y]; + if (info != null) + info.Draw(batch); + } + } + } + + public delegate float GetDepth(TiledMapTile tile, TiledMapTileLayer layer, int layerIndex, Point position); + + private class TileDrawInfo { + + private readonly IndividualTiledMapRenderer renderer; + private readonly TiledMapTile tile; + private readonly TiledMapTileLayer layer; + private readonly int layerIndex; + private readonly TiledMapTileset tileset; + private readonly Point position; + private readonly Rectangle source; + + public TileDrawInfo(IndividualTiledMapRenderer renderer, TiledMapTile tile, TiledMapTileLayer layer, int layerIndex, TiledMapTileset tileset, Point position, Rectangle source) { + this.renderer = renderer; + this.tile = tile; + this.layer = layer; + this.layerIndex = layerIndex; + this.tileset = tileset; + this.position = position; + this.source = source; + } + + public void Draw(SpriteBatch batch) { + var drawPos = new Vector2(this.position.X * this.renderer.map.TileWidth, this.position.Y * this.renderer.map.TileHeight); + var depth = this.renderer.DepthFunction(this.tile, this.layer, this.layerIndex, this.position); + batch.Draw(this.tileset.Texture, drawPos, this.source, Color.White, 0, Vector2.Zero, 1, SpriteEffects.None, depth); + } + + } + + } +} \ No newline at end of file diff --git a/MLEM.Extended/Tiled/TiledExtensions.cs b/MLEM.Extended/Tiled/TiledExtensions.cs new file mode 100644 index 0000000..dbb5dae --- /dev/null +++ b/MLEM.Extended/Tiled/TiledExtensions.cs @@ -0,0 +1,62 @@ +using System.Linq; +using Microsoft.Xna.Framework; +using MonoGame.Extended; +using MonoGame.Extended.Tiled; + +namespace MLEM.Extended.Tiled { + public static class TiledExtensions { + + public static string Get(this TiledMapProperties properties, string key) { + properties.TryGetValue(key, out var val); + return val; + } + + public static bool GetBool(this TiledMapProperties properties, string key) { + bool.TryParse(properties.Get(key), out var val); + return val; + } + + public static Color GetColor(this TiledMapProperties properties, string key) { + return ColorHelper.FromHex(properties.Get(key)); + } + + public static float GetFloat(this TiledMapProperties properties, string key) { + float.TryParse(properties.Get(key), out var val); + return val; + } + + public static int GetInt(this TiledMapProperties properties, string key) { + int.TryParse(properties.Get(key), out var val); + return val; + } + + public static TiledMapTileset GetTileset(this TiledMapTile tile, TiledMap map) { + return map.GetTilesetByTileGlobalIdentifier(tile.GlobalIdentifier); + } + + public static int GetLocalIdentifier(this TiledMapTile tile, TiledMapTileset tileset, TiledMap map) { + return tile.GlobalIdentifier - map.GetTilesetFirstGlobalIdentifier(tileset); + } + + public static TiledMapTilesetTile GetTilesetTile(this TiledMapTileset tileset, TiledMapTile tile, TiledMap map) { + var localId = tile.GetLocalIdentifier(tileset, map); + return tileset.Tiles.FirstOrDefault(t => t.LocalTileIdentifier == localId); + } + + public static TiledMapTilesetTile GetTilesetTile(this TiledMapTile tile, TiledMap map) { + var tileset = tile.GetTileset(map); + return tileset.GetTilesetTile(tile, map); + } + + public static TiledMapTile GetTile(this TiledMap map, string layerName, int x, int y) { + var layer = map.GetLayer(layerName); + return layer != null ? layer.GetTile((ushort) x, (ushort) y) : new TiledMapTile(0, (ushort) x, (ushort) y); + } + + public static RectangleF GetArea(this TiledMapObject obj, TiledMap map, Vector2 position) { + var tileSize = new Vector2(map.TileWidth, map.TileHeight); + return new RectangleF(obj.Position / tileSize + position, new Size2(obj.Size.Width, obj.Size.Height) / tileSize); + } + + } +} \ No newline at end of file