diff options
Diffstat (limited to 'Plugins/MonoGame.Extended/source/MonoGame.Extended.Tiled/Renderers/TiledMapModelBuilder.cs')
-rw-r--r-- | Plugins/MonoGame.Extended/source/MonoGame.Extended.Tiled/Renderers/TiledMapModelBuilder.cs | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/Plugins/MonoGame.Extended/source/MonoGame.Extended.Tiled/Renderers/TiledMapModelBuilder.cs b/Plugins/MonoGame.Extended/source/MonoGame.Extended.Tiled/Renderers/TiledMapModelBuilder.cs new file mode 100644 index 0000000..b96925e --- /dev/null +++ b/Plugins/MonoGame.Extended/source/MonoGame.Extended.Tiled/Renderers/TiledMapModelBuilder.cs @@ -0,0 +1,126 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.Xna.Framework.Graphics; + +namespace MonoGame.Extended.Tiled.Renderers +{ + public class TiledMapModelBuilder + { + private readonly GraphicsDevice _graphicsDevice; + + public TiledMapModelBuilder(GraphicsDevice graphicsDevice) + { + _graphicsDevice = graphicsDevice; + } + + private IEnumerable<TiledMapLayerModel> CreateLayerModels(TiledMap map, TiledMapLayer layer) + { + switch(layer) + { + case TiledMapTileLayer tileLayer: + return CreateTileLayerModels(map, tileLayer); + case TiledMapImageLayer imageLayer: + return CreateImageLayerModels(imageLayer); + default: + return new List<TiledMapLayerModel>(); + } + + } + + private IEnumerable<TiledMapLayerModel> CreateImageLayerModels(TiledMapImageLayer imageLayer) + { + var modelBuilder = new TiledMapStaticLayerModelBuilder(); + modelBuilder.AddSprite(imageLayer.Image, imageLayer.Position, imageLayer.Image.Bounds, TiledMapTileFlipFlags.None); + yield return modelBuilder.Build(_graphicsDevice, imageLayer.Image); + } + + private IEnumerable<TiledMapLayerModel> CreateTileLayerModels(TiledMap map, TiledMapTileLayer tileLayer) + { + var layerModels = new List<TiledMapLayerModel>(); + var staticLayerBuilder = new TiledMapStaticLayerModelBuilder(); + var animatedLayerBuilder = new TiledMapAnimatedLayerModelBuilder(); + + foreach (var tileset in map.Tilesets) + { + var firstGlobalIdentifier = map.GetTilesetFirstGlobalIdentifier(tileset); + var lastGlobalIdentifier = tileset.TileCount + firstGlobalIdentifier - 1; + var texture = tileset.Texture; + + foreach (var tile in tileLayer.Tiles.Where(t => firstGlobalIdentifier <= t.GlobalIdentifier && t.GlobalIdentifier <= lastGlobalIdentifier)) + { + var tileGid = tile.GlobalIdentifier; + var localTileIdentifier = tileGid - firstGlobalIdentifier; + var position = GetTilePosition(map, tile); + var sourceRectangle = tileset.GetTileRegion(localTileIdentifier); + var flipFlags = tile.Flags; + + // animated tiles + var tilesetTile = tileset.Tiles.FirstOrDefault(x => x.LocalTileIdentifier == localTileIdentifier); + if (tilesetTile?.Texture is not null) + { + position.Y += map.TileHeight - sourceRectangle.Height; + texture = tilesetTile.Texture; + } + + if (tilesetTile is TiledMapTilesetAnimatedTile animatedTilesetTile) + { + animatedLayerBuilder.AddSprite(texture, position, sourceRectangle, flipFlags); + animatedTilesetTile.CreateTextureRotations(tileset, flipFlags); + animatedLayerBuilder.AnimatedTilesetTiles.Add(animatedTilesetTile); + animatedLayerBuilder.AnimatedTilesetFlipFlags.Add(flipFlags); + + if (animatedLayerBuilder.IsFull) + layerModels.Add(animatedLayerBuilder.Build(_graphicsDevice, texture)); + } + else + { + staticLayerBuilder.AddSprite(texture, position, sourceRectangle, flipFlags); + + if (staticLayerBuilder.IsFull) + layerModels.Add(staticLayerBuilder.Build(_graphicsDevice, texture)); + } + } + + if (staticLayerBuilder.IsBuildable) + layerModels.Add(staticLayerBuilder.Build(_graphicsDevice, texture)); + + if (animatedLayerBuilder.IsBuildable) + layerModels.Add(animatedLayerBuilder.Build(_graphicsDevice, texture)); + } + + return layerModels; + } + + public TiledMapModel Build(TiledMap map) + { + var dictionary = new Dictionary<TiledMapLayer, TiledMapLayerModel[]>(); + foreach (var layer in map.Layers) + BuildLayer(map, layer, dictionary); + + return new TiledMapModel(map, dictionary); + } + + private void BuildLayer(TiledMap map, TiledMapLayer layer, Dictionary<TiledMapLayer, TiledMapLayerModel[]> dictionary) + { + if (layer is TiledMapGroupLayer groupLayer) + foreach (var subLayer in groupLayer.Layers) + BuildLayer(map, subLayer, dictionary); + else + dictionary.Add(layer, CreateLayerModels(map, layer).ToArray()); + } + + private static Point2 GetTilePosition(TiledMap map, TiledMapTile mapTile) + { + switch (map.Orientation) + { + case TiledMapOrientation.Orthogonal: + return TiledMapHelper.GetOrthogonalPosition(mapTile.X, mapTile.Y, map.TileWidth, map.TileHeight); + case TiledMapOrientation.Isometric: + return TiledMapHelper.GetIsometricPosition(mapTile.X, mapTile.Y, map.TileWidth, map.TileHeight); + default: + throw new NotSupportedException($"{map.Orientation} Tiled Maps are not yet implemented."); + } + } + } +} |