示例#1
0
 static void ReadTileObjects(XmlNode node, ref TiledMapTilesetTile tile)
 {
     if (node["objectgroup"] != null)
     {
         var layer = LayerParser.ParseObjectLayer(node["objectgroup"], false);
         tile.ObjectsDrawingOrder = layer.DrawingOrder;
         tile.Objects             = layer.Objects;
         return;
     }
     tile.ObjectsDrawingOrder = TiledMapObjectDrawingOrder.TopDown;
     tile.Objects             = new TiledObject[] {};
 }
示例#2
0
        public Light CreateTileLight(float x, float y, TiledMapTilesetTile tile)
        {
            var light = tile.Properties.GetFloat("Light");

            if (light <= 0)
            {
                return(null);
            }
            var color = tile.Properties.ContainsKey("LightColor") ? tile.Properties.GetColor("LightColor") : ColorExtensions.FromHex(0xffec969b);

            return(new PointLight {
                Position = new Vector2(x, y) * this.TileSize,
                Color = color,
                Scale = light * this.TileSize
            });
        }
示例#3
0
        void ReadTilesets(ContentReader input, TiledMap map)
        {
            var tilesetsCount = input.ReadInt32();
            var tilesets      = new TiledMapTileset[tilesetsCount];

            for (var i = 0; i < tilesetsCount; i += 1)
            {
                tilesets[i] = new TiledMapTileset();

                tilesets[i].Name         = input.ReadString();
                tilesets[i].TexturePaths = input.ReadObject <string[]>();

                if (input.ReadBoolean())
                {
                    var texturesCount = input.ReadInt32();
                    tilesets[i].Textures = new Texture2D[texturesCount];
                    for (var k = 0; k < texturesCount; k += 1)
                    {
                        var path = Path.Combine(Path.GetDirectoryName(input.AssetName), input.ReadString());
                        tilesets[i].Textures[k] = input.ContentManager.Load <Texture2D>(path);
                    }
                }

                tilesets[i].FirstGID   = input.ReadInt32();
                tilesets[i].TileWidth  = input.ReadInt32();
                tilesets[i].TileHeight = input.ReadInt32();
                tilesets[i].Spacing    = input.ReadInt32();
                tilesets[i].Margin     = input.ReadInt32();
                tilesets[i].TileCount  = input.ReadInt32();
                tilesets[i].Columns    = input.ReadInt32();
                tilesets[i].Offset     = input.ReadVector2();

                var tiles = new TiledMapTilesetTile[tilesets[i].TileCount];
                for (var k = 0; k < tiles.Length; k += 1)
                {
                    tiles[k]         = ReadTilesetTile(input, map);
                    tiles[k].Tileset = tilesets[i];
                }
                tilesets[i].Tiles           = tiles;
                tilesets[i].BackgroundColor = input.ReadObject <Color?>();
                tilesets[i].Properties      = input.ReadObject <Dictionary <string, string> >();
            }

            map.Tilesets = tilesets;
        }
示例#4
0
        TiledMapTilesetTile ReadTilesetTile(ContentReader input, TiledMap map)
        {
            var tile = new TiledMapTilesetTile();

            tile.GID             = input.ReadInt32();
            tile.TextureID       = input.ReadInt32();
            tile.TexturePosition = input.ReadObject <Rectangle>();

            tile.ObjectsDrawingOrder = (TiledMapObjectDrawingOrder)input.ReadByte();

            var objectsCount = input.ReadInt32();
            var objects      = new TiledObject[objectsCount];

            for (var k = 0; k < objectsCount; k += 1)
            {
                objects[k] = ReadObject(input, map);
            }
            tile.Objects = objects;

            tile.Properties = input.ReadObject <Dictionary <string, string> >();

            return(tile);
        }
        /// <summary>
        /// Returns collider for a given tile and sets an offset.
        /// </summary>
        ICollider GetCollider(TiledMapTilesetTile tiledTile, Tileset tileset, ref Vector2 colliderOffset)
        {
            ICollider collider = null;

            if (tiledTile.Objects.Length > 0 && tiledTile.Objects[0] is TiledRectangleObject)
            {
                var obj = tiledTile.Objects[0];

                if (obj.Type.ToLower() == _rectangleName)
                {
                    collider      = new RectangleCollider();
                    collider.Size = obj.Size;
                }
                if (obj.Type.ToLower() == _platformName)
                {
                    collider      = new PlatformCollider();
                    collider.Size = obj.Size;
                }
                // Here we need to flip y in the offset, because tiles are draw with origin in bottom left corner,
                // but colliders take origin as top left corner. Why? Ask Tiled dev.
                colliderOffset = obj.Position + tileset.Offset * new Vector2(1, -1) + obj.Size / 2;
            }
            return(collider);
        }
