Esempio n. 1
0
        private AnimatedTile LoadAnimatedTile(XmlHelper xmlHelper, Layer layer, TileSheet tileSheet)
        {
            int frameInterval = xmlHelper.GetIntAttribute("Interval");

            xmlHelper.AdvanceStartElement("Frames");

            Map map = layer.Map;
            List <StaticTile> tileFrames = new List <StaticTile>();

            while (xmlHelper.AdvanceNode() != XmlNodeType.EndElement)
            {
                if (xmlHelper.XmlReader.Name == "Static")
                {
                    tileFrames.Add(LoadStaticTile(xmlHelper, layer, tileSheet));
                }
                else if (xmlHelper.XmlReader.Name == "TileSheet")
                {
                    string tileSheetRef = xmlHelper.GetAttribute("Ref");
                    tileSheet = map.GetTileSheet(tileSheetRef);
                }
            }

            AnimatedTile animatedTile
                = new AnimatedTile(layer, tileFrames.ToArray(), frameInterval);

            // end of this element or optional props
            if (xmlHelper.AdvanceNode() != XmlNodeType.EndElement)
            {
                LoadProperties(xmlHelper, animatedTile);
            }

            return(animatedTile);
        }
        private void LoadLayerDataCsv(XmlHelper xmlHelper, Layer layer)
        {
            xmlHelper.AdvanceNode(XmlNodeType.Text);

            XmlReader xmlReader = xmlHelper.XmlReader;

            string csvData = xmlReader.Value;

            string[] csvElements = csvData.Split(new char[] { ',', '\r', '\n', '\t' }, StringSplitOptions.RemoveEmptyEntries);

            Location tileLocation = Location.Origin;

            foreach (string csvElement in csvElements)
            {
                int gid = int.Parse(csvElement);

                layer.Tiles[tileLocation] = LoadStaticTile(layer, gid);

                ++tileLocation.X;
                if (tileLocation.X >= layer.LayerWidth)
                {
                    tileLocation.X = 0;
                    ++tileLocation.Y;
                }
            }

            xmlHelper.AdvanceEndElement("data");
        }
        public Map Load(Stream stream)
        {
            XmlTextReader xmlReader = new XmlTextReader(stream);

            xmlReader.WhitespaceHandling = WhitespaceHandling.None;

            XmlHelper xmlHelper = new XmlHelper(xmlReader);

            xmlHelper.AdvanceDeclaration();
            xmlHelper.AdvanceStartElement("map");

            string orientation = xmlHelper.GetAttribute("orientation");

            if (orientation != "orthogonal")
            {
                throw new Exception("Only orthogonal Tiled maps are supported.");
            }

            int mapWidth  = xmlHelper.GetIntAttribute("width");
            int mapHeight = xmlHelper.GetIntAttribute("height");

            int tileWidth  = xmlHelper.GetIntAttribute("tilewidth");
            int tileHeight = xmlHelper.GetIntAttribute("tileheight");

            Map map = new Map();

            while (true)
            {
                XmlNodeType xmlNodeType = xmlHelper.AdvanceNode();
                if (xmlNodeType == XmlNodeType.EndElement)
                {
                    break;
                }

                if (xmlReader.Name == "properties")
                {
                    LoadProperties(xmlHelper, map);
                }
                else if (xmlReader.Name == "tileset")
                {
                    LoadTileSet(xmlHelper, map);
                }
                else if (xmlReader.Name == "layer")
                {
                    LoadLayer(xmlHelper, map);
                }
                else
                {
                    xmlHelper.SkipToEndElement(xmlReader.Name);
                }
            }

            // try to obtain map description via custom property
            if (map.Properties.ContainsKey("@Description"))
            {
                map.Description = map.Properties["@Description"];
            }

            return(map);
        }
Esempio n. 4
0
        public Map Load(Stream stream)
        {
            // not implemented yet
            throw new Exception("This format is not supported yet");

            XmlTextReader xmlReader = new XmlTextReader(stream);

            xmlReader.WhitespaceHandling = WhitespaceHandling.None;

            XmlHelper xmlHelper = new XmlHelper(xmlReader);

            xmlHelper.AdvanceDeclaration();
            xmlHelper.AdvanceStartElement("map");

            string orientation = xmlHelper.GetAttribute("orientation");

            if (orientation != "orthogonal")
            {
                throw new Exception("Only orthogonal Tiled maps are supported.");
            }

            int mapWidth  = xmlHelper.GetIntAttribute("width");
            int mapHeight = xmlHelper.GetIntAttribute("height");

            int tileWidth  = xmlHelper.GetIntAttribute("tilewidth");
            int tileHeight = xmlHelper.GetIntAttribute("tileheight");

            Map map = new Map();

            while (true)
            {
                XmlNodeType xmlNodeType = xmlHelper.AdvanceNode();
                if (xmlNodeType == XmlNodeType.EndElement)
                {
                    break;
                }

                if (xmlReader.Name == "tileset")
                {
                    LoadTileSet(xmlHelper, map);
                }
                else if (xmlReader.Name == "layer")
                {
                    LoadLayer(xmlHelper, map);
                }
            }

            LoadProperties(xmlHelper, map);

            return(map);
        }
