From a91ca6e7dc226032f4568479f366ac0d2298d83e Mon Sep 17 00:00:00 2001 From: code_b Date: Fri, 14 Jul 2023 23:38:13 +0300 Subject: [PATCH 01/14] test --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 2716e5ac..9ffcaeb1 100644 --- a/README.md +++ b/README.md @@ -28,3 +28,5 @@ Open the main `Jypeli.sln` with Visual Studio 2022 or JetBrains Rider. `TestProjects/Tasohyppelypeli` is a test project ready for development purposes. `TestProjects/Net6Android` is for Android development. + +# test commit \ No newline at end of file From f8f8f4460d00c38d6b06c69659db5d4c535f6f15 Mon Sep 17 00:00:00 2001 From: code_b Date: Fri, 14 Jul 2023 23:41:59 +0300 Subject: [PATCH 02/14] test --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 9ffcaeb1..1beb9e39 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,4 @@ If you do not wish to run android projects, you can also edit `Jypeli.csproj` & Open the main `Jypeli.sln` with Visual Studio 2022 or JetBrains Rider. `TestProjects/Tasohyppelypeli` is a test project ready for development purposes. -`TestProjects/Net6Android` is for Android development. - -# test commit \ No newline at end of file +`TestProjects/Net6Android` is for Android development. \ No newline at end of file From 86a776235df9a46226fd7d8f8b769bad3b5239d4 Mon Sep 17 00:00:00 2001 From: xNPx3 Date: Sun, 16 Jul 2023 13:43:09 +0300 Subject: [PATCH 03/14] Addresses some suggested changes, simplifies tile layer logic --- Jypeli.NET.sln | 11 ++ Jypeli/Jypeli.csproj | 1 + Jypeli/Levels/TiledMap.cs | 239 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 251 insertions(+) create mode 100644 Jypeli/Levels/TiledMap.cs diff --git a/Jypeli.NET.sln b/Jypeli.NET.sln index 524d1295..3347ab9b 100644 --- a/Jypeli.NET.sln +++ b/Jypeli.NET.sln @@ -27,6 +27,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Marswagen", "Examples\Marsw EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Pong", "Examples\Pong\Pong.csproj", "{0EE2DBBF-C8A1-469B-9177-B211B575420E}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TiledExample", "Examples\TiledExample\TiledExample.csproj", "{796CC5EA-BF0F-4B71-9580-92ED125667A0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -103,6 +105,14 @@ Global {0EE2DBBF-C8A1-469B-9177-B211B575420E}.Release|Any CPU.Build.0 = Release|Any CPU {0EE2DBBF-C8A1-469B-9177-B211B575420E}.Release|x86.ActiveCfg = Release|Any CPU {0EE2DBBF-C8A1-469B-9177-B211B575420E}.Release|x86.Build.0 = Release|Any CPU + {796CC5EA-BF0F-4B71-9580-92ED125667A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {796CC5EA-BF0F-4B71-9580-92ED125667A0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {796CC5EA-BF0F-4B71-9580-92ED125667A0}.Debug|x86.ActiveCfg = Debug|Any CPU + {796CC5EA-BF0F-4B71-9580-92ED125667A0}.Debug|x86.Build.0 = Debug|Any CPU + {796CC5EA-BF0F-4B71-9580-92ED125667A0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {796CC5EA-BF0F-4B71-9580-92ED125667A0}.Release|Any CPU.Build.0 = Release|Any CPU + {796CC5EA-BF0F-4B71-9580-92ED125667A0}.Release|x86.ActiveCfg = Release|Any CPU + {796CC5EA-BF0F-4B71-9580-92ED125667A0}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -114,6 +124,7 @@ Global {9A94D71A-702B-4B8A-B67E-266F84775B9C} = {B210F0DC-A8FE-4E35-9EC0-F65E8CC134E8} {834B1B18-421B-4AE8-9F26-A0D5A2376039} = {B210F0DC-A8FE-4E35-9EC0-F65E8CC134E8} {0EE2DBBF-C8A1-469B-9177-B211B575420E} = {B210F0DC-A8FE-4E35-9EC0-F65E8CC134E8} + {796CC5EA-BF0F-4B71-9580-92ED125667A0} = {B210F0DC-A8FE-4E35-9EC0-F65E8CC134E8} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {2E893DBE-1BA1-4FEC-B40D-37995FB065B9} diff --git a/Jypeli/Jypeli.csproj b/Jypeli/Jypeli.csproj index 4478ed1c..1aa305b4 100644 --- a/Jypeli/Jypeli.csproj +++ b/Jypeli/Jypeli.csproj @@ -133,6 +133,7 @@ + diff --git a/Jypeli/Levels/TiledMap.cs b/Jypeli/Levels/TiledMap.cs new file mode 100644 index 00000000..e914cf7b --- /dev/null +++ b/Jypeli/Levels/TiledMap.cs @@ -0,0 +1,239 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Reflection; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Jypeli +{ + /// + /// TODO summary tähän + /// + public class TiledMap + { +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + + public delegate void TileMethod(Vector position, double width, double height, Image tileImage); + protected Dictionary overrides = new Dictionary(); + + public List tilesets; + public TiledTileMap tilemap; + +#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member + + + /// + /// Loads the map data for creating the level. + /// + /// The map file in JSON format + /// The tileset files in JSON format + public TiledMap(string tilemapFile, params string[] tilesetFiles) + { + tilesets = new List(); + tilemap = TileMapLoader(tilemapFile); + foreach (string f in tilesetFiles) + { + tilesets.Add(TilesetLoader(f)); + } + } + + /// + /// Sets an method to call when looping through the tile matrix + /// + /// Tile ID in Tiled to assign a method for + /// The method to call + public void SetOverride(int tilenum, TileMethod method) + { + overrides[tilenum + 1] = method; + } + + /// + /// Creates the level. + /// + public void Execute() + { + double mapWidth = tilemap.Width * tilemap.TileWidth; + double mapHeight = tilemap.Height * tilemap.TileHeight; + + Game.Instance.Level.Size = new Vector(mapWidth, mapHeight); + Game.Instance.Level.CreateBorders(); + + + for (int l = 0; l < tilemap.Layers.Count; l++) + { + JArray data = (JArray)tilemap.Layers[l]["data"]; + object props = tilemap.Layers[l].TryGetValue("properties", out props) ? props : null; + + int? _layer = null; + + /*if (props != null) // if layer is manually set in props + { + JToken _token = ((JArray)props).SelectToken("$[?(@.name == 'Layer')]"); // find token + _layer = (int?)_token["value"]; // get value + ((JArray)props).Remove(_token); // remove original token to avoid exceptions later + } + + _layer = _layer != null ? (int)_layer : -1;*/ + + _layer = l - 3; // Bottom layer in tiled corresponds to in-game layer -3 + + // TODO: write check for more than 7 total layers + + /*Debug.WriteLine(l.ToString()); + Debug.WriteLine(_layer.ToString());*/ + + int i = 0; + for (int row = 0; row < tilemap.Height; row++) + { + for (int col = 0; col < tilemap.Width; col++) + { + double _x = -mapWidth / 2 + col * tilemap.TileWidth + tilemap.TileWidth / 2; + double _y = mapHeight / 2 + -row * tilemap.TileHeight - tilemap.TileHeight / 2; + + int tilenum = (int)data[i]; + if (tilenum != 0) + { + TiledTileset _tileset = tilesets[0]; + int j = 1; + while (tilenum > _tileset.TileCount) + { + tilenum -= _tileset.TileCount; + _tileset = tilesets[j]; + j++; + } + + if (overrides.ContainsKey(tilenum)) + { + overrides[tilenum].Invoke(new Vector(_x, _y), _tileset.TileWidth, _tileset.TileHeight, TiledMap.GetTileImage(tilenum, _tileset)); + } + else + { + PhysicsObject t = TiledMap.CreateTile(new Vector(_x, _y), _tileset.TileWidth, _tileset.TileHeight, TiledMap.GetTileImage(tilenum, _tileset), (JArray)props); + Game.Instance.Add(t, (int)_layer); + } + } + i++; + } + } + } + } + + static PhysicsObject CreateTile(Vector pos, double width, double height, Image tileImage, JArray props) + { + PhysicsObject tile = PhysicsObject.CreateStaticObject(width, height); + tile.Position = pos; + tile.Color = Color.Transparent; + + // layer properties + if (props != null) + foreach (var prop in props) + { + PropertyInfo propertyInfo = tile.GetType().GetProperty(prop["name"].ToString()); + + // testing if calling MakeOneWay works when there is a true bool with the same name + if (prop["name"].ToString() == "MakeOneWay" && (bool)prop["value"] && prop["type"].ToString() == "bool") + { + tile.MakeOneWay(); + } + + if (propertyInfo != null && propertyInfo.CanWrite) + { + try + { + propertyInfo.SetValue(tile, Convert.ChangeType(prop["value"], propertyInfo.PropertyType)); + } + catch (Exception e) + { + System.Diagnostics.Debug.WriteLine(e.Message); + } + } + } + + tile.Image = tileImage; + tile.Shape = Shape.Rectangle; // Shape.FromImage(tileImg); + tileImage.Scaling = ImageScaling.Nearest; + + return tile; + } + + static Image GetTileImage(int tilenum, TiledTileset tileset) + { + if (tilenum <= 0) + { + return null; + } + + Image tiles = Game.LoadImage(tileset.Image); + tilenum--; + + int col = tilenum % tileset.Columns + 1; + int row = tilenum / tileset.Columns + 1; + + int left = (col - 1) * (tileset.TileWidth + tileset.Spacing); + int top = (row - 1) * (tileset.TileHeight + tileset.Spacing); + int right = left + tileset.TileWidth; + int bottom = top + tileset.TileHeight; + + Image t = tiles.Area(left, top, right, bottom); + + return t; + } + + /// + /// Tileset data structure. Contains information how the tileset image should be split into individual tiles. + /// + public struct TiledTileset + { + public int Columns; + public string Image; + public int ImageHeight; + public int ImageWidth; + public int Margin; + public string Name; + public int Spacing; + public int TileCount; + public string TiledVersion; + public int TileHeight; + public int TileWidth; + public string Type; + public string Version; + } + static TiledTileset TilesetLoader(string file) + { + string json = File.ReadAllText(String.Format("Content\\{0}", file)); + TiledTileset set = JsonConvert.DeserializeObject(json); + return set; + } + + /// + /// Tilemap data structure. Contains the actual map data. + /// + public struct TiledTileMap + { + public int CompressionLevel; + public int Height; + public bool Infinite; + public List> Layers; + public int NextLayerID; + public int NextObjectID; + public string Orientation; + public string RenderOrder; + public string TiledVersion; + public int TileHeight; + public List> Tilesets; + public int TileWidth; + public string Type; + public string Version; + public int Width; + } + + static TiledTileMap TileMapLoader(string file) + { + string json = File.ReadAllText(String.Format("Content\\{0}", file)); + TiledTileMap map = JsonConvert.DeserializeObject(json); + return map; + } + } +} \ No newline at end of file From 363150127f45bd9b99521b0c102a8b055644ad4c Mon Sep 17 00:00:00 2001 From: xNPx3 Date: Wed, 19 Jul 2023 22:55:56 +0300 Subject: [PATCH 04/14] Fixed typo. --- Jypeli/Game/Time.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jypeli/Game/Time.cs b/Jypeli/Game/Time.cs index 1cef2c12..a4171c49 100644 --- a/Jypeli/Game/Time.cs +++ b/Jypeli/Game/Time.cs @@ -29,7 +29,7 @@ public partial class Game /// Tällä hetkellä myös pelin FPS-tavoite asettuu samaan arvoon. /// Tämän muuttaminen "vääräksi" arvoksi saattaa aiheuttaa erikoisia seurauksia jos on päällä. /// - public static double UpdatesPerSecod + public static double UpdatesPerSecond { get => Instance.Window.UpdatesPerSecond; set From 957ee00af446983a8c08fcdddb4953f069a58e0b Mon Sep 17 00:00:00 2001 From: xNPx3 Date: Wed, 19 Jul 2023 23:06:12 +0300 Subject: [PATCH 05/14] Added Tiled tilemap example project. --- Examples/Snowman/Content/map.tmj | 294 +++++++++++++++++++ Examples/Snowman/Content/tiles.png | Bin 0 -> 6185 bytes Examples/Snowman/Content/tileset.tsj | 14 + Examples/Snowman/Content/tileset_license.txt | 22 ++ Examples/Snowman/Ohjelma.cs | 25 ++ Examples/Snowman/Snowman.cs | 129 ++++++++ Examples/Snowman/Snowman.csproj | 34 +++ Jypeli.NET.sln | 20 +- Jypeli/Levels/TiledMap.cs | 133 ++++++--- 9 files changed, 623 insertions(+), 48 deletions(-) create mode 100644 Examples/Snowman/Content/map.tmj create mode 100644 Examples/Snowman/Content/tiles.png create mode 100644 Examples/Snowman/Content/tileset.tsj create mode 100644 Examples/Snowman/Content/tileset_license.txt create mode 100644 Examples/Snowman/Ohjelma.cs create mode 100644 Examples/Snowman/Snowman.cs create mode 100644 Examples/Snowman/Snowman.csproj diff --git a/Examples/Snowman/Content/map.tmj b/Examples/Snowman/Content/map.tmj new file mode 100644 index 00000000..d6a56abd --- /dev/null +++ b/Examples/Snowman/Content/map.tmj @@ -0,0 +1,294 @@ +{ "compressionlevel":-1, + "height":40, + "infinite":false, + "layers":[ + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 155, 155, 155, 155, 155, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 103, 103, 103, 103, 103, 103, 104, 0, 0, 0, 0, 102, 103, 103, 103, 103, 103, 103, 104, 0, 0, 0, 0, 0, 0, 0, + 0, 49, 50, 50, 50, 51, 0, 0, 0, 0, 0, 0, 0, 142, 143, 6, 123, 123, 123, 123, 124, 69, 69, 69, 102, 26, 123, 123, 5, 143, 143, 143, 144, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 143, 143, 143, 6, 25, 103, 103, 103, 26, 123, 5, 143, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 143, 143, 143, 143, 143, 143, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 143, 6, 123, 123, 123, 123, 5, 143, 143, 144, 0, 0, 0, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 143, 143, 143, 143, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 63, 63, 63, 63, 63, 63, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 63, 63, 63, 63, 63, 26, 123, 123, 123, 123, 123, 124, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 63, 63, 63, 26, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 124, 0, 0, 0, 109, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 62, 63, 63, 63, 63, 0, 0, 0, 63, 63, 26, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 124, 0, 0, 42, 43, 44, 0, 0, + 63, 63, 63, 63, 63, 63, 63, 63, 63, 26, 123, 123, 123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 25, 63, 63, 63, 26, 123, 123, 25, 23, 23, 23, 26, 123, 123, 25, 103, 103, 103, 26, 123, 124, 69, 69, 69, 69, 69, 69, 69, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 124, 103, 103, 103, 103, 103, 103, 103, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 124, 123, 123, 123, 123, 123, 123, 123], + "height":40, + "id":1, + "name":"Blocks", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":40, + "x":0, + "y":0 + }, + { + "data":[0, 70, 0, 0, 0, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 90, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 90, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 90, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 90, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0, + 0, 90, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 132, 0, 146, 0, + 0, 90, 0, 0, 0, 90, 0, 0, 0, 0, 0, 52, 0, 0, 86, 0, 145, 0, 0, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 90, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 125, 126, 72, 0, 129, 85, 0, 0, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 0, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 68, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 125, 128, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 129, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 128, 0, 0, 0, 0, 86, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 0, 0, 0, 0, 54, 54, 54, 0, 0, 0, 0, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74, 74, 0, 0, 0, 0, 74, 74, 74, 0, 0, 0, 0, 74, 74, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 0, 74, 74, 74, 0, 0, 0, 0, 74, 74, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":40, + "id":3, + "name":"Deco", + "opacity":1, + "properties":[ + { + "name":"CollisionIgnoreGroup", + "type":"int", + "value":1 + }], + "type":"tilelayer", + "visible":true, + "width":40, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 147, 147, 147, 147, 147, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 63, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":40, + "id":2, + "name":"One-way", + "opacity":1, + "properties":[ + { + "name":"MakeOneWay", + "type":"bool", + "value":true + }], + "type":"tilelayer", + "visible":true, + "width":40, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 179, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":40, + "id":4, + "locked":true, + "name":"Player", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":40, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 19, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 39, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 98, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, 122, 123, 123, 124, 0, 0, 0, 122, 123, 123, 124, 0, 0, 0, 122, 123, 124, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124, 0, 68, 0, 122, 123, 123, 124, 0, 68, 0, 122, 123, 123, 124, 0, 68, 0, 122, 123, 124, 68, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, 122, 123, 123, 124, 0, 0, 0, 122, 123, 123, 124, 0, 0, 0, 122, 123, 124, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":40, + "id":5, + "name":"Deco", + "opacity":1, + "properties":[ + { + "name":"CollisionIgnoreGroup", + "type":"int", + "value":1 + }], + "type":"tilelayer", + "visible":true, + "width":40, + "x":0, + "y":0 + }], + "nextlayerid":6, + "nextobjectid":1, + "orientation":"orthogonal", + "renderorder":"right-down", + "tiledversion":"1.10.1", + "tileheight":18, + "tilesets":[ + { + "firstgid":1, + "source":"tileset.tsj" + }], + "tilewidth":18, + "type":"map", + "version":"1.10", + "width":40 +} \ No newline at end of file diff --git a/Examples/Snowman/Content/tiles.png b/Examples/Snowman/Content/tiles.png new file mode 100644 index 0000000000000000000000000000000000000000..40fce07d07176ced41c455418454db6815f5675e GIT binary patch literal 6185 zcmV+^7}n>BP)l0JjpCns{^Wu5%%PQ|NrixVEo5|m>Mng zv>Qz2{oO#_r2qf`0d!JM zQvg8b*k%9#7j{WRK~#9!?VSsE+qMpX)n$#Bu5&6eu_gWgA9_Xc1%Mz4Qk0wRn&;F> zP$_osi2wocF$_1-hOOOV;Y}jjZe63s%Z7!tp`vm33S~c|#>)oDb?8Gm<&nmTBbgW6 zT2-HrNpUPoI}h$&sZ5GPjBSXY=3!{l-+tqWnz?KwZ5YO}EF(A+!ZGQ86TmT{262?& zEX$v$8P&^Ve?^U#{rve}y6%0)5wv-~v(`n6sp=z{yZ1yKaqrl1OeGw}&hi)>`!L+^WtqjX^$MlR#tKV<{ufOu;sFUQ%Ri_Y z)yrh>QR8JANB%mGgFcbW^DKItPr|VZaj5O8$=NTj>`m>u7ZDz)$82g|SEu9cJFEI# z=3bx-UMI)lf4E%Gbr<{d`@6^C6aaD5>hDY(5DAn`MI4LkHVg44pvPoztZ#2?BwN=N z;BeZ!035N*;Mi5q;<#8GH?OSGsQ}2FJkr&OWg}9(Qg`>t$?j?x;7=(T=p6|hMPsG) z9+|JuV~WP=ZEHlfYS|i$mC^9UE1#EbI4-a!(Cgkk4%89+@F@N0j;Y7lseXG*m3!r6 zN~>O#WwL>;3OH0SYCceySZ_jlPz{c^Hzy3nimEx5f!@LNB7$RNaExh7GUjj?mAF?< zW>i|1)x{k=4sX_w>&E6Q=e8{kgu_YeaZsa%1jJa~{mAMTS$m1^usE=yI9W=iR8oz@ zdl^M>prI9Y?zK49mEx#!<;m;(Ko>sYw@4=Sy;k)TG$ankH04w}dD#T~b`Kn7N1n&w ze0<(m^~FJlM?*{RxQE^WbPsVT;*M2f#H8dn?9Bm(8(IZdUK-}s_73b%{yjLnN`tY| zqKT*!;!qJv7kp0@I707`1cCXuW7m8p?)W=uylh#@*X^GPsD1>-stLyp`UwU{q|!LN zOW%V#&M24<& zIP|!d7AV?roSb0S*L|S`yMBFnF;BOKQG0LvnVAH8yRkaE{FLf#zpMOYcvu|%eX+vf zdtmEHz@)25t*-ppp6%I^?W-HBqlPJd59f*h_L6yP_|<%cEhXa$;78()ukFf@x^12Z z7^pH@c2p!X&XwPe;CN(lb`{mi%Z1qZUa5@7alLBghF2~7KrJQXYUTL^dm)ARARH(* zOsIg_H>bWmol(wD0p#Ic*8@T)sl=hCNkuZH6vko0a);w{Q?1r< zc(tnc4d5U$u2yapIJV;GUMrX5SP2gE4~~u;B9XD0V8Y(Wl$I%!#E)jtBe(kL#duPt_Vj|EANIw zNpYw?^$rDiP*>jEJDiWt7^@wJb{{1iv?p+ghAzEhgg7RyccADY`P93IQ3-kn_>Ewo zYj4K`UEM``87u5h4&xyHWH`%MDHY*R?hoWuYX8&Ans6wHgUdVB#T~om^Kr*OQ;1!0 zG}g*TUn@70Mko$6T*WFiSH@~~IF#6x<1jEJNt)x1qRirWvBf|Mj;q{Q9hphuYUR_E zcIB-72RJ5pVe33AG9y<|7w?iJDdLcXf&FnH&1YS?>NyMXDrv_|71IZrvW;MUy2qq8Y1gj9RA*YsfcaqnIvf(S5ZcnPq2?) z1&7%n!fz81WV0K`gs<>*SyYq|hcYRSwH601ly9%CNs=Dbz+IKfeqm(WH(MdreVdjk zhy(1}5oAM*1AcE*PYbMS#XO2QP|iw$A`QZkPOx8VYUTZLpvK8eUA!zijw4yKSmiiY z84i*pxuR;hyjDJZ?c%KQ6Lu37H#!F5GQB(5bio z)x!#@D?hhZo=%dCnOb>nUAa=3rTSC`a#k@7Eu%C@)+8~Fx@D9n!EtV_e57F@mpF;? zT_?Em11Uu1ra14-#vRH|YDxGBFGJm^2aeh>a11!`T64Q*CeDZx*?&91UiKX))yms9 zZv8KppN_in=304n=i>5C$j|m{&-T@8<>EHamy0n$mrIE4Utf($F<*aU7+7tjPTPb1 ztKncqR!b$0LUESEabOSjuTv|p!(p@xap>=LbFw6k#M;1$&pUfz4(^(9oAUA za7#5CaG-SI@jci(<49^UJhdz+_uVhsiad;hQNBLVXm#b+_5?e@(YgnFUmRK~ye8-Q z+qcAj_**s_P6NM6mJKR6Ju^jE@3{6^P{7V4amn=3M&M`E%Jn1qjpdQTv0ePl^_w~z zimVEub}nBle`y<82^OOrnrGFwR<4!%jpdOrR_KOctA0svsM0Ao@>+S91pAoTgMBQO zpU%nX?&{_26^}z(s(^3%y7vs^JK*MCopCIugn{B|Z{q`M<;JDPJXjp`V#6b%5jOWi z$`;_rxN!V zF98R)2YYj^yz9Dht7dJ4sOrnIftxO>y^H4Hz8=KE>@uB*$|Kb$x2BBuU~jLL_gz;` z*4EQAgz_>rWPjaT_Dy)U~;hCmG37MxDy}j2?fV+ z)K-|Dwen|swy#tx=T;I+WsH!&wPdVLC_*xOuiy%E5hhr=tbFJ4-QmrKop)OC(PoQo4P~z zHYE3l0VevxHOF!6-2sHr_d6P`-fnpCW^jCvHVhvhWf{QHxLy6?mUGZvWD*O9Lk@$tzXTieYA5#I1G=? zX8i#g80ady`palJEWU|xSXqq2^^U$%7arO>RCJ~}(DkNzN+Xg19G__%iS7}FfiCn4 z1tl?#adbHPrVt&mD4b>(XPog=F+ zhr^v~f^Znqw(Fitjik>j=X!!u0PhZ^tp@a11A<5UHAH8>crKE0d*l>)WeJe&;Mk zJAi}lGW=z#Q-Zw*j(wni^Q-(Dahy|rdJvBFBpfv|Q1+(}WOfq3vpw6h{pMPE#a`&g zn!s4ib77C5zQ&41MJZ#2&aS{0^mgUT@+cnVS~<7k)5`F!%g0>#LRAk!rIju6r?Unp z6=#d*kaxkMN;q_EXteIM?`3cw>_a$~B#t$O!`I4TR^o9u_`T2{hXd%|$=?5ZH+y0K zJQ@b-&$0SUwQg_%tqYk+xAt)xK27{V#aVVQbXogJT1DKU=k=Q1eDy|*W>;S)+qRYc z>n|%imLy5z&{H#597}Q<`UyC|_Ngkn`F0D9z@zNSwU?l(_cASDaimj-Gh@_vV`Xuy z)2db`@8EZ%3(XjGiJ490#k~maF7?>N&oKP$GC={BK zK$pF6IAX)(*38z4C^N-j-kPo zGra>2e&y5NW^S(Nz!@fMCDzI)tM|HcexU1ApU06jOy)mOz9Zg1iN`@hJ}0ALxolD> zJFET~Kv#b(_wnj+%nk=y-)u%!a6^5XDT`DOWgu}PoibfYAu{v6 zR;6ljbX`}T8tD39Nu^H@Nco9)nI^OO9+SDW+isxnk=u$xx}e~3IJ&JXPtB?FX|)Uv z!^8EAcw0TZPYK?da>2>6#q~DH&M4C5Hsu6+M`P7zU3q#hbn{;rN9>ei)pN!w-nf-Z zT~^@`EJhRHU$Rwr6W9l|S@2 z6>c3hTfA?noYQloSi_XsrB@=C8>>ZTz#>QAgkx&OK~>GDUb>w-DaCW=M)AIbJDXf4 z<8a_YEc|de9H>?<#-RWX#UPrdIvmktdh;{6#!t+b(161MrQY5ym$$b(4j*V!)tfX_ zgu{gEwK(8$k}!{@Fb*1)95PmN9Cj@UQ8mBTL4w1F8R67xgG2Ku;n2$bBM$j|r5uHU zfBXvRLIwwXY-1dX#Q}4EDIBWVci`RLvXi++iX%Sr!pZVL{HgL`3%AMO*my{KM+J^- z@9?@)Qe&kM4$fGCOjI$2s2Xti)mEeVlI{un;R$A6z$}jt{39HforkP<&~)K1{{mBp zrQYE(4K=Pj6dn|7tVB4JVpl|^jTPMd%&7f_AA4`SZm1XSy#rB-W|43>q^`U-4p)3i zx@`uB_Z>7)l=}{lJroUe!2royDQubIMb>*Sig2*Adfbj}zZnOti>F3WcrXs?=Sx(x zN#RgwKf$FHRfGe&X>X_GIDqu0I{_Wd>e+YEds(0>r>V#og1I!#Zz=y z9Im{P9O%l!KxP!>&ePGWwdf#<`gR7#UL(9*-ck3^9Rv?_V;u4F%_BJ2W&Vjmtj4h> zaU|>J5JzK1SK+mR{3wdSaSJ$Zq`y!cm+ic5jKkO~vg^X$bUyej996aQy?5|Q_xj>& zrYB5OW~pXk6lHPTQ4GkPMQNA8V;t}9Jo*U7@JAPLuT%m@FjmP? zlmv$z=u#ZcZBrb6Q+w>nLv^t?j(Eo&k7J#RJwZ^C0=056j;!yseY6X;<4 zfs;bJ;lQeY+0PTm$fP(9mY+BpL%g6s1t$yAQqTJNvpw6tr&i9D^U526OKatl6DWq# zl(!1sG4RWf{)IToJF(UA;4-?+G%8&ASvaQREJRX@MfHwpD&nB4Go(9DKLSVF!tJwg zOje;&Tz*mo9IF&ZG#Ysjj>PE(Q1mDqp^qhHNn@2>-=S24v6{_EJ<(XbxLu_f$Hd}b z4IdG0AMNc;e>$sXv+fbA9?8tLAC)-xN!VD{;5!;|;PaCF!UMc4=k?Xew(mON*mVBS z-pH<&MuZ;~3k0kRego>aGWU~vw5o9I_sl^Fu?(tynlgJKPRCsN_Kx~JvpCYrGMkN+ zR{Wn^1ImwaL}zTt7H-#$toC=YF9gR&5r<0j1jUx0T5zz%)c!dB+#A8M@%a;Pq*#li zexN%C3qg!kkXan6ZJ?`Uy~8b6wSUE&80e;QLI>iG9f$59SsXztLLA}KRl0IQ!#@eY zl_RI!;Y4QMhZ!6}&0L7lPU9dB`_@t%;KOBbM1Mg7N9bw=9DZn<2?NO-Egr`TJL=lF z;q5FlR-rg6Hde%gq>gMv7YrpF%-Si|SfS3Ao)kL8ICj(2ApGpxY&9r9)izsZHQIgwX@GyYjB#W^TZKhh0nphbRmr zK!((N49wo*b;hb=7^vhp9C3>S4J2D=%zHic6F;Q^(VU6OB}tMaMzYeCHz!Hjdxz@- z&}ngQOp47I!SQU*_H57gY|r-p+}KTa*x`TrWca$UEtOE?2acR5qZyU*YCecVaBoT$tB=JYRI~KD_V-{kPt`X>g3zzH zq=5uSY^-3#qV4y^GWzGn(BpSV$#@*`XO0uRb-%9($Iu7Ike59KN9&VYVd!`qt-XV- zJIsd-Ny+bUZ(V03c^pEO3e+b<$th6y`{Xz>DlMu?hEk4WK7@lek`eF+yegg!bM9C7bp%xMFTx!%2Z#xbz(ali;k%%*$*%ik-yE;G^j-K((8nu zxsd$GzKJ;bk$7H&&) + /// The main class. + /// + public static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + using var game = new Snowman(); + game.Run(); + } + } +} diff --git a/Examples/Snowman/Snowman.cs b/Examples/Snowman/Snowman.cs new file mode 100644 index 00000000..ae82b61b --- /dev/null +++ b/Examples/Snowman/Snowman.cs @@ -0,0 +1,129 @@ +using System; +using Jypeli; + +namespace Snowman +{ + public class Snowman : PhysicsGame + { + PlatformCharacter player; + TiledMap map; + double moveSpeed = 100; + + IntMeter counter; + + public override void Begin() + { + Level.BackgroundColor = Color.LightBlue; + Gravity = new Vector(0, -1500); + + Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, null); + + map = new TiledMap("map.tmj", "tileset.tsj"); + map.SetOverride(67, CreateDiamond); + map.SetOverride(68, CreateSpikes); + map.SetOverride(108, CreateJumpBlock); + map.SetOverride(145, CreateSnowman); + map.SetOverride(178, CreatePlayer); + map.Execute(); + + + counter = new IntMeter(0); + } + + private void CreateSnowman(Vector position, double width, double height, Image tileImage) + { + PhysicsObject snowman = PhysicsObject.CreateStaticObject(width, height); + snowman.Position = position; + tileImage.Scaling = ImageScaling.Nearest; + snowman.Image = tileImage; + snowman.Tag = "snowman"; + Add(snowman, -1); + } + + private void CreateDiamond(Vector position, double width, double height, Image tileImage) + { + PhysicsObject diamond = PhysicsObject.CreateStaticObject(width, height); + diamond.Position = position; + tileImage.Scaling = ImageScaling.Nearest; + diamond.Image = tileImage; + diamond.Tag = "diamond"; + diamond.Shape = Shape.Circle; + diamond.Oscillate(Vector.UnitY, 3, 0.5); + Add(diamond, 2); + } + + private void CreateSpikes(Vector position, double width, double height, Image tileImage) + { + PhysicsObject spike = PhysicsObject.CreateStaticObject(width, height); + spike.Position = position; + tileImage.Scaling = ImageScaling.Nearest; + spike.Image = tileImage; + spike.Tag = "spike"; + spike.Shape = Shape.FromImage(tileImage); + Add(spike, -2); + } + + private void CreatePlayer(Vector position, double width, double height, Image tileImage) + { + player = new PlatformCharacter(16, 16); + player.Position = position; + player.CollisionIgnoreGroup = 1; + + Image p = map.GetTileImage(146, map.tilesets[0]); + p = Image.Mirror(p); + p.Scaling = ImageScaling.Nearest; + player.Image = p; + + Add(player, 1); + + Camera.Follow(player); + Camera.StayInLevel = true; + Camera.ZoomFactor = 4; + + AddCollisionHandler(player, "jump block", Boost); + AddCollisionHandler(player, "diamond", CollectDiamond); + AddCollisionHandler(player, "snowman", (p, o) => + { + Keyboard.Clear(); + Keyboard.Listen(Key.Escape, ButtonState.Pressed, Exit, null); + MessageDisplay.Add(String.Format("You win! You collected {0}{1} diamonds. Press ESC to exit.", counter.Value == 6 ? "all " : "", counter.Value)); + }); + AddCollisionHandler(player, "spike", (p, o) => player.Position = position); + + Keyboard.Listen(Key.Left, ButtonState.Down, () => player.Walk(-moveSpeed), null); + Keyboard.Listen(Key.Right, ButtonState.Down, () => player.Walk(moveSpeed), null); + Keyboard.Listen(Key.Space, ButtonState.Pressed, () => player.Jump(450), null); + } + + private void CollectDiamond(IPhysicsObject collidingObject, IPhysicsObject otherObject) + { + otherObject.IgnoresCollisionResponse = true; + otherObject.Destroy(); + counter.Value += 1; + } + + private void Boost(IPhysicsObject collidingObject, IPhysicsObject otherObject) + { + if (player.Y > otherObject.Y) + { + Image i1 = map.GetTileImage(108, map.tilesets[0]); + Image i2 = map.GetTileImage(109, map.tilesets[0]); + i1.Scaling = ImageScaling.Nearest; + i2.Scaling = ImageScaling.Nearest; + otherObject.Image = i1; + player.ForceJump(1000); + Timer.SingleShot(1, () => otherObject.Image = i2); + } + } + + private void CreateJumpBlock(Vector position, double width, double height, Image tileImage) + { + PhysicsObject jumpBlock = PhysicsObject.CreateStaticObject(width, height); + jumpBlock.Position = position; + tileImage.Scaling = ImageScaling.Nearest; + jumpBlock.Image = tileImage; + jumpBlock.Tag = "jump block"; + Add(jumpBlock, -2); + } + } +} \ No newline at end of file diff --git a/Examples/Snowman/Snowman.csproj b/Examples/Snowman/Snowman.csproj new file mode 100644 index 00000000..694ea9f3 --- /dev/null +++ b/Examples/Snowman/Snowman.csproj @@ -0,0 +1,34 @@ + + + + WinExe + net6.0 + false + false + + + + + + + + + + + Always + + + Always + + + Always + + + + + + + + + + diff --git a/Jypeli.NET.sln b/Jypeli.NET.sln index 3347ab9b..3744c6ec 100644 --- a/Jypeli.NET.sln +++ b/Jypeli.NET.sln @@ -27,7 +27,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Marswagen", "Examples\Marsw EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Pong", "Examples\Pong\Pong.csproj", "{0EE2DBBF-C8A1-469B-9177-B211B575420E}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TiledExample", "Examples\TiledExample\TiledExample.csproj", "{796CC5EA-BF0F-4B71-9580-92ED125667A0}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Snowman", "Examples\Snowman\Snowman.csproj", "{29C4DB79-51C6-4CF5-9E85-71225C5CEFFD}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -105,14 +105,14 @@ Global {0EE2DBBF-C8A1-469B-9177-B211B575420E}.Release|Any CPU.Build.0 = Release|Any CPU {0EE2DBBF-C8A1-469B-9177-B211B575420E}.Release|x86.ActiveCfg = Release|Any CPU {0EE2DBBF-C8A1-469B-9177-B211B575420E}.Release|x86.Build.0 = Release|Any CPU - {796CC5EA-BF0F-4B71-9580-92ED125667A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {796CC5EA-BF0F-4B71-9580-92ED125667A0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {796CC5EA-BF0F-4B71-9580-92ED125667A0}.Debug|x86.ActiveCfg = Debug|Any CPU - {796CC5EA-BF0F-4B71-9580-92ED125667A0}.Debug|x86.Build.0 = Debug|Any CPU - {796CC5EA-BF0F-4B71-9580-92ED125667A0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {796CC5EA-BF0F-4B71-9580-92ED125667A0}.Release|Any CPU.Build.0 = Release|Any CPU - {796CC5EA-BF0F-4B71-9580-92ED125667A0}.Release|x86.ActiveCfg = Release|Any CPU - {796CC5EA-BF0F-4B71-9580-92ED125667A0}.Release|x86.Build.0 = Release|Any CPU + {29C4DB79-51C6-4CF5-9E85-71225C5CEFFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {29C4DB79-51C6-4CF5-9E85-71225C5CEFFD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {29C4DB79-51C6-4CF5-9E85-71225C5CEFFD}.Debug|x86.ActiveCfg = Debug|Any CPU + {29C4DB79-51C6-4CF5-9E85-71225C5CEFFD}.Debug|x86.Build.0 = Debug|Any CPU + {29C4DB79-51C6-4CF5-9E85-71225C5CEFFD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {29C4DB79-51C6-4CF5-9E85-71225C5CEFFD}.Release|Any CPU.Build.0 = Release|Any CPU + {29C4DB79-51C6-4CF5-9E85-71225C5CEFFD}.Release|x86.ActiveCfg = Release|Any CPU + {29C4DB79-51C6-4CF5-9E85-71225C5CEFFD}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -124,7 +124,7 @@ Global {9A94D71A-702B-4B8A-B67E-266F84775B9C} = {B210F0DC-A8FE-4E35-9EC0-F65E8CC134E8} {834B1B18-421B-4AE8-9F26-A0D5A2376039} = {B210F0DC-A8FE-4E35-9EC0-F65E8CC134E8} {0EE2DBBF-C8A1-469B-9177-B211B575420E} = {B210F0DC-A8FE-4E35-9EC0-F65E8CC134E8} - {796CC5EA-BF0F-4B71-9580-92ED125667A0} = {B210F0DC-A8FE-4E35-9EC0-F65E8CC134E8} + {29C4DB79-51C6-4CF5-9E85-71225C5CEFFD} = {B210F0DC-A8FE-4E35-9EC0-F65E8CC134E8} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {2E893DBE-1BA1-4FEC-B40D-37995FB065B9} diff --git a/Jypeli/Levels/TiledMap.cs b/Jypeli/Levels/TiledMap.cs index e914cf7b..a601e08b 100644 --- a/Jypeli/Levels/TiledMap.cs +++ b/Jypeli/Levels/TiledMap.cs @@ -9,14 +9,16 @@ namespace Jypeli { /// - /// TODO summary tähän + /// Tilemap which can load JSON data from maps created with Tiled (https://www.mapeditor.org/). + /// Allows assigning a custom function for individual tile numbers, overriding the default tile creation function. /// public class TiledMap { #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - public delegate void TileMethod(Vector position, double width, double height, Image tileImage); + delegate void TileMethod(Vector position, double width, double height, Image tileImage); protected Dictionary overrides = new Dictionary(); + public Dictionary tileImages = new Dictionary(); public List tilesets; public TiledTileMap tilemap; @@ -31,6 +33,8 @@ public class TiledMap /// The tileset files in JSON format public TiledMap(string tilemapFile, params string[] tilesetFiles) { + // TODO: load tileset files automatically (relative paths defined in map files) + tilesets = new List(); tilemap = TileMapLoader(tilemapFile); foreach (string f in tilesetFiles) @@ -40,13 +44,13 @@ public TiledMap(string tilemapFile, params string[] tilesetFiles) } /// - /// Sets an method to call when looping through the tile matrix + /// Override the default tile creation function for a tile. /// - /// Tile ID in Tiled to assign a method for - /// The method to call - public void SetOverride(int tilenum, TileMethod method) + /// Tile ID (in Tiled) to assign a method for + /// Callable TileMethod in the form of void TileMethod(Vector position, double width, double height, Image tileImage) + public void SetOverride(int tilenum, TileMethod tileMethod) { - overrides[tilenum + 1] = method; + overrides[tilenum + 1] = tileMethod; } /// @@ -58,7 +62,7 @@ public void Execute() double mapHeight = tilemap.Height * tilemap.TileHeight; Game.Instance.Level.Size = new Vector(mapWidth, mapHeight); - Game.Instance.Level.CreateBorders(); + //Game.Instance.Level.CreateBorders(); for (int l = 0; l < tilemap.Layers.Count; l++) @@ -77,13 +81,10 @@ public void Execute() _layer = _layer != null ? (int)_layer : -1;*/ - _layer = l - 3; // Bottom layer in tiled corresponds to in-game layer -3 + _layer = l - 2; // Bottom layer in Tiled corresponds to in-game layer -2 // TODO: write check for more than 7 total layers - /*Debug.WriteLine(l.ToString()); - Debug.WriteLine(_layer.ToString());*/ - int i = 0; for (int row = 0; row < tilemap.Height; row++) { @@ -97,20 +98,21 @@ public void Execute() { TiledTileset _tileset = tilesets[0]; int j = 1; - while (tilenum > _tileset.TileCount) + int _num = tilenum; + while (_num > _tileset.TileCount) { - tilenum -= _tileset.TileCount; + _num -= _tileset.TileCount; _tileset = tilesets[j]; j++; } if (overrides.ContainsKey(tilenum)) { - overrides[tilenum].Invoke(new Vector(_x, _y), _tileset.TileWidth, _tileset.TileHeight, TiledMap.GetTileImage(tilenum, _tileset)); + overrides[tilenum].Invoke(new Vector(_x, _y), _tileset.TileWidth, _tileset.TileHeight, GetTileImage(tilenum, _tileset)); } else { - PhysicsObject t = TiledMap.CreateTile(new Vector(_x, _y), _tileset.TileWidth, _tileset.TileHeight, TiledMap.GetTileImage(tilenum, _tileset), (JArray)props); + PhysicsObject t = CreateTile(new Vector(_x, _y), _tileset.TileWidth, _tileset.TileHeight, GetTileImage(tilenum, _tileset), (JArray)props); Game.Instance.Add(t, (int)_layer); } } @@ -120,11 +122,14 @@ public void Execute() } } - static PhysicsObject CreateTile(Vector pos, double width, double height, Image tileImage, JArray props) + PhysicsObject CreateTile(Vector pos, double width, double height, Image tileImage, JArray props) { PhysicsObject tile = PhysicsObject.CreateStaticObject(width, height); tile.Position = pos; tile.Color = Color.Transparent; + tile.Image = tileImage; + tile.Shape = Shape.Rectangle; + tileImage.Scaling = ImageScaling.Nearest; // layer properties if (props != null) @@ -151,38 +156,71 @@ static PhysicsObject CreateTile(Vector pos, double width, double height, Image t } } - tile.Image = tileImage; - tile.Shape = Shape.Rectangle; // Shape.FromImage(tileImg); - tileImage.Scaling = ImageScaling.Nearest; - return tile; } - static Image GetTileImage(int tilenum, TiledTileset tileset) + /// + /// Gets a tile image from a tileset + /// + /// + /// + /// Image of the specified tile + public Image GetTileImage(int tilenum, TiledTileset tileset) { if (tilenum <= 0) { return null; } - Image tiles = Game.LoadImage(tileset.Image); - tilenum--; + if (tileImages.TryGetValue(tilenum, out Image img)) + { + return img; + } + else + { + Image tiles = Game.LoadImage(tileset.Image); + tilenum--; - int col = tilenum % tileset.Columns + 1; - int row = tilenum / tileset.Columns + 1; + int col = tilenum % tileset.Columns + 1; + int row = tilenum / tileset.Columns + 1; - int left = (col - 1) * (tileset.TileWidth + tileset.Spacing); - int top = (row - 1) * (tileset.TileHeight + tileset.Spacing); - int right = left + tileset.TileWidth; - int bottom = top + tileset.TileHeight; + int left = (col - 1) * (tileset.TileWidth + tileset.Spacing); + int top = (row - 1) * (tileset.TileHeight + tileset.Spacing); + int right = left + tileset.TileWidth; + int bottom = top + tileset.TileHeight; - Image t = tiles.Area(left, top, right, bottom); + Image t = tiles.Area(left, top, right, bottom); + tileImages[tilenum + 1] = t; - return t; + return t; + } } /// - /// Tileset data structure. Contains information how the tileset image should be split into individual tiles. + /// Reads text from a file. + /// + /// File path + /// File contents + public string LoadText(string file) + { + string data = String.Empty; + string path = Game.Device.IsPhone ? file : Game.Device.ContentPath + "\\" + file; // Tested with Windows 10 and Android 12 + + using (StreamReader input = new StreamReader(Game.Device.StreamContent(path))) + { + string line; + while ((line = input.ReadLine()) != null) + { + data += line; + } + } + return data; + } + +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + /// + /// Tileset data structure. + /// Contains information how the tileset image should be split into individual tiles. /// public struct TiledTileset { @@ -200,18 +238,20 @@ public struct TiledTileset public string Type; public string Version; } - static TiledTileset TilesetLoader(string file) + TiledTileset TilesetLoader(string file) { - string json = File.ReadAllText(String.Format("Content\\{0}", file)); + string json = LoadText(file); TiledTileset set = JsonConvert.DeserializeObject(json); return set; } /// - /// Tilemap data structure. Contains the actual map data. + /// Tilemap data structure. + /// Contains the actual map data. /// public struct TiledTileMap { + public string BackgroundColor; public int CompressionLevel; public int Height; public bool Infinite; @@ -227,13 +267,30 @@ public struct TiledTileMap public string Type; public string Version; public int Width; + } - static TiledTileMap TileMapLoader(string file) + TiledTileMap TileMapLoader(string file) { - string json = File.ReadAllText(String.Format("Content\\{0}", file)); + string json = LoadText(file); TiledTileMap map = JsonConvert.DeserializeObject(json); return map; } + /* + // TODO + public struct TileMapLayer + { + public List Data; + public int Height; + public int ID; + public string Name; + public double Opacity; + public string Type; + public bool Visible; + public int Width; + public double X; + public double Y; + }*/ +#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member } } \ No newline at end of file From 2cd48b5386e973341164eedb0f96aec5aed5e7a7 Mon Sep 17 00:00:00 2001 From: xNPx3 Date: Sun, 29 Oct 2023 19:48:42 +0200 Subject: [PATCH 06/14] local --- Jypeli/Levels/TiledMap.cs | 44 +++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/Jypeli/Levels/TiledMap.cs b/Jypeli/Levels/TiledMap.cs index a601e08b..8f0f96ed 100644 --- a/Jypeli/Levels/TiledMap.cs +++ b/Jypeli/Levels/TiledMap.cs @@ -16,9 +16,9 @@ public class TiledMap { #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - delegate void TileMethod(Vector position, double width, double height, Image tileImage); + public delegate void TileMethod(Vector position, double width, double height, Image tileImage); protected Dictionary overrides = new Dictionary(); - public Dictionary tileImages = new Dictionary(); + private Dictionary> tileImages = new Dictionary>(); public List tilesets; public TiledTileMap tilemap; @@ -172,28 +172,40 @@ public Image GetTileImage(int tilenum, TiledTileset tileset) return null; } - if (tileImages.TryGetValue(tilenum, out Image img)) + if (tileImages.TryGetValue(tileset, out Dictionary ts)) { - return img; + if (ts.TryGetValue(tilenum, out Image img)) + { + return img; + } + else + { + return LoadTileImage(tilenum, tileset); + } } else { - Image tiles = Game.LoadImage(tileset.Image); - tilenum--; + tileImages[tileset] = new Dictionary(); + return LoadTileImage(tilenum, tileset); + } + } + private Image LoadTileImage(int tilenum, TiledTileset tileset) + { + Image tiles = Game.LoadImage(tileset.Image); + tilenum--; - int col = tilenum % tileset.Columns + 1; - int row = tilenum / tileset.Columns + 1; + int col = tilenum % tileset.Columns + 1; + int row = tilenum / tileset.Columns + 1; - int left = (col - 1) * (tileset.TileWidth + tileset.Spacing); - int top = (row - 1) * (tileset.TileHeight + tileset.Spacing); - int right = left + tileset.TileWidth; - int bottom = top + tileset.TileHeight; + int left = (col - 1) * (tileset.TileWidth + tileset.Spacing); + int top = (row - 1) * (tileset.TileHeight + tileset.Spacing); + int right = left + tileset.TileWidth; + int bottom = top + tileset.TileHeight; - Image t = tiles.Area(left, top, right, bottom); - tileImages[tilenum + 1] = t; + Image t = tiles.Area(left, top, right, bottom); + tileImages[tileset][tilenum + 1] = t; - return t; - } + return t; } /// From 8e52aeda89c55acfc504426a5fc2d9a6ea859efa Mon Sep 17 00:00:00 2001 From: xNPx3 Date: Sun, 29 Oct 2023 22:19:54 +0200 Subject: [PATCH 07/14] cleaning --- Examples/Snowman/Snowman.cs | 1 + Jypeli/Levels/TiledMap.cs | 9 --------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/Examples/Snowman/Snowman.cs b/Examples/Snowman/Snowman.cs index ae82b61b..7bbf1f44 100644 --- a/Examples/Snowman/Snowman.cs +++ b/Examples/Snowman/Snowman.cs @@ -93,6 +93,7 @@ private void CreatePlayer(Vector position, double width, double height, Image ti Keyboard.Listen(Key.Left, ButtonState.Down, () => player.Walk(-moveSpeed), null); Keyboard.Listen(Key.Right, ButtonState.Down, () => player.Walk(moveSpeed), null); Keyboard.Listen(Key.Space, ButtonState.Pressed, () => player.Jump(450), null); + Keyboard.Listen(Key.Up, ButtonState.Pressed, () => player.Jump(450), null); } private void CollectDiamond(IPhysicsObject collidingObject, IPhysicsObject otherObject) diff --git a/Jypeli/Levels/TiledMap.cs b/Jypeli/Levels/TiledMap.cs index 8f0f96ed..42f80277 100644 --- a/Jypeli/Levels/TiledMap.cs +++ b/Jypeli/Levels/TiledMap.cs @@ -72,15 +72,6 @@ public void Execute() int? _layer = null; - /*if (props != null) // if layer is manually set in props - { - JToken _token = ((JArray)props).SelectToken("$[?(@.name == 'Layer')]"); // find token - _layer = (int?)_token["value"]; // get value - ((JArray)props).Remove(_token); // remove original token to avoid exceptions later - } - - _layer = _layer != null ? (int)_layer : -1;*/ - _layer = l - 2; // Bottom layer in Tiled corresponds to in-game layer -2 // TODO: write check for more than 7 total layers From c8747e1eff4aff17dee8be3b7e7d2e49d2c414c8 Mon Sep 17 00:00:00 2001 From: xNPx3 Date: Wed, 8 Nov 2023 20:06:39 +0200 Subject: [PATCH 08/14] Error message for image failing to load --- Examples/Snowman/Content/map.tmj | 2 +- Jypeli/Levels/TiledMap.cs | 41 ++++++++++++++++++++++---------- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/Examples/Snowman/Content/map.tmj b/Examples/Snowman/Content/map.tmj index d6a56abd..1be8b740 100644 --- a/Examples/Snowman/Content/map.tmj +++ b/Examples/Snowman/Content/map.tmj @@ -276,7 +276,7 @@ "x":0, "y":0 }], - "nextlayerid":6, + "nextlayerid":8, "nextobjectid":1, "orientation":"orthogonal", "renderorder":"right-down", diff --git a/Jypeli/Levels/TiledMap.cs b/Jypeli/Levels/TiledMap.cs index 42f80277..e4f8e84b 100644 --- a/Jypeli/Levels/TiledMap.cs +++ b/Jypeli/Levels/TiledMap.cs @@ -55,6 +55,7 @@ public void SetOverride(int tilenum, TileMethod tileMethod) /// /// Creates the level. + /// Objects are placed from in-game layer -2 upwards. /// public void Execute() { @@ -74,7 +75,11 @@ public void Execute() _layer = l - 2; // Bottom layer in Tiled corresponds to in-game layer -2 - // TODO: write check for more than 7 total layers + // TODO: better logic for layers + if (_layer > 3) + { + _layer = 3; + } int i = 0; for (int row = 0; row < tilemap.Height; row++) @@ -163,6 +168,7 @@ public Image GetTileImage(int tilenum, TiledTileset tileset) return null; } + // check if the same image was used before this tile if (tileImages.TryGetValue(tileset, out Dictionary ts)) { if (ts.TryGetValue(tilenum, out Image img)) @@ -182,21 +188,29 @@ public Image GetTileImage(int tilenum, TiledTileset tileset) } private Image LoadTileImage(int tilenum, TiledTileset tileset) { - Image tiles = Game.LoadImage(tileset.Image); - tilenum--; + try + { + Image tiles = Game.LoadImage(tileset.Image); + + tilenum--; - int col = tilenum % tileset.Columns + 1; - int row = tilenum / tileset.Columns + 1; + int col = tilenum % tileset.Columns + 1; + int row = tilenum / tileset.Columns + 1; - int left = (col - 1) * (tileset.TileWidth + tileset.Spacing); - int top = (row - 1) * (tileset.TileHeight + tileset.Spacing); - int right = left + tileset.TileWidth; - int bottom = top + tileset.TileHeight; + int left = (col - 1) * (tileset.TileWidth + tileset.Spacing); + int top = (row - 1) * (tileset.TileHeight + tileset.Spacing); + int right = left + tileset.TileWidth; + int bottom = top + tileset.TileHeight; - Image t = tiles.Area(left, top, right, bottom); - tileImages[tileset][tilenum + 1] = t; + Image t = tiles.Area(left, top, right, bottom); + tileImages[tileset][tilenum + 1] = t; - return t; + return t; + } + catch (System.IO.FileNotFoundException nfe) + { + throw new System.IO.FileNotFoundException("Tileset image was not found. Check the file path and make sure everything is set up correctly in Tiled.\nCommon cause of this error is creating the tileset first and then moving it into a new directory.", nfe); + } } /// @@ -206,8 +220,9 @@ private Image LoadTileImage(int tilenum, TiledTileset tileset) /// File contents public string LoadText(string file) { + // Tested with Windows 10 and Android 12 string data = String.Empty; - string path = Game.Device.IsPhone ? file : Game.Device.ContentPath + "\\" + file; // Tested with Windows 10 and Android 12 + string path = Game.Device.IsPhone ? file : Game.Device.ContentPath + "\\" + file; using (StreamReader input = new StreamReader(Game.Device.StreamContent(path))) { From d8598109e00805fd3a086b4e098731bc7bc02038 Mon Sep 17 00:00:00 2001 From: xNPx3 Date: Sun, 12 Nov 2023 16:12:33 +0200 Subject: [PATCH 09/14] Removed local test project; moved LoadText method under Jypeli.Game --- Examples/Snowman/Content/map.tmj | 294 ------------------- Examples/Snowman/Content/tiles.png | Bin 6185 -> 0 bytes Examples/Snowman/Content/tileset.tsj | 14 - Examples/Snowman/Content/tileset_license.txt | 22 -- Examples/Snowman/Ohjelma.cs | 25 -- Examples/Snowman/Snowman.cs | 130 -------- Examples/Snowman/Snowman.csproj | 34 --- Jypeli/Game/Content.cs | 18 ++ Jypeli/Levels/TiledMap.cs | 28 +- 9 files changed, 21 insertions(+), 544 deletions(-) delete mode 100644 Examples/Snowman/Content/map.tmj delete mode 100644 Examples/Snowman/Content/tiles.png delete mode 100644 Examples/Snowman/Content/tileset.tsj delete mode 100644 Examples/Snowman/Content/tileset_license.txt delete mode 100644 Examples/Snowman/Ohjelma.cs delete mode 100644 Examples/Snowman/Snowman.cs delete mode 100644 Examples/Snowman/Snowman.csproj diff --git a/Examples/Snowman/Content/map.tmj b/Examples/Snowman/Content/map.tmj deleted file mode 100644 index 1be8b740..00000000 --- a/Examples/Snowman/Content/map.tmj +++ /dev/null @@ -1,294 +0,0 @@ -{ "compressionlevel":-1, - "height":40, - "infinite":false, - "layers":[ - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 155, 155, 155, 155, 155, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 103, 103, 103, 103, 103, 103, 104, 0, 0, 0, 0, 102, 103, 103, 103, 103, 103, 103, 104, 0, 0, 0, 0, 0, 0, 0, - 0, 49, 50, 50, 50, 51, 0, 0, 0, 0, 0, 0, 0, 142, 143, 6, 123, 123, 123, 123, 124, 69, 69, 69, 102, 26, 123, 123, 5, 143, 143, 143, 144, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 143, 143, 143, 6, 25, 103, 103, 103, 26, 123, 5, 143, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 143, 143, 143, 143, 143, 143, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 143, 6, 123, 123, 123, 123, 5, 143, 143, 144, 0, 0, 0, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 143, 143, 143, 143, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 63, 63, 63, 63, 63, 63, 64, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 63, 63, 63, 63, 63, 26, 123, 123, 123, 123, 123, 124, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 63, 63, 63, 26, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 124, 0, 0, 0, 109, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 62, 63, 63, 63, 63, 0, 0, 0, 63, 63, 26, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 124, 0, 0, 42, 43, 44, 0, 0, - 63, 63, 63, 63, 63, 63, 63, 63, 63, 26, 123, 123, 123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 25, 63, 63, 63, 26, 123, 123, 25, 23, 23, 23, 26, 123, 123, 25, 103, 103, 103, 26, 123, 124, 69, 69, 69, 69, 69, 69, 69, - 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 124, 103, 103, 103, 103, 103, 103, 103, - 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 124, 123, 123, 123, 123, 123, 123, 123], - "height":40, - "id":1, - "name":"Blocks", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":40, - "x":0, - "y":0 - }, - { - "data":[0, 70, 0, 0, 0, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 90, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 90, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 90, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 90, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0, - 0, 90, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 132, 0, 146, 0, - 0, 90, 0, 0, 0, 90, 0, 0, 0, 0, 0, 52, 0, 0, 86, 0, 145, 0, 0, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 90, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 125, 126, 72, 0, 129, 85, 0, 0, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 0, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 68, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 125, 128, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 129, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 128, 0, 0, 0, 0, 86, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 0, 0, 0, 0, 54, 54, 54, 0, 0, 0, 0, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74, 74, 0, 0, 0, 0, 74, 74, 74, 0, 0, 0, 0, 74, 74, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 0, 74, 74, 74, 0, 0, 0, 0, 74, 74, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":40, - "id":3, - "name":"Deco", - "opacity":1, - "properties":[ - { - "name":"CollisionIgnoreGroup", - "type":"int", - "value":1 - }], - "type":"tilelayer", - "visible":true, - "width":40, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 147, 147, 147, 147, 147, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 63, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":40, - "id":2, - "name":"One-way", - "opacity":1, - "properties":[ - { - "name":"MakeOneWay", - "type":"bool", - "value":true - }], - "type":"tilelayer", - "visible":true, - "width":40, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 179, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":40, - "id":4, - "locked":true, - "name":"Player", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":40, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 19, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 39, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 98, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, 122, 123, 123, 124, 0, 0, 0, 122, 123, 123, 124, 0, 0, 0, 122, 123, 124, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124, 0, 68, 0, 122, 123, 123, 124, 0, 68, 0, 122, 123, 123, 124, 0, 68, 0, 122, 123, 124, 68, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, 122, 123, 123, 124, 0, 0, 0, 122, 123, 123, 124, 0, 0, 0, 122, 123, 124, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":40, - "id":5, - "name":"Deco", - "opacity":1, - "properties":[ - { - "name":"CollisionIgnoreGroup", - "type":"int", - "value":1 - }], - "type":"tilelayer", - "visible":true, - "width":40, - "x":0, - "y":0 - }], - "nextlayerid":8, - "nextobjectid":1, - "orientation":"orthogonal", - "renderorder":"right-down", - "tiledversion":"1.10.1", - "tileheight":18, - "tilesets":[ - { - "firstgid":1, - "source":"tileset.tsj" - }], - "tilewidth":18, - "type":"map", - "version":"1.10", - "width":40 -} \ No newline at end of file diff --git a/Examples/Snowman/Content/tiles.png b/Examples/Snowman/Content/tiles.png deleted file mode 100644 index 40fce07d07176ced41c455418454db6815f5675e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6185 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 - /// The main class. - /// - public static class Program - { - /// - /// The main entry point for the application. - /// - [STAThread] - static void Main() - { - using var game = new Snowman(); - game.Run(); - } - } -} diff --git a/Examples/Snowman/Snowman.cs b/Examples/Snowman/Snowman.cs deleted file mode 100644 index 7bbf1f44..00000000 --- a/Examples/Snowman/Snowman.cs +++ /dev/null @@ -1,130 +0,0 @@ -using System; -using Jypeli; - -namespace Snowman -{ - public class Snowman : PhysicsGame - { - PlatformCharacter player; - TiledMap map; - double moveSpeed = 100; - - IntMeter counter; - - public override void Begin() - { - Level.BackgroundColor = Color.LightBlue; - Gravity = new Vector(0, -1500); - - Keyboard.Listen(Key.Escape, ButtonState.Pressed, ConfirmExit, null); - - map = new TiledMap("map.tmj", "tileset.tsj"); - map.SetOverride(67, CreateDiamond); - map.SetOverride(68, CreateSpikes); - map.SetOverride(108, CreateJumpBlock); - map.SetOverride(145, CreateSnowman); - map.SetOverride(178, CreatePlayer); - map.Execute(); - - - counter = new IntMeter(0); - } - - private void CreateSnowman(Vector position, double width, double height, Image tileImage) - { - PhysicsObject snowman = PhysicsObject.CreateStaticObject(width, height); - snowman.Position = position; - tileImage.Scaling = ImageScaling.Nearest; - snowman.Image = tileImage; - snowman.Tag = "snowman"; - Add(snowman, -1); - } - - private void CreateDiamond(Vector position, double width, double height, Image tileImage) - { - PhysicsObject diamond = PhysicsObject.CreateStaticObject(width, height); - diamond.Position = position; - tileImage.Scaling = ImageScaling.Nearest; - diamond.Image = tileImage; - diamond.Tag = "diamond"; - diamond.Shape = Shape.Circle; - diamond.Oscillate(Vector.UnitY, 3, 0.5); - Add(diamond, 2); - } - - private void CreateSpikes(Vector position, double width, double height, Image tileImage) - { - PhysicsObject spike = PhysicsObject.CreateStaticObject(width, height); - spike.Position = position; - tileImage.Scaling = ImageScaling.Nearest; - spike.Image = tileImage; - spike.Tag = "spike"; - spike.Shape = Shape.FromImage(tileImage); - Add(spike, -2); - } - - private void CreatePlayer(Vector position, double width, double height, Image tileImage) - { - player = new PlatformCharacter(16, 16); - player.Position = position; - player.CollisionIgnoreGroup = 1; - - Image p = map.GetTileImage(146, map.tilesets[0]); - p = Image.Mirror(p); - p.Scaling = ImageScaling.Nearest; - player.Image = p; - - Add(player, 1); - - Camera.Follow(player); - Camera.StayInLevel = true; - Camera.ZoomFactor = 4; - - AddCollisionHandler(player, "jump block", Boost); - AddCollisionHandler(player, "diamond", CollectDiamond); - AddCollisionHandler(player, "snowman", (p, o) => - { - Keyboard.Clear(); - Keyboard.Listen(Key.Escape, ButtonState.Pressed, Exit, null); - MessageDisplay.Add(String.Format("You win! You collected {0}{1} diamonds. Press ESC to exit.", counter.Value == 6 ? "all " : "", counter.Value)); - }); - AddCollisionHandler(player, "spike", (p, o) => player.Position = position); - - Keyboard.Listen(Key.Left, ButtonState.Down, () => player.Walk(-moveSpeed), null); - Keyboard.Listen(Key.Right, ButtonState.Down, () => player.Walk(moveSpeed), null); - Keyboard.Listen(Key.Space, ButtonState.Pressed, () => player.Jump(450), null); - Keyboard.Listen(Key.Up, ButtonState.Pressed, () => player.Jump(450), null); - } - - private void CollectDiamond(IPhysicsObject collidingObject, IPhysicsObject otherObject) - { - otherObject.IgnoresCollisionResponse = true; - otherObject.Destroy(); - counter.Value += 1; - } - - private void Boost(IPhysicsObject collidingObject, IPhysicsObject otherObject) - { - if (player.Y > otherObject.Y) - { - Image i1 = map.GetTileImage(108, map.tilesets[0]); - Image i2 = map.GetTileImage(109, map.tilesets[0]); - i1.Scaling = ImageScaling.Nearest; - i2.Scaling = ImageScaling.Nearest; - otherObject.Image = i1; - player.ForceJump(1000); - Timer.SingleShot(1, () => otherObject.Image = i2); - } - } - - private void CreateJumpBlock(Vector position, double width, double height, Image tileImage) - { - PhysicsObject jumpBlock = PhysicsObject.CreateStaticObject(width, height); - jumpBlock.Position = position; - tileImage.Scaling = ImageScaling.Nearest; - jumpBlock.Image = tileImage; - jumpBlock.Tag = "jump block"; - Add(jumpBlock, -2); - } - } -} \ No newline at end of file diff --git a/Examples/Snowman/Snowman.csproj b/Examples/Snowman/Snowman.csproj deleted file mode 100644 index 694ea9f3..00000000 --- a/Examples/Snowman/Snowman.csproj +++ /dev/null @@ -1,34 +0,0 @@ - - - - WinExe - net6.0 - false - false - - - - - - - - - - - Always - - - Always - - - Always - - - - - - - - - - diff --git a/Jypeli/Game/Content.cs b/Jypeli/Game/Content.cs index 0a760f60..86610077 100644 --- a/Jypeli/Game/Content.cs +++ b/Jypeli/Game/Content.cs @@ -183,6 +183,24 @@ public static Font LoadFont(string name) return new Font(name); } + /// + /// Lukee merkkijonon tiedostosta. + /// + /// Tiedoston nimi + /// Tiedoston sisältö merkkijonona + public static string LoadText(string file) + { + string data = String.Empty; + string path = Device.IsPhone ? file : Device.ContentPath + "\\" + file; + + using (StreamReader input = new StreamReader(Device.StreamContent(path))) + { + data = input.ReadToEnd(); + } + return data; + } + + /// /// Etsii millä päätteellä annettu tiedosto löytyy /// diff --git a/Jypeli/Levels/TiledMap.cs b/Jypeli/Levels/TiledMap.cs index e4f8e84b..b83a90e5 100644 --- a/Jypeli/Levels/TiledMap.cs +++ b/Jypeli/Levels/TiledMap.cs @@ -213,28 +213,6 @@ private Image LoadTileImage(int tilenum, TiledTileset tileset) } } - /// - /// Reads text from a file. - /// - /// File path - /// File contents - public string LoadText(string file) - { - // Tested with Windows 10 and Android 12 - string data = String.Empty; - string path = Game.Device.IsPhone ? file : Game.Device.ContentPath + "\\" + file; - - using (StreamReader input = new StreamReader(Game.Device.StreamContent(path))) - { - string line; - while ((line = input.ReadLine()) != null) - { - data += line; - } - } - return data; - } - #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member /// /// Tileset data structure. @@ -258,7 +236,7 @@ public struct TiledTileset } TiledTileset TilesetLoader(string file) { - string json = LoadText(file); + string json = Game.LoadText(file); TiledTileset set = JsonConvert.DeserializeObject(json); return set; } @@ -290,12 +268,12 @@ public struct TiledTileMap TiledTileMap TileMapLoader(string file) { - string json = LoadText(file); + string json = Game.LoadText(file); TiledTileMap map = JsonConvert.DeserializeObject(json); return map; } /* - // TODO + // TODO: layer struct public struct TileMapLayer { public List Data; From 600a05d49cf94571f5340dc8208b797255124ec9 Mon Sep 17 00:00:00 2001 From: xNPx3 Date: Sun, 12 Nov 2023 17:31:44 +0200 Subject: [PATCH 10/14] removed local projects from solution --- Jypeli.NET.sln | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/Jypeli.NET.sln b/Jypeli.NET.sln index 3744c6ec..524d1295 100644 --- a/Jypeli.NET.sln +++ b/Jypeli.NET.sln @@ -27,8 +27,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Marswagen", "Examples\Marsw EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Pong", "Examples\Pong\Pong.csproj", "{0EE2DBBF-C8A1-469B-9177-B211B575420E}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Snowman", "Examples\Snowman\Snowman.csproj", "{29C4DB79-51C6-4CF5-9E85-71225C5CEFFD}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -105,14 +103,6 @@ Global {0EE2DBBF-C8A1-469B-9177-B211B575420E}.Release|Any CPU.Build.0 = Release|Any CPU {0EE2DBBF-C8A1-469B-9177-B211B575420E}.Release|x86.ActiveCfg = Release|Any CPU {0EE2DBBF-C8A1-469B-9177-B211B575420E}.Release|x86.Build.0 = Release|Any CPU - {29C4DB79-51C6-4CF5-9E85-71225C5CEFFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {29C4DB79-51C6-4CF5-9E85-71225C5CEFFD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {29C4DB79-51C6-4CF5-9E85-71225C5CEFFD}.Debug|x86.ActiveCfg = Debug|Any CPU - {29C4DB79-51C6-4CF5-9E85-71225C5CEFFD}.Debug|x86.Build.0 = Debug|Any CPU - {29C4DB79-51C6-4CF5-9E85-71225C5CEFFD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {29C4DB79-51C6-4CF5-9E85-71225C5CEFFD}.Release|Any CPU.Build.0 = Release|Any CPU - {29C4DB79-51C6-4CF5-9E85-71225C5CEFFD}.Release|x86.ActiveCfg = Release|Any CPU - {29C4DB79-51C6-4CF5-9E85-71225C5CEFFD}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -124,7 +114,6 @@ Global {9A94D71A-702B-4B8A-B67E-266F84775B9C} = {B210F0DC-A8FE-4E35-9EC0-F65E8CC134E8} {834B1B18-421B-4AE8-9F26-A0D5A2376039} = {B210F0DC-A8FE-4E35-9EC0-F65E8CC134E8} {0EE2DBBF-C8A1-469B-9177-B211B575420E} = {B210F0DC-A8FE-4E35-9EC0-F65E8CC134E8} - {29C4DB79-51C6-4CF5-9E85-71225C5CEFFD} = {B210F0DC-A8FE-4E35-9EC0-F65E8CC134E8} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {2E893DBE-1BA1-4FEC-B40D-37995FB065B9} From 2bc5b3f93468447a35e941754dcdfb37140a8e76 Mon Sep 17 00:00:00 2001 From: xNPx3 Date: Sun, 12 Nov 2023 20:29:45 +0200 Subject: [PATCH 11/14] cleaning up --- Jypeli/Levels/TiledMap.cs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Jypeli/Levels/TiledMap.cs b/Jypeli/Levels/TiledMap.cs index b83a90e5..9209c4e1 100644 --- a/Jypeli/Levels/TiledMap.cs +++ b/Jypeli/Levels/TiledMap.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.IO; using System.Reflection; +using Jypeli.Devices; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -20,8 +21,8 @@ public class TiledMap protected Dictionary overrides = new Dictionary(); private Dictionary> tileImages = new Dictionary>(); - public List tilesets; - public TiledTileMap tilemap; + public readonly List tilesets; + public readonly TiledTileMap tilemap; #pragma warning restore CS1591 // Missing XML comment for publicly visible type or member @@ -207,13 +208,16 @@ private Image LoadTileImage(int tilenum, TiledTileset tileset) return t; } - catch (System.IO.FileNotFoundException nfe) + catch { - throw new System.IO.FileNotFoundException("Tileset image was not found. Check the file path and make sure everything is set up correctly in Tiled.\nCommon cause of this error is creating the tileset first and then moving it into a new directory.", nfe); + // TODO: better error message? + throw new FileNotFoundException($"Tileset source file {tileset.Image} was not found.\nMake sure everything is set up correctly."); } } #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + // TODO: make immutable + /// /// Tileset data structure. /// Contains information how the tileset image should be split into individual tiles. @@ -263,7 +267,6 @@ public struct TiledTileMap public string Type; public string Version; public int Width; - } TiledTileMap TileMapLoader(string file) @@ -272,6 +275,7 @@ TiledTileMap TileMapLoader(string file) TiledTileMap map = JsonConvert.DeserializeObject(json); return map; } + /* // TODO: layer struct public struct TileMapLayer @@ -287,6 +291,7 @@ public struct TileMapLayer public double X; public double Y; }*/ + #pragma warning restore CS1591 // Missing XML comment for publicly visible type or member } } \ No newline at end of file From 8a99d510327b53c3f9aa185513af967b59ee8ee5 Mon Sep 17 00:00:00 2001 From: xNPx3 Date: Sun, 12 Nov 2023 21:01:24 +0200 Subject: [PATCH 12/14] typo --- Jypeli/Game/Time.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jypeli/Game/Time.cs b/Jypeli/Game/Time.cs index a4171c49..24b7f7c2 100644 --- a/Jypeli/Game/Time.cs +++ b/Jypeli/Game/Time.cs @@ -19,7 +19,7 @@ public partial class Game /// /// Ajetaanko peliä kiinteällä aika-askeleella. /// Eli pelin aika "hidastuu" jos tietokoneen tehot eivät riitä reaaliaikaiseen päivitykseen. - /// Tämä pakottaa pelin logiikan toimimaan sillä nopeudella kuin on asetettu. + /// Tämä pakottaa pelin logiikan toimimaan sillä nopeudella kuin on asetettu. /// public static bool FixedTimeStep { get; set; } From b489c9184baeab87f4b4b1aa2c67c67df4f4c7b0 Mon Sep 17 00:00:00 2001 From: xNPx3 Date: Sun, 19 Nov 2023 15:07:27 +0200 Subject: [PATCH 13/14] Make UpdatesPerSecod obsolete --- Jypeli/Game/Time.cs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Jypeli/Game/Time.cs b/Jypeli/Game/Time.cs index 24b7f7c2..cbc5f7a2 100644 --- a/Jypeli/Game/Time.cs +++ b/Jypeli/Game/Time.cs @@ -19,7 +19,7 @@ public partial class Game /// /// Ajetaanko peliä kiinteällä aika-askeleella. /// Eli pelin aika "hidastuu" jos tietokoneen tehot eivät riitä reaaliaikaiseen päivitykseen. - /// Tämä pakottaa pelin logiikan toimimaan sillä nopeudella kuin on asetettu. + /// Tämä pakottaa pelin logiikan toimimaan sillä nopeudella kuin on asetettu. /// public static bool FixedTimeStep { get; set; } @@ -29,7 +29,8 @@ public partial class Game /// Tällä hetkellä myös pelin FPS-tavoite asettuu samaan arvoon. /// Tämän muuttaminen "vääräksi" arvoksi saattaa aiheuttaa erikoisia seurauksia jos on päällä. /// - public static double UpdatesPerSecond + [Obsolete("-> UpdatesPerSecond")] + public static double UpdatesPerSecod { get => Instance.Window.UpdatesPerSecond; set @@ -39,6 +40,21 @@ public static double UpdatesPerSecond } } + /// + /// Kuinka monta pelipäivitystä ajetaan sekunnissa. + /// Vakiona 60. + /// Tällä hetkellä myös pelin FPS-tavoite asettuu samaan arvoon. + /// Tämän muuttaminen "vääräksi" arvoksi saattaa aiheuttaa erikoisia seurauksia jos on päällä. + /// + public static double UpdatesPerSecond + { + get => UpdatesPerSecod; + set + { + UpdatesPerSecod = value; + } + } + /// /// Onko peli pysähdyksissä. /// From 61c76baf345a4cfce818e22f22584cfe632c645c Mon Sep 17 00:00:00 2001 From: xNPx3 Date: Fri, 5 Jan 2024 02:29:55 +0200 Subject: [PATCH 14/14] Removed dependency 'Newtonsoft.Json', optimized tile image loading --- Jypeli/Jypeli.csproj | 1 - Jypeli/Levels/TiledMap.cs | 179 ++++++++++++++++++++------------------ 2 files changed, 93 insertions(+), 87 deletions(-) diff --git a/Jypeli/Jypeli.csproj b/Jypeli/Jypeli.csproj index 1aa305b4..4478ed1c 100644 --- a/Jypeli/Jypeli.csproj +++ b/Jypeli/Jypeli.csproj @@ -133,7 +133,6 @@ - diff --git a/Jypeli/Levels/TiledMap.cs b/Jypeli/Levels/TiledMap.cs index 9209c4e1..74842c70 100644 --- a/Jypeli/Levels/TiledMap.cs +++ b/Jypeli/Levels/TiledMap.cs @@ -1,11 +1,8 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.IO; using System.Reflection; -using Jypeli.Devices; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using System.Text.Json; namespace Jypeli { @@ -20,12 +17,19 @@ public class TiledMap public delegate void TileMethod(Vector position, double width, double height, Image tileImage); protected Dictionary overrides = new Dictionary(); private Dictionary> tileImages = new Dictionary>(); + private Dictionary tilesetImages = new Dictionary(); public readonly List tilesets; public readonly TiledTileMap tilemap; #pragma warning restore CS1591 // Missing XML comment for publicly visible type or member + private JsonSerializerOptions serOptions = new JsonSerializerOptions + { + PropertyNameCaseInsensitive = true, + NumberHandling = System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString + }; + /// /// Loads the map data for creating the level. @@ -40,7 +44,9 @@ public TiledMap(string tilemapFile, params string[] tilesetFiles) tilemap = TileMapLoader(tilemapFile); foreach (string f in tilesetFiles) { - tilesets.Add(TilesetLoader(f)); + TiledTileset t = TilesetLoader(f); + tilesets.Add(t); + tilesetImages.Add(t, Game.LoadImage(t.Image)); } } @@ -64,17 +70,13 @@ public void Execute() double mapHeight = tilemap.Height * tilemap.TileHeight; Game.Instance.Level.Size = new Vector(mapWidth, mapHeight); - //Game.Instance.Level.CreateBorders(); - for (int l = 0; l < tilemap.Layers.Count; l++) { - JArray data = (JArray)tilemap.Layers[l]["data"]; - object props = tilemap.Layers[l].TryGetValue("properties", out props) ? props : null; + List data = tilemap.Layers[l].Data; + List props = tilemap.Layers[l].Properties; - int? _layer = null; - - _layer = l - 2; // Bottom layer in Tiled corresponds to in-game layer -2 + int? _layer = l - 2; // Bottom layer in Tiled corresponds to in-game layer -2 // TODO: better logic for layers if (_layer > 3) @@ -93,6 +95,7 @@ public void Execute() int tilenum = (int)data[i]; if (tilenum != 0) { + // TODO: multiple tilesets TiledTileset _tileset = tilesets[0]; int j = 1; int _num = tilenum; @@ -109,7 +112,7 @@ public void Execute() } else { - PhysicsObject t = CreateTile(new Vector(_x, _y), _tileset.TileWidth, _tileset.TileHeight, GetTileImage(tilenum, _tileset), (JArray)props); + PhysicsObject t = CreateTile(new Vector(_x, _y), _tileset.TileWidth, _tileset.TileHeight, GetTileImage(tilenum, _tileset), props); Game.Instance.Add(t, (int)_layer); } } @@ -119,7 +122,7 @@ public void Execute() } } - PhysicsObject CreateTile(Vector pos, double width, double height, Image tileImage, JArray props) + PhysicsObject CreateTile(Vector pos, double width, double height, Image tileImage, List props = null) { PhysicsObject tile = PhysicsObject.CreateStaticObject(width, height); tile.Position = pos; @@ -128,27 +131,28 @@ PhysicsObject CreateTile(Vector pos, double width, double height, Image tileImag tile.Shape = Shape.Rectangle; tileImage.Scaling = ImageScaling.Nearest; - // layer properties + // Layer properties if (props != null) foreach (var prop in props) { - PropertyInfo propertyInfo = tile.GetType().GetProperty(prop["name"].ToString()); + PropertyInfo propertyInfo = tile.GetType().GetProperty(prop.Name); // testing if calling MakeOneWay works when there is a true bool with the same name - if (prop["name"].ToString() == "MakeOneWay" && (bool)prop["value"] && prop["type"].ToString() == "bool") + if (prop.Name == "MakeOneWay") { - tile.MakeOneWay(); + if (bool.Parse(prop.Value.ToString()) && prop.Type.ToString() == "bool") + tile.MakeOneWay(); } if (propertyInfo != null && propertyInfo.CanWrite) { try { - propertyInfo.SetValue(tile, Convert.ChangeType(prop["value"], propertyInfo.PropertyType)); + propertyInfo.SetValue(tile, Convert.ChangeType(prop.Value.GetRawText(), propertyInfo.PropertyType)); } catch (Exception e) { - System.Diagnostics.Debug.WriteLine(e.Message); + Debug.WriteLine(e.Message); } } } @@ -189,33 +193,22 @@ public Image GetTileImage(int tilenum, TiledTileset tileset) } private Image LoadTileImage(int tilenum, TiledTileset tileset) { - try - { - Image tiles = Game.LoadImage(tileset.Image); - - tilenum--; + int col = (tilenum - 1) % tileset.Columns + 1; + int row = (tilenum - 1) / tileset.Columns + 1; - int col = tilenum % tileset.Columns + 1; - int row = tilenum / tileset.Columns + 1; + int left = (col - 1) * (tileset.TileWidth + tileset.Spacing); + int top = (row - 1) * (tileset.TileHeight + tileset.Spacing); + int right = left + tileset.TileWidth; + int bottom = top + tileset.TileHeight; - int left = (col - 1) * (tileset.TileWidth + tileset.Spacing); - int top = (row - 1) * (tileset.TileHeight + tileset.Spacing); - int right = left + tileset.TileWidth; - int bottom = top + tileset.TileHeight; + Image t = tilesetImages[tileset].Area(left, top, right, bottom); + tileImages[tileset][tilenum] = t; - Image t = tiles.Area(left, top, right, bottom); - tileImages[tileset][tilenum + 1] = t; - - return t; - } - catch - { - // TODO: better error message? - throw new FileNotFoundException($"Tileset source file {tileset.Image} was not found.\nMake sure everything is set up correctly."); - } + return t; } #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + // TODO: make immutable /// @@ -224,73 +217,87 @@ private Image LoadTileImage(int tilenum, TiledTileset tileset) /// public struct TiledTileset { - public int Columns; - public string Image; - public int ImageHeight; - public int ImageWidth; - public int Margin; - public string Name; - public int Spacing; - public int TileCount; - public string TiledVersion; - public int TileHeight; - public int TileWidth; - public string Type; - public string Version; + public int Columns { get; set; } + public string Image { get; set; } + public int ImageHeight { get; set; } + public int ImageWidth { get; set; } + public int Margin { get; set; } + public string Name { get; set; } + public int Spacing { get; set; } + public int TileCount { get; set; } + public string TiledVersion { get; set; } + public int TileHeight { get; set; } + public int TileWidth { get; set; } + public string Type { get; set; } + public string Version { get; set; } } TiledTileset TilesetLoader(string file) { string json = Game.LoadText(file); - TiledTileset set = JsonConvert.DeserializeObject(json); + TiledTileset set = JsonSerializer.Deserialize(json, serOptions); + return set; } /// /// Tilemap data structure. - /// Contains the actual map data. + /// Contains information about the map. /// public struct TiledTileMap { - public string BackgroundColor; - public int CompressionLevel; - public int Height; - public bool Infinite; - public List> Layers; - public int NextLayerID; - public int NextObjectID; - public string Orientation; - public string RenderOrder; - public string TiledVersion; - public int TileHeight; - public List> Tilesets; - public int TileWidth; - public string Type; - public string Version; - public int Width; + public string BackgroundColor { get; set; } + public int CompressionLevel { get; set; } + public int Height { get; set; } + public bool Infinite { get; set; } + public List Layers { get; set; } + public int NextLayerID { get; set; } + public int NextObjectID { get; set; } + public string Orientation { get; set; } + public string RenderOrder { get; set; } + public string TiledVersion { get; set; } + public int TileHeight { get; set; } + public List> Tilesets { get; set; } + public int TileWidth { get; set; } + public string Type { get; set; } + public string Version { get; set; } + public int Width { get; set; } } TiledTileMap TileMapLoader(string file) { string json = Game.LoadText(file); - TiledTileMap map = JsonConvert.DeserializeObject(json); + TiledTileMap map = JsonSerializer.Deserialize(json, serOptions); + return map; } - /* - // TODO: layer struct + /// + /// Tile layer data structure. + /// public struct TileMapLayer { - public List Data; - public int Height; - public int ID; - public string Name; - public double Opacity; - public string Type; - public bool Visible; - public int Width; - public double X; - public double Y; - }*/ + public List Data { get; set; } + public int Height { get; set; } + public int ID { get; set; } + public string Name { get; set; } + public double Opacity { get; set; } + public List Properties { get; set; } + public string Type { get; set; } + public bool Visible { get; set; } + public int Width { get; set; } + public double X { get; set; } + public double Y { get; set; } + } + + /// + /// Tile layer property structure. + /// + public struct Property + { + public string Name { get; set; } + public string Type { get; set; } + public JsonElement Value { get; set; } + } #pragma warning restore CS1591 // Missing XML comment for publicly visible type or member }