示例#6
0
        void WriteTilesetTile(ContentWriter output, TiledMapTilesetTile tile)
        {
            output.Write(tile.GID);
            output.Write(tile.TextureID);
            output.WriteObject(tile.TexturePosition);

            output.Write((byte)tile.ObjectsDrawingOrder);

            if (tile.Objects != null)
            {
                output.Write(tile.Objects.Length);
                foreach (var obj in tile.Objects)
                {
                    WriteObject(output, obj);
                }
            }
            else
            {
                output.Write(0);
            }


            output.WriteObject(tile.Properties);
        }
示例#7
0
        static TiledMapTileset ParseTileset(XmlNode tilesetXml)
        {
            var tileset = new TiledMapTileset();

            tileset.FirstGID = int.Parse(tilesetXml.Attributes["firstgid"].Value);

            var tilesetDir = "";

            if (tilesetXml.Attributes["source"] != null)
            {
                ExternalTilesetsFirstGID.Add(
                    Path.GetFullPath(TiledMapImporter.CurrentRootDir + '/' + tilesetXml.Attributes["source"].Value),
                    (uint)tileset.FirstGID
                    );

                // If there is "source" field, that means, tileset is external.
                var doc = new XmlDocument();
                try
                {
                    // Paths in tileset file are relative to that file, so root dir needs to be swapped.
                    TiledMapImporter.CurrentRootDir = TiledMapImporter.TmxRootDir + Path.GetDirectoryName(tilesetXml.Attributes["source"].Value) + "/";

                    doc.Load(TiledMapImporter.CurrentRootDir + "/" + Path.GetFileName(tilesetXml.Attributes["source"].Value));
                    tilesetDir = Path.GetDirectoryName(tilesetXml.Attributes["source"].Value) + '/';
                    tilesetXml = doc["tileset"];                     // Swapping to actual tileset.
                }
                catch (Exception e)
                {
                    throw new Exception("Error loading external tileset! " + e.Message + " " + e.StackTrace);
                }
            }
            tileset.Properties = XmlHelper.GetProperties(tilesetXml);

            // This means, that tileset won't be used in the game and should be ignored.
            if (
                tileset.Properties.ContainsKey(IgnoreTilesetFlag) &&
                bool.Parse(tileset.Properties[IgnoreTilesetFlag])
                )
            {
                TiledMapImporter.CurrentRootDir = TiledMapImporter.TmxRootDir;
                return(null);
            }

            Logger.Log("Parsing tileset " + tilesetXml.Attributes["name"].Value);

            #region Main fields.

            tileset.Name       = tilesetXml.Attributes["name"].Value;
            tileset.TileWidth  = int.Parse(tilesetXml.Attributes["tilewidth"].Value);
            tileset.TileHeight = int.Parse(tilesetXml.Attributes["tileheight"].Value);
            tileset.TileCount  = int.Parse(tilesetXml.Attributes["tilecount"].Value);
            tileset.Columns    = int.Parse(tilesetXml.Attributes["columns"].Value);

            tileset.Margin  = XmlHelper.GetXmlIntSafe(tilesetXml, "margin");
            tileset.Spacing = XmlHelper.GetXmlIntSafe(tilesetXml, "spacing");

            if (tilesetXml.Attributes["backgroundcolor"] != null)
            {
                tileset.BackgroundColor = XmlHelper.StringToColor(tilesetXml.Attributes["backgroundcolor"].Value);
            }

            if (tilesetXml["tileoffset"] != null)
            {
                tileset.Offset = new Vector2(
                    float.Parse(tilesetXml["tileoffset"].Attributes["x"].Value, CultureInfo.InvariantCulture),
                    float.Parse(tilesetXml["tileoffset"].Attributes["y"].Value, CultureInfo.InvariantCulture)
                    );
            }

            #endregion Main fields.


            // Turning tile xml into usable dictionary.
            var tiles = new Dictionary <int, XmlNode>();            // List won't suit, because some tile ids may be skipped.
            foreach (XmlNode tileXml in tilesetXml.SelectNodes("tile"))
            {
                tiles.Add(int.Parse(tileXml.Attributes["id"].Value), tileXml);
            }
            // Turning tile xml into usable dictionary.

            /*
             * It is very problematic to load Texture2D without
             * GraphicsDevice, so textures are imported later as external references.
             * At this stage map will just remember their
             * relative paths, and will pick textures up later.
             */

            tileset.Tiles = new TiledMapTilesetTile[tileset.TileCount];

            if (tilesetXml["image"] != null)
            {
                /*
                 * NOTE: Single image tilesets can still have
                 * <tile> tags with properties.
                 */
                // Single-image tileset.
                var texturePaths = new string[1];

                texturePaths[0]      = tilesetDir + tilesetXml["image"].Attributes["source"].Value;
                tileset.TexturePaths = texturePaths;

                var currentID = 0;
                for (var y = 0; y < tileset.Height; y += 1)
                {
                    for (var x = 0; x < tileset.Width; x += 1)
                    {
                        var tile = new TiledMapTilesetTile();
                        //tile.Tileset = tileset; // Assigning tileset here is useless - loopback link will be lost during serialization.
                        tile.GID             = tileset.FirstGID + currentID;
                        tile.TextureID       = 0;
                        tile.TexturePosition = new Rectangle(
                            tileset.Margin + x * (tileset.TileWidth + tileset.Spacing),
                            tileset.Margin + y * (tileset.TileHeight + tileset.Spacing),
                            tileset.TileWidth,
                            tileset.TileHeight
                            );

                        if (tiles.ContainsKey(currentID))
                        {
                            ReadTileObjects(tiles[currentID], ref tile);
                            tile.Properties = XmlHelper.GetProperties(tiles[currentID]);
                        }
                        else
                        {
                            tile.Objects    = new TiledObject[0];
                            tile.Properties = new Dictionary <string, string>();
                        }
                        tileset.Tiles[currentID] = tile;
                        currentID += 1;
                    }
                }
                // Single-image tileset.
            }
            else
            {
                // Image collection tileset.
                var texturePaths = new List <string>();

                var currentID = 0;
                foreach (var nodePair in tiles)
                {
                    var tile = new TiledMapTilesetTile();
                    //tile.Tileset = tileset;
                    tile.GID = tileset.FirstGID + nodePair.Key;

                    var texturePath = tilesetDir + nodePair.Value["image"].Attributes["source"].Value;
                    if (texturePaths.Contains(texturePath))
                    {
                        // Avoiding duplicates.
                        tile.TextureID = texturePaths.IndexOf(texturePath);
                    }
                    else
                    {
                        tile.TextureID = texturePaths.Count;
                        texturePaths.Add(texturePath);
                    }

                    tile.TexturePosition = new Rectangle(
                        0, 0,
                        int.Parse(nodePair.Value["image"].Attributes["width"].Value),
                        int.Parse(nodePair.Value["image"].Attributes["height"].Value)
                        );

                    ReadTileObjects(nodePair.Value, ref tile);

                    tile.Properties = XmlHelper.GetProperties(nodePair.Value);

                    tileset.Tiles[currentID] = tile;
                    currentID += 1;
                }
                tileset.TexturePaths = texturePaths.ToArray();


                // Image collection tileset.
            }

            TiledMapImporter.CurrentRootDir = TiledMapImporter.TmxRootDir;


            return(tileset);
        }
