source: 2016/27/ohjaajat/VenienteFragore/VenienteFragore/VenienteFragore/TiledTileMap.cs @ 7658

Revision 7658, 4.5 KB checked in by sieerinn, 3 years ago (diff)
Line 
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Linq;
5using System.Text;
6using Jypeli;
7using TiledSharp;
8
9
10public 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        int x, int y, 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        level = tmxMap;
29    }
30
31    public static TiledTileMap FromLevelAsset(string assetName)
32    {
33        var tmxMap = new TmxMap(string.Format("Content/{0}.tmx", assetName));
34        var 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        var game = (SimplePhysics.Game)Game.Instance;
52        game.InitializeTileMap(level.Width, level.Height);
53        game.Level.Width = level.Width * level.TileWidth;
54        game.Level.Height = level.Height * level.TileHeight;
55
56        foreach (var tmxLayer in level.Layers)
57        {
58            CreateTileLayer(tmxLayer, game);
59        }
60
61        foreach (var group in level.ObjectGroups)
62        {
63            CreateObjectLayer(group, game);
64        }
65    }
66
67    private void CreateTileLayer(TmxLayer layer, Game game)
68    {
69        TileMethod method;
70        if (!tileLegend.TryGetValue(layer.Name, out method)) return;
71
72        //double tileWidth = level.TileWidth;
73        //double tileHeight = level.TileHeight;
74
75        foreach (var tile in layer.Tiles)
76        {
77            int gid = tile.Gid;
78            if (gid == 0)
79                continue;
80
81            int tileIndex = tile.Gid - 1;
82            var tile1 = tile;
83            Dictionary<string, string> props = level.Tilesets[0].Tiles.Where(t => level.Tilesets[0].FirstGid + t.Id == tile1.Gid).Select(t => t.Properties).FirstOrDefault();
84            props = props ?? new Dictionary<string, string>();
85            method(tile.X, tile.Y, tileImages[tileIndex], layer.Name, props);
86        }
87    }
88
89    private void CreateObjectLayer(TmxObjectGroup group, Game game)
90    {
91        ObjectMethod method;
92        if (!objectLegend.TryGetValue(group.Name, out method)) return;
93        foreach (var obj in group.Objects)
94        {
95            Shape shape = Shape.Rectangle;
96            if (obj.ObjectType == TmxObjectGroup.TmxObjectType.Ellipse)
97                shape = Shape.Circle;
98
99            var angle = Angle.FromDegrees(-obj.Rotation);
100            var topLeft = new Vector(game.Level.Left + obj.X, game.Level.Top - obj.Y);
101            var len = Math.Sqrt(Math.Pow(obj.Width * 0.5, 2) + Math.Pow(obj.Height * 0.5, 2));
102            var positionFix = Vector.FromLengthAndAngle(len, angle + Angle.FromRadians(-Math.Atan2(obj.Height, obj.Width)));
103            method(topLeft + positionFix, obj.Width, obj.Height, angle, shape, obj.Name, obj.Properties);
104        }
105    }
106
107    private void LoadTileImages()
108    {
109        int tileCount = level.Tilesets.Sum(t => (t.Image.Width.Value / t.TileWidth) * (t.Image.Height.Value / t.TileHeight));
110        tileImages = new Image[tileCount];
111
112        foreach (var tileSet in level.Tilesets)
113        {
114            var tilesetImage = Game.LoadImage(Path.GetFileNameWithoutExtension(tileSet.Image.Source));
115            int tilesW = tileSet.Image.Width.Value / tileSet.TileWidth;
116            int tilesH = tileSet.Image.Height.Value / tileSet.TileHeight;
117            for (int y = 0; y < tilesH; y++)
118            {
119                for (int x = 0; x < tilesW; x++)
120                {
121                    int index = tileSet.FirstGid + (y * tilesW + x) - 1; // Tiled uses one-based indexing for tiles.
122                    tileImages[index] = tilesetImage.Area(x * tileSet.TileWidth, y * tileSet.TileHeight, (x + 1) * tileSet.TileWidth,
123                        (y + 1) * tileSet.TileHeight);
124                }
125            }
126        }
127    }
128}
Note: See TracBrowser for help on using the repository browser.