예제 #1
0
 /// <summary>
 /// Checks is a tile is flipped diagonally
 /// </summary>
 /// <param name="layer">An entry of the TiledMap.layers array</param>
 /// <param name="dataIndex">An index of the TiledLayer.data array</param>
 /// <returns>True if the tile was flipped diagonally or False if not</returns>
 public bool IsTileFlippedDiagonal(TiledLayer layer, int dataIndex)
 {
     return((layer.dataRotationFlags[dataIndex] & (FLIPPED_DIAGONALLY_FLAG >> SHIFT_FLIP_FLAG_TO_BYTE)) > 0);
 }
예제 #2
0
 /// <summary>
 /// Checks is a tile is flipped diagonally
 /// </summary>
 /// <param name="layer">An entry of the TiledMap.layers array</param>
 /// <param name="tileHor">The tile's horizontal position</param>
 /// <param name="tileVert">The tile's vertical position</param>
 /// <returns>True if the tile was flipped diagonally or False if not</returns>
 public bool IsTileFlippedDiagonal(TiledLayer layer, int tileHor, int tileVert)
 {
     return(IsTileFlippedDiagonal(layer, tileHor + (tileVert * layer.width)));
 }
예제 #3
0
 /// <summary>
 /// Checks is a tile is flipped horizontally
 /// </summary>
 /// <param name="layer">An entry of the TiledMap.layers array</param>
 /// <param name="dataIndex">An index of the TiledLayer.data array</param>
 /// <returns>True if the tile was flipped horizontally or False if not</returns>
 public bool IsTileFlippedHorizontal(TiledLayer layer, int dataIndex)
 {
     return((layer.dataRotationFlags[dataIndex] & (FLIPPED_HORIZONTALLY_FLAG >> SHIFT_FLIP_FLAG_TO_BYTE)) > 0);
 }
예제 #4
0
 /// <summary>
 /// Checks is a tile is flipped vertically
 /// </summary>
 /// <param name="layer">An entry of the TiledMap.layers array</param>
 /// <param name="dataIndex">An index of the TiledLayer.data array</param>
 /// <returns>True if the tile was flipped vertically or False if not</returns>
 public bool IsTileFlippedVertical(TiledLayer layer, int dataIndex)
 {
     return((layer.dataRotationFlags[dataIndex] & (FLIPPED_VERTICALLY_FLAG >> SHIFT_FLIP_FLAG_TO_BYTE)) > 0);
 }