Esempio n. 5
0
        private void LoadLayer(XmlHelper xmlHelper, Map map)
        {
            string id = xmlHelper.GetAttribute("Id");

            xmlHelper.AdvanceStartElement("Description");
            string description = xmlHelper.GetCData();

            xmlHelper.AdvanceEndElement("Description");

            xmlHelper.AdvanceStartElement("Dimensions");
            Size layerSize = Size.FromString(xmlHelper.GetAttribute("LayerSize"));
            Size tileSize  = Size.FromString(xmlHelper.GetAttribute("TileSize"));

            xmlHelper.AdvanceEndElement("Dimensions");

            Layer layer = new Layer(id, map, layerSize, tileSize);

            layer.Description = description;

            xmlHelper.AdvanceStartElement("TileArray");

            Location  tileLocation = Location.Origin;
            TileSheet tileSheet    = null;
            XmlReader xmlReader    = xmlHelper.XmlReader;

            while (xmlHelper.AdvanceStartRepeatedElement("Row", "TileArray"))
            {
                tileLocation.X = 0;

                while (xmlHelper.AdvanceNode() != XmlNodeType.EndElement)
                {
                    if (xmlReader.Name == "Null")
                    {
                        int nullCount = xmlHelper.GetIntAttribute("Count");
                        tileLocation.X += nullCount % layerSize.Width;
                    }
                    else if (xmlReader.Name == "TileSheet")
                    {
                        string tileSheetRef = xmlHelper.GetAttribute("Ref");
                        tileSheet = map.GetTileSheet(tileSheetRef);
                    }
                    else if (xmlReader.Name == "Static")
                    {
                        layer.Tiles[tileLocation] = LoadStaticTile(xmlHelper, layer, tileSheet);

                        ++tileLocation.X;
                    }
                    else if (xmlReader.Name == "Animated")
                    {
                        layer.Tiles[tileLocation] = LoadAnimatedTile(xmlHelper, layer, tileSheet);

                        ++tileLocation.X;
                    }
                }

                ++tileLocation.Y;
            }

            LoadProperties(xmlHelper, layer);

            xmlHelper.AdvanceEndElement("Layer");

            map.AddLayer(layer);
        }
        private void LoadLayer(XmlHelper xmlHelper, Map map)
        {
            if (map.TileSheets.Count == 0)
            {
                throw new Exception("Must load at least one tileset to determine layer tile size");
            }

            string id = xmlHelper.GetAttribute("name");

            int  layerWidth  = xmlHelper.GetIntAttribute("width");
            int  layerHeight = xmlHelper.GetIntAttribute("height");
            Size layerSize   = new Size(layerWidth, layerHeight);

            int visible = xmlHelper.GetIntAttribute("visible", 1);

            // must assume tile size from first tile set
            Size tileSize = map.TileSheets[0].TileSize;

            Layer layer = new Layer(id, map, layerSize, tileSize);

            layer.Visible = visible > 0;

            // load properties if available
            XmlNodeType xmlNodeType = xmlHelper.AdvanceNode();

            if (xmlNodeType == XmlNodeType.Element && xmlHelper.XmlReader.Name == "properties")
            {
                LoadProperties(xmlHelper, layer);

                // try to obtain layer description via custom property
                if (layer.Properties.ContainsKey("@Description"))
                {
                    layer.Description = layer.Properties["@Description"];
                }

                xmlHelper.AdvanceStartElement("data");
            }
            else if (xmlNodeType != XmlNodeType.Element || xmlHelper.XmlReader.Name != "data")
            {
                throw new Exception("The element <properties> or <data> expected");
            }

            string dataEncoding    = xmlHelper.GetAttribute("encoding", "xml");
            string dataCompression = xmlHelper.GetAttribute("compression", "none");

            if (dataEncoding == "xml")
            {
                LoadLayerDataXml(xmlHelper, layer);
            }
            else if (dataEncoding == "base64")
            {
                LoadLayerDataBase64(xmlHelper, layer, dataCompression);
            }
            else if (dataEncoding == "csv")
            {
                LoadLayerDataCsv(xmlHelper, layer);
            }
            else
            {
                throw new Exception("Unknown encoding/compression setting combination (" + dataEncoding + "/" + dataCompression + ")");
            }

            xmlHelper.AdvanceEndElement("layer");

            map.AddLayer(layer);
        }
        private void LoadLayerDataBase64(XmlHelper xmlHelper, Layer layer, string dataCompression)
        {
            xmlHelper.AdvanceNode(XmlNodeType.Text);

            string base64Data = xmlHelper.XmlReader.Value;

            byte[] dataBytes = System.Convert.FromBase64String(base64Data);

            if (dataCompression == "none")
            {
                // do nothing
            }
            else if (dataCompression == "gzip")
            {
                GZipStream inGZipStream = new GZipStream(
                    new MemoryStream(dataBytes), CompressionMode.Decompress);

                MemoryStream outMemoryStream = new MemoryStream();

                byte[] buffer = new byte[1024];
                while (true)
                {
                    int bytesRead = inGZipStream.Read(buffer, 0, buffer.Length);
                    if (bytesRead == 0)
                    {
                        break;
                    }
                    outMemoryStream.Write(buffer, 0, bytesRead);
                }

                dataBytes = outMemoryStream.ToArray();
            }
            else if (dataCompression == "zlib")
            {
                ZInputStream inZInputStream = new ZInputStream(
                    new MemoryStream(dataBytes));

                MemoryStream outMemoryStream = new MemoryStream();

                byte[] buffer = new byte[1024];
                while (true)
                {
                    int bytesRead = inZInputStream.Read(buffer, 0, buffer.Length);
                    if (bytesRead == 0)
                    {
                        break;
                    }
                    outMemoryStream.Write(buffer, 0, bytesRead);
                }

                dataBytes = outMemoryStream.ToArray();
            }
            else
            {
                throw new Exception("Unknown compression scheme: " + dataCompression);
            }

            if (dataBytes.Length % 4 != 0)
            {
                throw new Exception("Base64 byte stream size must be a mutliple of 4 bytes");
            }

            Location tileLocation = Location.Origin;

            for (int byteIndex = 0; byteIndex < dataBytes.Length; byteIndex += 4)
            {
                int gid =
                    dataBytes[byteIndex] |
                    dataBytes[byteIndex + 1] << 8 |
                        dataBytes[byteIndex + 2] << 16 |
                        dataBytes[byteIndex + 3] << 24;

                layer.Tiles[tileLocation] = LoadStaticTile(layer, gid);

                ++tileLocation.X;
                if (tileLocation.X >= layer.LayerWidth)
                {
                    tileLocation.X = 0;
                    ++tileLocation.Y;
                }
            }

            xmlHelper.AdvanceEndElement("data");
        }
        private void LoadTileSet(XmlHelper xmlHelper, Map map)
        {
            string id = xmlHelper.GetAttribute("name");

            int firstGid = xmlHelper.GetIntAttribute("firstgid");

            int  tileWidth  = xmlHelper.GetIntAttribute("tilewidth");
            int  tileHeight = xmlHelper.GetIntAttribute("tileheight");
            Size tileSize   = new Size(tileWidth, tileHeight);

            int  marginValue = xmlHelper.GetIntAttribute("margin", 0);
            Size margin      = new Size(marginValue);

            int  spacingValue = xmlHelper.GetIntAttribute("spacing", 0);
            Size spacing      = new Size(spacingValue);

            xmlHelper.AdvanceStartElement("image");
            string imageSource = xmlHelper.GetAttribute("source");

            xmlHelper.AdvanceEndElement("image");

            Size sheetSize = new Size();

            try
            {
                using (System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(imageSource))
                {
                    sheetSize.Width  = (bitmap.Width + spacingValue - marginValue) / (tileWidth + spacingValue);
                    sheetSize.Height = (bitmap.Height + spacingValue - marginValue) / (tileHeight + spacingValue);
                }
            }
            catch (Exception exception)
            {
                throw new Exception("Unable to determine sheet size from image source", exception);
            }

            TileSheet tileSheet = new TileSheet(id, map, imageSource, sheetSize, tileSize);

            tileSheet.Margin  = margin;
            tileSheet.Spacing = spacing;

            // keep track of first gid as custom property
            tileSheet.Properties["@FirstGid"] = firstGid;

            // also add lastgid to facilitate import
            tileSheet.Properties["@LastGid"] = firstGid + tileSheet.TileCount - 1;

            // properties at tile level within tile sets not supported
            // but are mapped as prefixed properties at tile sheet level
            XmlNodeType xmlNodeType = xmlHelper.AdvanceNode();

            while (xmlNodeType == XmlNodeType.Element && xmlHelper.XmlReader.Name == "tile")
            {
                int tileId = xmlHelper.GetIntAttribute("id");
                xmlHelper.AdvanceNamedNode(XmlNodeType.Element, "properties");
                Component dummyComponent = new DummyComponent();
                LoadProperties(xmlHelper, dummyComponent);
                xmlHelper.AdvanceEndElement("tile");

                foreach (string propertyName in dummyComponent.Properties.Keys)
                {
                    tileSheet.Properties["@Tile@" + tileId + "@" + propertyName]
                        = dummyComponent.Properties[propertyName];
                }

                xmlNodeType = xmlHelper.AdvanceNode();
            }

            map.AddTileSheet(tileSheet);
        }