示例#8
0
        public GameMap(TiledMap tiledMap)
        {
            TiledMap = tiledMap;

            tiles = new Tile[tiledMap.Width, tiledMap.Height];

            foreach (var layer in tiledMap.TileLayers)
            {
                for (int x = 0; x < layer.Width; x++)
                {
                    for (int y = 0; y < layer.Height; y++)
                    {
                        if (tiles[x, y] == null)
                        {
                            tiles[x, y] = new Tile(this, x, y);
                        }

                        layer.TryGetTile(x, y, out TiledMapTile? tiledMapTile);

                        TiledMapTile layerTile = tiledMapTile.Value;

                        if (layerTile.IsBlank)
                        {
                            continue;
                        }

                        TiledMapTileset     tileset     = TiledMap.GetTilesetByTileGlobalIdentifier(layerTile.GlobalIdentifier);
                        TiledMapTilesetTile tilesetTile = tileset.Tiles.FirstOrDefault(
                            t => t.LocalTileIdentifier == layerTile.GlobalIdentifier - tileset.FirstGlobalIdentifier);

                        if (tilesetTile != null)
                        {
                            tilesetTile.Properties.TryGetValue("IsWalkable", out string isWalkable);
                            tilesetTile.Properties.TryGetValue("IsPlaceable", out string isPlaceable);
                            tilesetTile.Properties.TryGetValue("IsSpawnable", out string isSpawnable);

                            tiles[x, y].IsWalkable  = isWalkable == "true";
                            tiles[x, y].IsPlaceable = isPlaceable == "true";
                            tiles[x, y].IsSpawnable = isSpawnable == "true";

                            if (tiles[x, y].IsSpawnable)
                            {
                                spawnableTiles.Add(tiles[x, y]);
                            }
                        }
                    }
                }
            }

            // Store references to each tile's adjacent tiles.
            foreach (var tile in tiles)
            {
                if (tile.Position.X > 0)
                {
                    tile.AdjacentTiles.Add(this[tile.X - 1, tile.Y]);
                }

                if (tile.Position.X < TiledMap.Width - 1)
                {
                    tile.AdjacentTiles.Add(this[tile.X + 1, tile.Y]);
                }

                if (tile.Position.Y > 0)
                {
                    tile.AdjacentTiles.Add(this[tile.X, tile.Y - 1]);
                }

                if (tile.Position.Y < TiledMap.Height - 1)
                {
                    tile.AdjacentTiles.Add(this[tile.X, tile.Y + 1]);
                }
            }
        }