예제 #5
0
        private TiledLayer[] ParseLayers(XmlNodeList nodesLayer, XmlNodeList nodesObjectGroup, XmlNodeList nodesImageLayer)
        {
            var result = new List <TiledLayer>();

            foreach (XmlNode node in nodesLayer)
            {
                var nodeData      = node.SelectSingleNode("data");
                var nodesProperty = node.SelectNodes("properties/property");
                var encoding      = nodeData.Attributes["encoding"].Value;
                var attrVisible   = node.Attributes["visible"];
                var attrLocked    = node.Attributes["locked"];
                var attrTint      = node.Attributes["tintcolor"];
                var attrOffsetX   = node.Attributes["offsetx"];
                var attrOffsetY   = node.Attributes["offsety"];

                var tiledLayer = new TiledLayer();
                tiledLayer.id      = int.Parse(node.Attributes["id"].Value);
                tiledLayer.name    = node.Attributes["name"].Value;
                tiledLayer.height  = int.Parse(node.Attributes["height"].Value);
                tiledLayer.width   = int.Parse(node.Attributes["width"].Value);
                tiledLayer.type    = "tilelayer";
                tiledLayer.visible = true;

                if (attrVisible != null)
                {
                    tiledLayer.visible = attrVisible.Value == "1";
                }
                if (attrLocked != null)
                {
                    tiledLayer.locked = attrLocked.Value == "1";
                }
                if (attrTint != null)
                {
                    tiledLayer.tintcolor = attrTint.Value;
                }
                if (attrOffsetX != null)
                {
                    tiledLayer.offsetX = int.Parse(attrOffsetX.Value);
                }
                if (attrOffsetY != null)
                {
                    tiledLayer.offsetY = int.Parse(attrOffsetY.Value);
                }
                if (nodesProperty != null)
                {
                    tiledLayer.properties = ParseProperties(nodesProperty);
                }

                if (encoding == "csv")
                {
                    var csvs = nodeData.InnerText.Split(',');

                    tiledLayer.data = new int[csvs.Length];
                    tiledLayer.dataRotationFlags = new byte[csvs.Length];

                    // Parse the comma separated csv string and update the inner data as well as the data rotation flags
                    for (var i = 0; i < csvs.Length; i++)
                    {
                        var rawID = uint.Parse(csvs[i]);
                        var hor   = ((rawID & FLIPPED_HORIZONTALLY_FLAG));
                        var ver   = ((rawID & FLIPPED_VERTICALLY_FLAG));
                        var dia   = ((rawID & FLIPPED_DIAGONALLY_FLAG));
                        tiledLayer.dataRotationFlags[i] = (byte)((hor | ver | dia) >> SHIFT_FLIP_FLAG_TO_BYTE);

                        // assign data to rawID with the rotation flags cleared
                        tiledLayer.data[i] = (int)(rawID & ~(FLIPPED_HORIZONTALLY_FLAG | FLIPPED_VERTICALLY_FLAG | FLIPPED_DIAGONALLY_FLAG));
                    }
                }
                else if (encoding == "base64")
                {
                    var compression = nodeData.Attributes["compression"]?.Value;

                    using (var base64DataStream = new MemoryStream(Convert.FromBase64String(nodeData.InnerText)))
                    {
                        if (compression == null)
                        {
                            // Parse the decoded bytes and update the inner data as well as the data rotation flags
                            var rawBytes = new byte[4];
                            tiledLayer.data = new int[base64DataStream.Length];
                            tiledLayer.dataRotationFlags = new byte[base64DataStream.Length];

                            for (var i = 0; i < base64DataStream.Length; i++)
                            {
                                base64DataStream.Read(rawBytes, 0, rawBytes.Length);
                                var rawID = BitConverter.ToUInt32(rawBytes, 0);
                                var hor   = ((rawID & FLIPPED_HORIZONTALLY_FLAG));
                                var ver   = ((rawID & FLIPPED_VERTICALLY_FLAG));
                                var dia   = ((rawID & FLIPPED_DIAGONALLY_FLAG));
                                tiledLayer.dataRotationFlags[i] = (byte)((hor | ver | dia) >> SHIFT_FLIP_FLAG_TO_BYTE);

                                // assign data to rawID with the rotation flags cleared
                                tiledLayer.data[i] = (int)(rawID & ~(FLIPPED_HORIZONTALLY_FLAG | FLIPPED_VERTICALLY_FLAG | FLIPPED_DIAGONALLY_FLAG));
                            }
                        }
                        else if (compression == "zlib")
                        {
                            // .NET doesn't play well with the headered zlib data that Tiled produces,
                            // so we have to manually skip the 2-byte header to get what DeflateStream's looking for
                            // Should an external library be used instead of this hack?
                            base64DataStream.ReadByte();
                            base64DataStream.ReadByte();

                            using (var decompressionStream = new DeflateStream(base64DataStream, CompressionMode.Decompress))
                            {
                                // Parse the raw decompressed bytes and update the inner data as well as the data rotation flags
                                var decompressedDataBuffer = new byte[4]; // size of each tile
                                var dataRotationFlagsList  = new List <byte>();
                                var layerDataList          = new List <int>();

                                while (decompressionStream.Read(decompressedDataBuffer, 0, decompressedDataBuffer.Length) == decompressedDataBuffer.Length)
                                {
                                    var rawID = BitConverter.ToUInt32(decompressedDataBuffer, 0);
                                    var hor   = ((rawID & FLIPPED_HORIZONTALLY_FLAG));
                                    var ver   = ((rawID & FLIPPED_VERTICALLY_FLAG));
                                    var dia   = ((rawID & FLIPPED_DIAGONALLY_FLAG));
                                    dataRotationFlagsList.Add((byte)((hor | ver | dia) >> SHIFT_FLIP_FLAG_TO_BYTE));

                                    // assign data to rawID with the rotation flags cleared
                                    layerDataList.Add((int)(rawID & ~(FLIPPED_HORIZONTALLY_FLAG | FLIPPED_VERTICALLY_FLAG | FLIPPED_DIAGONALLY_FLAG)));
                                }

                                tiledLayer.data = layerDataList.ToArray();
                                tiledLayer.dataRotationFlags = dataRotationFlagsList.ToArray();
                            }
                        }
                        else if (compression == "gzip")
                        {
                            using (var decompressionStream = new GZipStream(base64DataStream, CompressionMode.Decompress))
                            {
                                // Parse the raw decompressed bytes and update the inner data as well as the data rotation flags
                                var decompressedDataBuffer = new byte[4]; // size of each tile
                                var dataRotationFlagsList  = new List <byte>();
                                var layerDataList          = new List <int>();

                                while (decompressionStream.Read(decompressedDataBuffer, 0, decompressedDataBuffer.Length) == decompressedDataBuffer.Length)
                                {
                                    var rawID = BitConverter.ToUInt32(decompressedDataBuffer, 0);
                                    var hor   = ((rawID & FLIPPED_HORIZONTALLY_FLAG));
                                    var ver   = ((rawID & FLIPPED_VERTICALLY_FLAG));
                                    var dia   = ((rawID & FLIPPED_DIAGONALLY_FLAG));

                                    dataRotationFlagsList.Add((byte)((hor | ver | dia) >> SHIFT_FLIP_FLAG_TO_BYTE));

                                    // assign data to rawID with the rotation flags cleared
                                    layerDataList.Add((int)(rawID & ~(FLIPPED_HORIZONTALLY_FLAG | FLIPPED_VERTICALLY_FLAG | FLIPPED_DIAGONALLY_FLAG)));
                                }

                                tiledLayer.data = layerDataList.ToArray();
                                tiledLayer.dataRotationFlags = dataRotationFlagsList.ToArray();
                            }
                        }
                        else
                        {
                            throw new TiledException("Zstandard compression is currently not supported");
                        }
                    }
                }
                else
                {
                    throw new TiledException("Only CSV and Base64 encodings are currently supported");
                }

                result.Add(tiledLayer);
            }

            foreach (XmlNode node in nodesObjectGroup)
            {
                var nodesProperty = node.SelectNodes("properties/property");
                var nodesObject   = node.SelectNodes("object");
                var attrVisible   = node.Attributes["visible"];
                var attrLocked    = node.Attributes["locked"];
                var attrTint      = node.Attributes["tintcolor"];
                var attrOffsetX   = node.Attributes["offsetx"];
                var attrOffsetY   = node.Attributes["offsety"];

                var tiledLayer = new TiledLayer();
                tiledLayer.id      = int.Parse(node.Attributes["id"].Value);
                tiledLayer.name    = node.Attributes["name"].Value;
                tiledLayer.objects = ParseObjects(nodesObject);
                tiledLayer.type    = "objectgroup";
                tiledLayer.visible = true;

                if (attrVisible != null)
                {
                    tiledLayer.visible = attrVisible.Value == "1";
                }
                if (attrLocked != null)
                {
                    tiledLayer.locked = attrLocked.Value == "1";
                }
                if (attrTint != null)
                {
                    tiledLayer.tintcolor = attrTint.Value;
                }
                if (attrOffsetX != null)
                {
                    tiledLayer.offsetX = int.Parse(attrOffsetX.Value);
                }
                if (attrOffsetY != null)
                {
                    tiledLayer.offsetY = int.Parse(attrOffsetY.Value);
                }
                if (nodesProperty != null)
                {
                    tiledLayer.properties = ParseProperties(nodesProperty);
                }

                result.Add(tiledLayer);
            }

            foreach (XmlNode node in nodesImageLayer)
            {
                var nodesProperty = node.SelectNodes("properties/property");
                var nodeImage     = node.SelectSingleNode("image");
                var attrVisible   = node.Attributes["visible"];
                var attrLocked    = node.Attributes["locked"];
                var attrTint      = node.Attributes["tintcolor"];
                var attrOffsetX   = node.Attributes["offsetx"];
                var attrOffsetY   = node.Attributes["offsety"];

                var tiledLayer = new TiledLayer();
                tiledLayer.id      = int.Parse(node.Attributes["id"].Value);
                tiledLayer.name    = node.Attributes["name"].Value;
                tiledLayer.type    = "imagelayer";
                tiledLayer.visible = true;

                if (attrVisible != null)
                {
                    tiledLayer.visible = attrVisible.Value == "1";
                }
                if (attrLocked != null)
                {
                    tiledLayer.locked = attrLocked.Value == "1";
                }
                if (attrTint != null)
                {
                    tiledLayer.tintcolor = attrTint.Value;
                }
                if (attrOffsetX != null)
                {
                    tiledLayer.offsetX = int.Parse(attrOffsetX.Value);
                }
                if (attrOffsetY != null)
                {
                    tiledLayer.offsetY = int.Parse(attrOffsetY.Value);
                }
                if (nodesProperty != null)
                {
                    tiledLayer.properties = ParseProperties(nodesProperty);
                }
                if (nodeImage != null)
                {
                    tiledLayer.image = ParseImage(nodeImage);
                }

                result.Add(tiledLayer);
            }

            return(result.ToArray());
        }