/// <summary> /// Import the sprite animation /// </summary> public override void Import(ImportFile file) { using (var sourceFile = File.OpenRead(file.Filename)) using (var targetWriter = new ResourceWriter(File.OpenWrite(file.TargetFilename), typeof(ImageAnimation))) Import(sourceFile, targetWriter); }
private void Import(ImportFile file, XmlDocument doc, ResourceWriter writer) { var map = doc.GetElementsByTagName("map")[0]; var width = int.Parse(map.Attributes["width"].Value); var height = int.Parse(map.Attributes["height"].Value); writer.Write((ushort)width); writer.Write((ushort)height); writer.Write((ushort)int.Parse(map.Attributes["tilewidth"].Value)); writer.Write((ushort)int.Parse(map.Attributes["tileheight"].Value)); var layers = map.SelectNodes("objectgroup | layer"); var tilesets = map.SelectNodes("tileset"); // Write tile sets var tileSetFirstId = new int[tilesets.Count]; writer.Write((ushort)tileSetFirstId.Length); for (int i = 0; i < tileSetFirstId.Length; i++) { XmlNode tileSet = tilesets[i]; var source = tileSet.Attributes["source"].Value; tileSetFirstId[i] = int.Parse(tileSet.Attributes["firstgid"].Value); var uri1 = new Uri(Path.Combine(Path.GetDirectoryName(file.TargetFilename), source)); var uri2 = new Uri(file.TargetDirectory + "\\"); var name = Path.ChangeExtension(uri2.MakeRelativeUri(uri1).ToString(), null); writer.Write(name); } // Write layers writer.Write((ushort)layers.Count); foreach (XmlNode layer in layers) { writer.Write(layer.Attributes["name"]?.Value ?? ""); writer.Write((ushort)width); writer.Write((ushort)height); // Properties var objprops = layer.SelectNodes("properties/property"); writer.Write((ushort)objprops.Count); foreach (XmlNode objprop in objprops) { writer.Write(objprop.Attributes["name"].Value); writer.Write(objprop.Attributes["value"].Value); } switch (layer.Name) { case "layer": { // Write tiles var data = layer["data"]; var encoding = data.Attributes["encoding"].Value; if (encoding != "csv") { throw new ImportException($"encoding '{encoding}' not supported"); } var ids = data.InnerText.Split(','); writer.Write((ushort)ids.Length); for (int i = 0; i < ids.Length; i++) { var id = int.Parse(ids[i]); if (id == 0) { writer.Write((ushort)0xFFFF); continue; } int tileSetId; for (tileSetId = 0; tileSetId < tileSetFirstId.Length - 1 && id >= tileSetFirstId[tileSetId + 1]; tileSetId++) { ; } writer.Write((ushort)tileSetId); writer.Write((ushort)(id - tileSetFirstId[tileSetId])); } // Write objects writer.Write((ushort)0); break; } case "objectgroup": { // No tiles writer.Write((ushort)0); var properties = layer.SelectNodes("properties/property"); // Write objects var objects = layer.SelectNodes("object"); writer.Write((ushort)objects.Count); foreach (XmlNode o in objects) { XmlNode obj = o; var template = obj.Attributes["template"]?.Value; if (template != null) { var templateDoc = new XmlDocument(); templateDoc.Load(Path.Combine(Path.GetDirectoryName(file.Filename), template)); obj = templateDoc.SelectSingleNode("/template/object"); } writer.Write(o.Attributes["name"]?.Value ?? obj.Attributes["name"]?.Value ?? ""); writer.Write(o.Attributes["type"]?.Value ?? obj.Attributes["type"]?.Value ?? ""); writer.Write(new Vector2(float.Parse(o.Attributes["x"].Value), float.Parse(o.Attributes["y"].Value))); // Point if (obj.SelectSingleNode("point") != null) { writer.Write((byte)TileMap.ShapeType.Point); } // Polygon else if (obj.SelectSingleNode("polygon") != null) { writer.Write((byte)TileMap.ShapeType.Polygon); var points = obj.SelectSingleNode("polygon").Attributes["points"].Value.Split(new char[] { ' ' }); writer.Write((ushort)points.Length); for (int i = 0; i < points.Length; i++) { writer.Write(Vector2.Parse(points[i])); } } // Polyline else if (obj.SelectSingleNode("polyline") != null) { writer.Write((byte)TileMap.ShapeType.PolyLine); var points = obj.SelectSingleNode("polyline").Attributes["points"].Value.Split(new char[] { ' ' }); writer.Write((ushort)points.Length); for (int i = 0; i < points.Length; i++) { writer.Write(Vector2.Parse(points[i])); } } // Ellipse else if (obj.SelectSingleNode("ellipse") != null) { writer.Write((byte)TileMap.ShapeType.Circle); writer.Write(float.Parse(o.Attributes["width"]?.Value ?? obj.Attributes["width"]?.Value ?? "0")); writer.Write(float.Parse(o.Attributes["height"]?.Value ?? obj.Attributes["height"]?.Value ?? "0")); } // Box else { writer.Write((byte)TileMap.ShapeType.Box); writer.Write(float.Parse(o.Attributes["width"]?.Value ?? obj.Attributes["width"]?.Value ?? "0")); writer.Write(float.Parse(o.Attributes["height"]?.Value ?? obj.Attributes["height"]?.Value ?? "0")); } // Properties var layerprops = obj.SelectNodes("properties/property"); writer.Write((ushort)layerprops.Count); foreach (XmlNode layerProp in layerprops) { writer.Write(layerProp.Attributes["name"].Value); writer.Write(layerProp.Attributes["value"].Value); } } break; } } } }
private void Import(ImportFile file, XmlDocument doc, ResourceWriter writer) { var tileset = doc.GetElementsByTagName("tileset")[0]; var images = doc.GetElementsByTagName("image"); var tiles = doc.GetElementsByTagName("tile"); var columns = int.Parse(tileset.Attributes["columns"].Value); var spacing = int.Parse(tileset.Attributes["spacing"]?.Value ?? "0"); var tilewidth = int.Parse(tileset.Attributes["tilewidth"].Value); var tileheight = int.Parse(tileset.Attributes["tileheight"].Value); var tilecount = int.Parse(tileset.Attributes["tilecount"].Value); if (images.Count == 0) { throw new ImportException("TileSet has no images"); } if (images.Count > 1) { throw new ImportException("Multiple TileSet images not supported"); } var image = images[0].Attributes["source"].Value; if (Path.ChangeExtension(image, null) != Path.GetFileName(file.Name)) { throw new ImportException("TileSet image must be same name as the tile set"); } image = Path.ChangeExtension(file.Filename, Path.GetExtension(image)); writer.Write((ushort)tilewidth); writer.Write((ushort)tileheight); writer.Write((ushort)tilecount); writer.Write((ushort)tiles.Count); // Write the image using (var source = File.OpenRead(image)) ImageImporter.Import(source, writer, Thickness.Empty, SixLabors.Primitives.Rectangle.Empty); // Embed the tile images into the tile set foreach (XmlNode tile in tiles) { var id = int.Parse(tile.Attributes["id"].Value); var x = id % columns; var y = id / columns; x = (x * tilewidth) + x * spacing; y = (y * tileheight) + y * spacing; writer.Write((ushort)id); writer.Write((ushort)x); writer.Write((ushort)y); WriteProperties(writer, tile["properties"]); var objectGroup = tile["objectgroup"]; if (objectGroup != null) { writer.Write((ushort)objectGroup.ChildNodes.Count); foreach (XmlNode obj in objectGroup) { var objx = int.Parse(obj.Attributes["x"].Value); var objy = int.Parse(obj.Attributes["y"].Value); var polygon = obj["polygon"]; if (null != polygon) { var points = polygon.Attributes["points"].Value.Split(new char[] { ' ' }); writer.Write((ushort)points.Length); for (int i = 0; i < points.Length; i++) { writer.Write(Vector2.Parse(points[i]) + new Vector2(objx, objy)); } } else { writer.Write((ushort)0); } WriteProperties(writer, obj["properties"]); } } else { writer.Write((ushort)0); } } }