示例#9
0
        protected void SetTilesFromTiledMap(TiledMap tiledMap)
        {
            Tiles = new List <Tile>();
            List <TiledMapTile>        tiledMapTiles        = tiledMap.TileLayers.FirstOrDefault().Tiles.ToList();
            TiledMapTileset            tiledMapTileset      = tiledMap.Tilesets.FirstOrDefault();
            List <TiledMapTilesetTile> tiledMapTilesetTiles = tiledMapTileset.Tiles.ToList();
            var       test           = tiledMapTiles.Where(t => t.GlobalIdentifier != 0).ToList();
            int       textureColumns = tiledMapTileset.Columns;
            Texture2D tilesetTexture = tiledMap.Tilesets.FirstOrDefault().Texture;
            int?      rows           = tiledMap.TileLayers.FirstOrDefault().Height;
            int?      columns        = tiledMap.TileLayers.FirstOrDefault().Width;
            int       i = 0;

            for (int y = 0; y < rows; y++)
            {
                for (int x = 0; x < columns; x++)
                {
                    TiledMapTile tiledMapTile = tiledMapTiles[i];
                    Tile         tile         = new Tile
                    {
                        Container     = this,
                        Location      = new Point(x, y),
                        CollisionType = CollisionType.None,
                        TileType      = (TileType)tiledMapTile.GlobalIdentifier,
                        MaxHealth     = 0,
                        CurrentHealth = 0,
                        North         = y == 0 ? null : columns * y - columns + x,
                        NorthEast     = y == 0 || x == columns - 1 ? null : columns * y - columns + x + 1,
                        East          = x == columns - 1 ? null : (int?)Tiles.Count() + 1,
                        SouthEast     = y == rows - 1 || x == columns - 1 ? null : columns * y + columns + x + 1,
                        South         = y == rows - 1 ? null : columns * y + columns + x,
                        SouthWest     = y == rows - 1 || x == 0 ? null : columns * y + columns + x - 1,
                        West          = x == 0 ? null : (int?)Tiles.Count() - 1,
                        NorthWest     = y == 0 || x == 0 ? null : columns * y - columns + x - 1,
                    };
                    tile.Position = new Vector2(x * MainGame.TileSize, y * MainGame.TileSize) - Center + tile.TileCenter;
                    Vector2 relativePosition = new Vector2(x * MainGame.TileSize, y * MainGame.TileSize);
                    relativePosition -= Center;
                    tile.Bounds       = new Rectangle((int)relativePosition.X, (int)relativePosition.Y, MainGame.TileSize, MainGame.TileSize);

                    // Set Image Data
                    if (tiledMapTile.GlobalIdentifier > 0)
                    {
                        tile.Image       = tilesetTexture;
                        tile.ImageSource = new Rectangle(
                            ((tiledMapTile.GlobalIdentifier - 1) % textureColumns) * Art.TileSize,
                            ((tiledMapTile.GlobalIdentifier - 1) / textureColumns - 1 < 0 ? 0 : (tiledMapTile.GlobalIdentifier - 1) / textureColumns) * Art.TileSize,
                            Art.TileSize, Art.TileSize);
                        tile.Heading = tiledMapTile.IsFlippedDiagonally && tiledMapTile.IsFlippedHorizontally ? (float)Math.PI / 2
                           : tiledMapTile.IsFlippedDiagonally && tiledMapTile.IsFlippedVertically ? -(float)Math.PI / 2
                           : tiledMapTile.IsFlippedVertically ? (float)Math.PI : 0;
                    }

                    // Set Tileset Data
                    TiledMapTilesetTile tiledMapTilesetTile = tiledMapTilesetTiles.FirstOrDefault(t => t.LocalTileIdentifier + 1 == tiledMapTile.GlobalIdentifier);
                    if (tiledMapTilesetTile != null)
                    {
                        tile.CollisionType = tiledMapTilesetTile.Properties.ContainsKey("Collision") ?
                                             (CollisionType)int.Parse(tiledMapTilesetTile.Properties["Collision"]) : CollisionType.None;
                        tile.MaxHealth     = tiledMapTilesetTile.Properties.ContainsKey("Health") ? int.Parse(tiledMapTilesetTile.Properties["Health"]) : 0;
                        tile.CurrentHealth = tile.MaxHealth;
                    }

                    Tiles.Add(tile);
                    i++;
                }
            }
        }