1 | using System; |
---|
2 | using System.Collections.Generic; |
---|
3 | using System.IO; |
---|
4 | using System.Linq; |
---|
5 | using System.Text; |
---|
6 | using Jypeli; |
---|
7 | using TiledSharp; |
---|
8 | |
---|
9 | |
---|
10 | public class TiledTileMap |
---|
11 | { |
---|
12 | public delegate void ObjectMethod( |
---|
13 | Vector position, double width, double height, Angle angle, Shape shape, string name, Dictionary<string, string> properties); |
---|
14 | |
---|
15 | public delegate void TileMethod( |
---|
16 | Vector position, double width, double height, Image image, string layerName, Dictionary<string, string> properties); |
---|
17 | |
---|
18 | private readonly Dictionary<string, ObjectMethod> objectLegend = new Dictionary<string, ObjectMethod>(); |
---|
19 | |
---|
20 | private readonly Dictionary<string, TileMethod> tileLegend = new Dictionary<string, TileMethod>(); |
---|
21 | |
---|
22 | private readonly TmxMap level; |
---|
23 | |
---|
24 | private Image[] tileImages; |
---|
25 | |
---|
26 | private TiledTileMap(TmxMap tmxMap) |
---|
27 | { |
---|
28 | this.level = tmxMap; |
---|
29 | } |
---|
30 | |
---|
31 | public static TiledTileMap FromLevelAsset(string assetName) |
---|
32 | { |
---|
33 | TmxMap tmxMap = new TmxMap(string.Format("Content/{0}.tmx", assetName)); |
---|
34 | TiledTileMap map = new TiledTileMap(tmxMap); |
---|
35 | map.LoadTileImages(); |
---|
36 | return map; |
---|
37 | } |
---|
38 | |
---|
39 | public void SetObjectMethod(string layerName, ObjectMethod objectMethod) |
---|
40 | { |
---|
41 | objectLegend[layerName] = objectMethod; |
---|
42 | } |
---|
43 | |
---|
44 | public void SetTileMethod(string layerName, TileMethod tileMethod) |
---|
45 | { |
---|
46 | tileLegend[layerName] = tileMethod; |
---|
47 | } |
---|
48 | |
---|
49 | public void Execute() |
---|
50 | { |
---|
51 | Game game = Game.Instance; |
---|
52 | game.Level.Width = level.Width * level.TileWidth; |
---|
53 | game.Level.Height = level.Height * level.TileHeight; |
---|
54 | |
---|
55 | foreach (var tmxLayer in level.Layers) |
---|
56 | { |
---|
57 | CreateTile(tmxLayer, game); |
---|
58 | } |
---|
59 | |
---|
60 | foreach (var group in level.ObjectGroups) |
---|
61 | { |
---|
62 | CreateObject(group, game); |
---|
63 | } |
---|
64 | } |
---|
65 | |
---|
66 | private void CreateTile(TmxLayer layer, Game game) |
---|
67 | { |
---|
68 | TileMethod method; |
---|
69 | if (!tileLegend.TryGetValue(layer.Name, out method)) return; |
---|
70 | |
---|
71 | double tileWidth = level.TileWidth; |
---|
72 | double tileHeight = level.TileHeight; |
---|
73 | |
---|
74 | for (int i = 0; i < layer.Tiles.Count; i++) |
---|
75 | { |
---|
76 | var tile = layer.Tiles[i]; |
---|
77 | int gid = tile.Gid; |
---|
78 | if (gid == 0) |
---|
79 | continue; |
---|
80 | |
---|
81 | int tileIndex = tile.Gid - 1; |
---|
82 | double realX = game.Level.Left + (tile.X * tileWidth) + (tileWidth / 2); |
---|
83 | double realY = game.Level.Top - (tile.Y * tileHeight) - (tileHeight / 2); |
---|
84 | Dictionary<string,string> props = level.Tilesets[0].Tiles.Where(t => level.Tilesets[0].FirstGid + t.Id == tile.Gid).Select(t => t.Properties).FirstOrDefault(); |
---|
85 | props = props ?? new Dictionary<string, string>(); |
---|
86 | method(new Vector(realX, realY), tileWidth, tileHeight, tileImages[tileIndex], layer.Name, props); |
---|
87 | } |
---|
88 | } |
---|
89 | |
---|
90 | private void CreateObject(TmxObjectGroup group, Game game) |
---|
91 | { |
---|
92 | ObjectMethod method; |
---|
93 | if (!objectLegend.TryGetValue(group.Name, out method)) return; |
---|
94 | foreach (var obj in group.Objects) |
---|
95 | { |
---|
96 | Shape shape = Shape.Rectangle; |
---|
97 | if (obj.ObjectType == TmxObjectGroup.TmxObjectType.Ellipse) |
---|
98 | shape = Shape.Circle; |
---|
99 | |
---|
100 | var angle = Angle.FromDegrees(-obj.Rotation); |
---|
101 | var topLeft = new Vector(game.Level.Left + obj.X, game.Level.Top - obj.Y); |
---|
102 | var len = Math.Sqrt(Math.Pow(obj.Width * 0.5, 2) + Math.Pow(obj.Height * 0.5, 2)); |
---|
103 | var positionFix = Vector.FromLengthAndAngle(len, angle + Angle.FromRadians(-Math.Atan2(obj.Height, obj.Width))); |
---|
104 | method(topLeft + positionFix, obj.Width, obj.Height, angle, shape, obj.Name, obj.Properties); |
---|
105 | } |
---|
106 | } |
---|
107 | |
---|
108 | private void LoadTileImages() |
---|
109 | { |
---|
110 | int tileCount = level.Tilesets.Sum(t => (t.Image.Width.Value / t.TileWidth) * (t.Image.Height.Value / t.TileHeight)); |
---|
111 | tileImages = new Image[tileCount]; |
---|
112 | |
---|
113 | foreach (var tileSet in level.Tilesets) |
---|
114 | { |
---|
115 | Image tilesetImage = Game.LoadImage(Path.GetFileNameWithoutExtension(tileSet.Image.Source)); |
---|
116 | int tilesW = tileSet.Image.Width.Value / tileSet.TileWidth; |
---|
117 | int tilesH = tileSet.Image.Height.Value / tileSet.TileHeight; |
---|
118 | for (int y = 0; y < tilesH; y++) |
---|
119 | { |
---|
120 | for (int x = 0; x < tilesW; x++) |
---|
121 | { |
---|
122 | int index = tileSet.FirstGid + (y * tilesW + x) - 1; // Tiled uses one-based indexing for tiles. |
---|
123 | tileImages[index] = tilesetImage.Area(x * tileSet.TileWidth, y * tilesH, (x + 1) * tileSet.TileWidth, |
---|
124 | (y + 1) * tileSet.TileHeight); |
---|
125 | } |
---|
126 | } |
---|
127 | } |
---|
128 | } |
---|
129 | } |
---|