1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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
80
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
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.");
}
}
}
}
|