/// <summary> /// Creates a MapObject from node /// </summary> /// <param name="node">NanoXMLNode XML to parse</param> /// <param name="parentObjectLayer">This MapObject's MapObjectLayer parent</param> public MapObject(NanoXMLNode node, MapObjectLayer parentObjectLayer) : base(node) { if (node.GetAttribute("name") != null) { Name = node.GetAttribute("name").Value; } else { Name = "Object"; } if (node.GetAttribute("type") != null) { Type = node.GetAttribute("type").Value; } else Type = string.Empty; if (node.GetAttribute("visible") != null) { Visible = int.Parse(node.GetAttribute("visible").Value, CultureInfo.InvariantCulture) == 1; } else Visible = true; if (node.GetAttribute("gid") != null) GID = int.Parse(node.GetAttribute("gid").Value, CultureInfo.InvariantCulture); else GID = 0; ParentObjectLayer = parentObjectLayer; }
/// <summary> /// Only derived classes should use this constructor. Creates an Object from a XML node /// </summary> /// <param name="node">XML node to parse</param> protected Object(NanoXMLNode node) { if (node.GetAttribute("rotation") != null) { Rotation = 360 - float.Parse(node.GetAttribute("rotation").Value, CultureInfo.InvariantCulture); } else Rotation = 0; // values default to 0 if the attribute is missing from the node float x = node.GetAttribute("x") != null ? float.Parse(node.GetAttribute("x").Value, CultureInfo.InvariantCulture) : 0; float y = node.GetAttribute("y") != null ? float.Parse(node.GetAttribute("y").Value, CultureInfo.InvariantCulture) : 0; float width = node.GetAttribute("width") != null ? float.Parse(node.GetAttribute("width").Value, CultureInfo.InvariantCulture) : 1; float height = node.GetAttribute("height") != null ? float.Parse(node.GetAttribute("height").Value, CultureInfo.InvariantCulture) : 1; Bounds = new Rect(x, y, width, height); this.ObjectType = ObjectType.Box; // stores a string of points to parse out if this object is a polygon or polyline string pointsAsString = null; if (node["ellipse"] != null) { ObjectType = ObjectType.Ellipse; } // if there's a polygon node, it's a polygon object else if (node["polygon"] != null) { pointsAsString = node["polygon"].GetAttribute("points").Value; ObjectType = ObjectType.Polygon; } // if there's a polyline node, it's a polyline object else if (node["polyline"] != null) { pointsAsString = node["polyline"].GetAttribute("points").Value; ObjectType = ObjectType.Polyline; } // if we have some points to parse, we do that now if (pointsAsString != null) { // points are separated first by spaces Points = new List<Vector2>(); string[] pointPairs = pointsAsString.Split(' '); foreach (string p in pointPairs) { // then we split on commas string[] coords = p.Split(','); // then we parse the X/Y coordinates Points.Add(new Vector2( float.Parse(coords[0], CultureInfo.InvariantCulture), float.Parse(coords[1], CultureInfo.InvariantCulture))); } } }
/// <summary> /// Creates a Map Object Layer from node /// </summary> /// <param name="node">XML node to parse</param> /// <param name="tiledMap">MapObjectLayer parent Map</param> /// <param name="layerDepth">This Layer's zDepth</param> /// <param name="materials">List of Materials containing the TileSet textures</param> public MapObjectLayer(NanoXMLNode node, Map tiledMap, int layerDepth) : base(node, tiledMap) { if (node.GetAttribute("color") != null) { // get the color string, removing the leading # string color = node.GetAttribute("color").Value.Substring(1); // get the RGB individually string r = color.Substring(0, 2); string g = color.Substring(2, 2); string b = color.Substring(4, 2); // convert to the color Color = new Color( (byte)int.Parse(r, NumberStyles.AllowHexSpecifier), (byte)int.Parse(g, NumberStyles.AllowHexSpecifier), (byte)int.Parse(b, NumberStyles.AllowHexSpecifier)); } Objects = new List<MapObject>(); foreach (NanoXMLNode objectNode in node.SubNodes) { if (!objectNode.Name.Equals("object")) continue; MapObject mapObjectContent = new MapObject(objectNode, this); mapObjectContent = mapObjectContent.ScaleObject(tiledMap.MapRenderParameter) as MapObject; // Object names need to be unique for our lookup system, but Tiled // doesn't require unique names. string objectName = mapObjectContent.Name; int duplicateCount = 2; // if a object already has the same name... if (Objects.Find(o => o.Name.Equals(objectName)) != null) { // figure out a object name that does work do { objectName = string.Format("{0}{1}", mapObjectContent.Name, duplicateCount); duplicateCount++; } while (Objects.Find(o => o.Name.Equals(objectName)) != null); // log a warning for the user to see //Debug.LogWarning("Renaming object \"" + mapObjectContent.Name + "\" to \"" + objectName + "\" in layer \"" + Name + "\" to make a unique name."); // save that name mapObjectContent.Name = objectName; } //mapObjectContent.CreateTileObject(tiledMap, Name, layerDepth, materials); AddObject(mapObjectContent); } }
/// <summary> /// Initialize the Window /// </summary> /// <param name="objectLayerNode">NanoXMLNode of the MapObjectLayer from with MapObject will be read</param> public static void Init(NanoXMLNode objectLayerNode) { // Get existing open window or if none, make a new one: TiledMapObjectsWindow window = (TiledMapObjectsWindow)EditorWindow.GetWindow(typeof(TiledMapObjectsWindow)); _objectLayerNode = objectLayerNode; string name = objectLayerNode.GetAttribute("name") != null ? objectLayerNode.GetAttribute("name").Value : "ObjectLayer"; window.title = name; window.RebuildObjectsProperties(); }
/// <summary> /// Creates a Tile Layer from node /// </summary> /// <param name="node">XML node to parse</param> /// <param name="map">TileLayer parent Map</param> /// <param name="layerDepth">This Layer's zDepth</param> /// <param name="makeUnique">true to generate Unique Tiles</param> /// <param name="materials">List of Materials containing the TileSet textures</param> public TileLayer(NanoXMLNode node, Map map, int layerDepth, bool makeUnique, List<Material> materials) : base(node) { NanoXMLNode dataNode = node["data"]; Data = new uint[Width * Height]; LayerDepth = layerDepth; MakeUniqueTiles = makeUnique; // figure out what encoding is being used, if any, and process // the data appropriately if (dataNode.GetAttribute("encoding") != null) { string encoding = dataNode.GetAttribute("encoding").Value; if (encoding == "base64") { ReadAsBase64(dataNode); } else if (encoding == "csv") { ReadAsCsv(dataNode); } else { throw new Exception("Unknown encoding: " + encoding); } } else { // XML format simply lays out a lot of <tile gid="X" /> nodes inside of data. int i = 0; foreach (NanoXMLNode tileNode in dataNode.SubNodes) { if (tileNode.Name.Equals("tile")) { Data[i] = uint.Parse(tileNode.GetAttribute("gid").Value, CultureInfo.InvariantCulture); i++; } } if (i != Data.Length) throw new Exception("Not enough tile nodes to fill data"); } Initialize(map, Data, materials); }
/// <summary> /// Creates an Image Layer from node /// </summary> /// <param name="node">XML node to parse</param> /// <param name="map">ImageLayer parent Map</param> /// <param name="mapPath">Map's directory path</param> /// <param name="baseMaterial">Material to use on this SpriteRenderer</param> public ImageLayer(NanoXMLNode node, Map map, string mapPath) : base(node, map) { NanoXMLNode imageNode = node["image"]; this.Image = imageNode.GetAttribute("source").Value; if (node.GetAttribute("x") != null) { Position.x = float.Parse(node.GetAttribute("x").Value, NumberStyles.Float) / (float)map.MapRenderParameter.TileWidth; } if (node.GetAttribute("y") != null) { Position.y = -float.Parse(node.GetAttribute("y").Value, NumberStyles.Float) / (float)map.MapRenderParameter.TileHeight; } // if the image is in any director up from us, just take the filename //if (this.Image.StartsWith("..")) // this.Image = Path.GetFileName(this.Image); if (imageNode.GetAttribute("trans") != null) { string color = imageNode.GetAttribute("trans").Value; string r = color.Substring(0, 2); string g = color.Substring(2, 2); string b = color.Substring(4, 2); this.ColorKey = new Color((byte)Convert.ToInt32(r, 16), (byte)Convert.ToInt32(g, 16), (byte)Convert.ToInt32(b, 16)); } SortingOrder = map.DefaultSortingOrder - LayerDepth; _ppu = map.MapRenderParameter.TileWidth; useWWWToLoad = map.UsingStreamingAssetsPath; string texturePath = mapPath; if (!useWWWToLoad) { texturePath = Utils.XUniTMXHelpers.ParsePath(mapPath, Image); } else { if (!texturePath.Contains("://")) texturePath = "file://" + texturePath + Path.GetFileName(this.Image); } Image = texturePath; }
/// <summary> /// Public constructor. Loads xml document from raw string /// </summary> /// <param name="xmlString">String with xml</param> public NanoXMLDocument(string xmlString) { int i = 0; while (true) { SkipSpaces(xmlString, ref i); char thing = xmlString[i]; if (xmlString[i] != '<') { throw new XMLParsingException("Unexpected token"); } i++; // skip < if (xmlString[i] == '?') // declaration { i++; // skip ? ParseAttributes(xmlString, ref i, declarations, '?', '>'); i++; // skip ending ? i++; // skip ending > continue; } if (xmlString[i] == '!') // doctype { while (xmlString[i] != '>') // skip doctype { i++; } i++; // skip > continue; } rootNode = new NanoXMLNode(xmlString, ref i); break; } }
protected Layer(NanoXMLNode node) { //string Type = node.Name; Name = node.GetAttribute("name").Value; if (string.IsNullOrEmpty(Name)) Name = "Layer"; if (node.GetAttribute("width") != null) Width = int.Parse(node.GetAttribute("width").Value, CultureInfo.InvariantCulture); else Width = 0; if (node.GetAttribute("height") != null) Height = int.Parse(node.GetAttribute("height").Value, CultureInfo.InvariantCulture); else Height = 0; if (node.GetAttribute("opacity") != null) { Opacity = float.Parse(node.GetAttribute("opacity").Value, CultureInfo.InvariantCulture); } else Opacity = 1; if (node.GetAttribute("visible") != null) { Visible = int.Parse(node.GetAttribute("visible").Value, CultureInfo.InvariantCulture) == 1; } else Visible = true; NanoXMLNode propertiesNode = node["properties"]; if (propertiesNode != null) { Properties = new PropertyCollection(propertiesNode); } LayerGameObject = new GameObject(Name); }
/// <summary> /// Public constructor. Loads xml document from raw string /// </summary> /// <param name="xmlString">String with xml</param> public NanoXMLDocument(string xmlString) { int i = 0; while (true) { SkipSpaces(xmlString, ref i); if (xmlString[i] != '<') throw new XMLParsingException("Unexpected token"); i++; // skip < if (xmlString[i] == '?') // declaration { i++; // skip ? ParseAttributes(xmlString, ref i, declarations, '?', '>'); i++; // skip ending ? i++; // skip ending > continue; } if (xmlString[i] == '!') // doctype { while (xmlString[i] != '>') // skip doctype i++; i++; // skip > continue; } rootNode = new NanoXMLNode(xmlString, ref i); break; } }
void ShowObjectsWindow(NanoXMLNode objectLayerNode) { TiledMapObjectsWindow.Init(objectLayerNode); }
/// <summary> /// Initializes, Reads this Map's info /// </summary> /// <param name="document">NanoXMLDocument containing Map's XML</param> void Initialize(NanoXMLDocument document) { MapNode = document.RootNode; Orientation = (Orientation)Enum.Parse(typeof(Orientation), MapNode.GetAttribute("orientation").Value, true); Width = int.Parse(MapNode.GetAttribute("width").Value, CultureInfo.InvariantCulture); Height = int.Parse(MapNode.GetAttribute("height").Value, CultureInfo.InvariantCulture); TileWidth = int.Parse(MapNode.GetAttribute("tilewidth").Value, CultureInfo.InvariantCulture); TileHeight = int.Parse(MapNode.GetAttribute("tileheight").Value, CultureInfo.InvariantCulture); if (MapNode.GetAttribute("version") != null) { Version = MapNode.GetAttribute("version").Value; } else Version = string.Empty; if (MapNode.GetAttribute("renderorder") != null) { string renderOrder = MapNode.GetAttribute("renderorder").Value; MapRenderOrder = (RenderOrder)Enum.Parse(typeof(RenderOrder), renderOrder.Replace('-', '_'), true); } else MapRenderOrder = RenderOrder.Right_Down; if (MapNode.GetAttribute("backgroundcolor") != null) { string color = MapNode.GetAttribute("backgroundcolor").Value; string r = color.Substring(1, 2); string g = color.Substring(3, 2); string b = color.Substring(5, 2); this.BackgroundColor = new Color( (byte)Convert.ToInt32(r, 16), (byte)Convert.ToInt32(g, 16), (byte)Convert.ToInt32(b, 16)); } if (_mapName == null) _mapName = "Map"; if (!_mapPath.EndsWith(Path.AltDirectorySeparatorChar.ToString())) _mapPath = _mapPath + Path.AltDirectorySeparatorChar; MapObject = new GameObject(_mapName); Transform mapObjectTransform = MapObject.transform; mapObjectTransform.parent = Parent.transform; mapObjectTransform.localPosition = Vector3.zero; MapObject.layer = mapObjectTransform.parent.gameObject.layer; NanoXMLNode propertiesElement = MapNode["properties"]; if (propertiesElement != null) Properties = new PropertyCollection(propertiesElement); TileSets = new List<TileSet>(); Tiles = new Dictionary<int, Tile>(); _tileSetsToLoaded = 0; _numberOfTileSetsToLoad = 0; // First get how many tilesets we need to load foreach (NanoXMLNode node in MapNode.SubNodes) { if (node.Name.Equals("tileset")) _numberOfTileSetsToLoad++; } // Maps might not have any tileset, being just a tool for object placement :P if (_numberOfTileSetsToLoad < 1) { ContinueLoadingTiledMapAfterTileSetsLoaded(); } // Then load all of them. After all loaded, continue with map loading foreach (NanoXMLNode node in MapNode.SubNodes) { if (node.Name.Equals("tileset")) { if (node.GetAttribute("source") != null) { int firstID = int.Parse(node.GetAttribute("firstgid").Value, CultureInfo.InvariantCulture); if (UsingStreamingAssetsPath) { // Run coroutine for www using TaskManager new Task(LoadExternalTileSet(node, _mapPath, firstID), true); } else { // Parse the path string path = node.GetAttribute("source").Value; string rootPath = Directory.GetParent(_mapPath).FullName; string appPath = Path.GetFullPath(Application.dataPath.Replace("/Assets", "")); while (path.StartsWith("../")) { rootPath = Directory.GetParent(rootPath).FullName; path = path.Remove(0, 3); } rootPath = rootPath.Replace(appPath + Path.DirectorySeparatorChar, ""); path = Path.GetDirectoryName(path) + Path.AltDirectorySeparatorChar + Path.GetFileNameWithoutExtension(path); if (path.StartsWith("/")) path = path.Remove(0, 1); rootPath = rootPath.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); if (rootPath.Length > 0) rootPath += Path.AltDirectorySeparatorChar; path = rootPath + path; //path = path.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); TextAsset externalTileSetTextAsset = Resources.Load<TextAsset>(path); BuildExternalTileSet(externalTileSetTextAsset.text, Directory.GetParent(path).ToString(), firstID); } } else { new TileSet(node, _mapPath, this, UsingStreamingAssetsPath, OnFinishedLoadingTileSet); } } } }
/// <summary> /// Load this TileSet's information from node and builds its tiles /// </summary> /// <param name="node">NanoXMLNode to parse</param> /// <param name="mapPath">Map's directory</param> /// <param name="map">Reference to the Map this TileSet is in</param> /// <param name="isUsingStreamingPath">true if is using StreamingAssets path or HTTP URL (WWW)</param> /// <param name="onFinishedGeneratingTileSet">Delegate to call when this TileSet finishes loading</param> /// <param name="firstID">First ID is a per-Map property, so External TileSets won't have this info in the node</param> public TileSet(NanoXMLNode node, string mapPath, Map map, bool isUsingStreamingPath = false, int firstID = 1) : this(node, map, firstID) { _useWWWToLoad = isUsingStreamingPath; // Build tiles from this tileset string[] texturePath = new string[TileSetImages.Count];//mapPath; for (int i = 0; i < texturePath.Length; i++) { if (_useWWWToLoad) { texturePath[i] = string.Concat(mapPath, TileSetImages[i].Image); if (!texturePath[i].Contains("://")) texturePath[i] = string.Concat("file://", texturePath[i]); } else { texturePath[i] = Utils.XUniTMXHelpers.ParsePath(mapPath, TileSetImages[i].Image); } TileSetImages[i].Image = texturePath[i]; } }
/// <summary> /// Load this TileSet's information from node /// </summary> /// <param name="node">NanoXMLNode to parse</param> /// <param name="map">Reference to the Map this TileSet is in</param> /// <param name="firstGID">First ID is a per-Map property, so External TileSets won't have this info in the node</param> protected TileSet(NanoXMLNode node, Map map, int firstGID = 1) { if (node.GetAttribute("firstgid") == null || !int.TryParse(node.GetAttribute("firstgid").Value, out FirstId)) FirstId = firstGID; //this.FirstId = int.Parse(node.GetAttribute("firstgid").Value, CultureInfo.InvariantCulture); this.Name = node.GetAttribute("name").Value; this.TileWidth = int.Parse(node.GetAttribute("tilewidth").Value, CultureInfo.InvariantCulture); this.TileHeight = int.Parse(node.GetAttribute("tileheight").Value, CultureInfo.InvariantCulture); if (node.GetAttribute("spacing") != null) { this.Spacing = int.Parse(node.GetAttribute("spacing").Value, CultureInfo.InvariantCulture); } if (node.GetAttribute("margin") != null) { this.Margin = int.Parse(node.GetAttribute("margin").Value, CultureInfo.InvariantCulture); } NanoXMLNode tileOffset = node["tileoffset"]; if (tileOffset != null) { this.TileOffsetX = int.Parse(tileOffset.GetAttribute("x").Value, CultureInfo.InvariantCulture); this.TileOffsetY = -int.Parse(tileOffset.GetAttribute("y").Value, CultureInfo.InvariantCulture); } NanoXMLNode imageNode = node["image"]; this.Image = imageNode.GetAttribute("source").Value; // if the image is in any director up from us, just take the filename //if (this.Image.StartsWith("..")) // this.Image = Path.GetFileName(this.Image); if (imageNode.GetAttribute("trans") != null) { string color = imageNode.GetAttribute("trans").Value; string r = color.Substring(0, 2); string g = color.Substring(2, 2); string b = color.Substring(4, 2); this.ColorKey = new Color((byte)Convert.ToInt32(r, 16), (byte)Convert.ToInt32(g, 16), (byte)Convert.ToInt32(b, 16)); } foreach (NanoXMLNode subNode in node.SubNodes) { if (subNode.Name.Equals("tile")) { int id = this.FirstId + int.Parse(subNode.GetAttribute("id").Value, CultureInfo.InvariantCulture); // Load Tile Properties, if any NanoXMLNode propertiesNode = subNode["properties"]; if (propertiesNode != null) { PropertyCollection properties = new PropertyCollection(propertiesNode);//Property.ReadProperties(propertiesNode); this.TileProperties.Add(id, properties); } // Load Tile Animation, if any NanoXMLNode animationNode = subNode["animation"]; if (animationNode != null) { TileAnimation _tileAnimation = new TileAnimation(); foreach (NanoXMLNode frame in animationNode.SubNodes) { if (!frame.Name.Equals("frame")) continue; int tileid = int.Parse(frame.GetAttribute("tileid").Value, CultureInfo.InvariantCulture) + FirstId; int duration = int.Parse(frame.GetAttribute("duration").Value, CultureInfo.InvariantCulture); _tileAnimation.AddTileFrame(tileid, duration); } this.AnimatedTiles.Add(id, _tileAnimation); } // Load Tile Objects, if any NanoXMLNode objectsNode = subNode["objectgroup"]; if (objectsNode != null) { List<TileObject> tileObjects = new List<TileObject>(); foreach (NanoXMLNode tileObjNode in objectsNode.SubNodes) { TileObject tObj = new TileObject(tileObjNode); tObj.ScaleObject(map.TileWidth, map.TileHeight, map.Orientation); tileObjects.Add(tObj); } // There's a bug in Tiled 0.10.1- where the objectgroup node won't go away even if you delete all objects from a tile's collision group. if(tileObjects.Count > 0) TilesObjects.Add(id, tileObjects); } } } }
/// <summary> /// Load this TileSet's information from node and builds its tiles /// </summary> /// <param name="node">NanoXMLNode to parse</param> /// <param name="mapPath">Map's directory</param> /// <param name="map">Reference to the Map this TileSet is in</param> /// <param name="isUsingStreamingPath">true if is using StreamingAssets path or HTTP URL (WWW)</param> /// <param name="onFinishedLoadingTileSet">Delegate to call when this TileSet finishes loading</param> /// <param name="firstID">First ID is a per-Map property, so External TileSets won't have this info in the node</param> public TileSet(NanoXMLNode node, string mapPath, Map map, bool isUsingStreamingPath = false, Action<TileSet> onFinishedLoadingTileSet = null, int firstID = 1) : this(node, map, firstID) { // Build tiles from this tileset string texturePath = mapPath; // Parse the path if (Image.StartsWith("../")) { string path = Image; string rootPath = mapPath; string appPath = Path.GetFullPath(Application.dataPath.Replace("/Assets", "")); while (path.StartsWith("../")) { rootPath = Directory.GetParent(rootPath).FullName; path = path.Remove(0, 3); } rootPath = rootPath.Replace(appPath + Path.DirectorySeparatorChar, ""); path = Path.GetDirectoryName(path) + Path.AltDirectorySeparatorChar + Path.GetFileNameWithoutExtension(path); if (path.StartsWith("/")) path = path.Remove(0, 1); rootPath = rootPath.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); if (rootPath.Length > 0) rootPath += Path.AltDirectorySeparatorChar; texturePath = string.Concat(rootPath, path); } else if (!Application.isWebPlayer) { if (!texturePath.EndsWith(Path.AltDirectorySeparatorChar.ToString(), StringComparison.InvariantCultureIgnoreCase)) texturePath += Path.AltDirectorySeparatorChar; if (texturePath.Equals("/")) texturePath = ""; if (Path.GetDirectoryName(this.Image).Length > 0) texturePath += Path.GetDirectoryName(this.Image) + Path.AltDirectorySeparatorChar; if (texturePath.Equals("/")) texturePath = ""; texturePath = string.Concat(texturePath, Path.GetFileNameWithoutExtension(this.Image)); } else { texturePath = Path.Combine(mapPath, Path.GetFileName(this.Image)); } OnFinishedLoadingTileSet = onFinishedLoadingTileSet; //Debug.Log(texturePath); if (!isUsingStreamingPath) { //texturePath = string.Concat(texturePath, Path.GetExtension(this.Image)); this.Texture = Resources.Load<Texture2D>(texturePath); BuildTiles(map.TileWidth); } else { texturePath = string.Concat(texturePath, Path.GetExtension(this.Image)); if (!texturePath.Contains("://")) texturePath = string.Concat("file://", texturePath); //Debug.Log(texturePath); // Run Coroutine for WWW using TaskManager. new X_UniTMX.Utils.Task(LoadTileSetTexture(texturePath, map.TileWidth), true); } }
private void ReadAsBase64(NanoXMLNode dataNode) { // get a stream to the decoded Base64 text Stream data = new MemoryStream(Convert.FromBase64String(dataNode.Value), false); // figure out what, if any, compression we're using. the compression determines // if we need to wrap our data stream in a decompression stream if (dataNode.GetAttribute("compression") != null) { string compression = dataNode.GetAttribute("compression").Value; if (compression == "gzip") { data = new Ionic.Zlib.GZipStream(data, Ionic.Zlib.CompressionMode.Decompress, false); } else if (compression == "zlib") { data = new Ionic.Zlib.ZlibStream(data, Ionic.Zlib.CompressionMode.Decompress, false); } else { throw new InvalidOperationException("Unknown compression: " + compression); } } // simply read in all the integers using (data) { using (BinaryReader reader = new BinaryReader(data)) { for (int i = 0; i < Data.Length; i++) { Data[i] = reader.ReadUInt32(); } } } }
/// <summary> /// Load this TileSet's information from node /// </summary> /// <param name="node">NanoXMLNode to parse</param> /// <param name="map">Reference to the Map this TileSet is in</param> /// <param name="firstGID">First ID is a per-Map property, so External TileSets won't have this info in the node</param> protected TileSet(NanoXMLNode node, Map map, int firstGID = 1) { if (node.GetAttribute("firstgid") == null || !int.TryParse(node.GetAttribute("firstgid").Value, out FirstId)) FirstId = firstGID; //this.FirstId = int.Parse(node.GetAttribute("firstgid").Value, CultureInfo.InvariantCulture); this.Name = node.GetAttribute("name").Value; this.TileWidth = int.Parse(node.GetAttribute("tilewidth").Value, CultureInfo.InvariantCulture); this.TileHeight = int.Parse(node.GetAttribute("tileheight").Value, CultureInfo.InvariantCulture); if (node.GetAttribute("spacing") != null) { this.Spacing = int.Parse(node.GetAttribute("spacing").Value, CultureInfo.InvariantCulture); } if (node.GetAttribute("margin") != null) { this.Margin = int.Parse(node.GetAttribute("margin").Value, CultureInfo.InvariantCulture); } NanoXMLNode tileOffset = node["tileoffset"]; if (tileOffset != null) { this.TileOffsetX = int.Parse(tileOffset.GetAttribute("x").Value, CultureInfo.InvariantCulture); this.TileOffsetY = -int.Parse(tileOffset.GetAttribute("y").Value, CultureInfo.InvariantCulture); } AddTileSetImage(node["image"]); _mapTileWidth = map.MapRenderParameter.TileWidth; _mapTileHeight = map.MapRenderParameter.TileHeight; foreach (NanoXMLNode subNode in node.SubNodes) { if (subNode.Name.Equals("tile")) { int id = this.FirstId + int.Parse(subNode.GetAttribute("id").Value, CultureInfo.InvariantCulture); // Load Tile Properties, if any NanoXMLNode propertiesNode = subNode["properties"]; if (propertiesNode != null) { PropertyCollection properties = new PropertyCollection(propertiesNode);//Property.ReadProperties(propertiesNode); this.TileProperties.Add(id, properties); } // Load Tile Animation, if any NanoXMLNode animationNode = subNode["animation"]; if (animationNode != null) { TileAnimation _tileAnimation = new TileAnimation(); foreach (NanoXMLNode frame in animationNode.SubNodes) { if (!frame.Name.Equals("frame")) continue; int tileid = int.Parse(frame.GetAttribute("tileid").Value, CultureInfo.InvariantCulture) + FirstId; int duration = int.Parse(frame.GetAttribute("duration").Value, CultureInfo.InvariantCulture); _tileAnimation.AddTileFrame(tileid, duration); } this.AnimatedTiles.Add(id, _tileAnimation); } // Load Tile Objects, if any NanoXMLNode objectsNode = subNode["objectgroup"]; List<TileObject> tileObjects = null; if (objectsNode != null) { tileObjects = new List<TileObject>(); foreach (NanoXMLNode tileObjNode in objectsNode.SubNodes) { TileObject tObj = new TileObject(tileObjNode, _mapTileWidth, _mapTileHeight); //tObj.ScaleObject(map.TileWidth, map.TileHeight, map.Orientation); tObj = tObj.ScaleObject(map.MapRenderParameter) as TileObject; tileObjects.Add(tObj); } // There's a bug in Tiled 0.10.1- where the objectgroup node won't go away even if you delete all objects from a tile's collision group. if(tileObjects.Count > 0) TilesObjects.Add(id, tileObjects); } // Load Tile Image, if this is an ImageCollection TileSet AddTileSetImage(subNode["image"], tileObjects); } } }
private void ReadAsCsv(NanoXMLNode dataNode) { // split the text up into lines string[] lines = dataNode.Value.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries); // iterate each line for (int i = 0; i < lines.Length; i++) { // split the line into individual pieces string[] indices = lines[i].Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); // iterate the indices and store in our data for (int j = 0; j < indices.Length; j++) { Data[i * Width + j] = uint.Parse(indices[j], CultureInfo.InvariantCulture); } } }
void AddTileSetImage(NanoXMLNode imageNode, List<TileObject> tileObjects = null) { if (imageNode == null) return; TileSetImage tsi = new TileSetImage(); tsi.FullPath = tsi.Image = imageNode.GetAttribute("source").Value; if(imageNode.GetAttribute("width") != null) tsi.Width = int.Parse(imageNode.GetAttribute("width").Value, CultureInfo.InvariantCulture); if (imageNode.GetAttribute("height") != null) tsi.Height = int.Parse(imageNode.GetAttribute("height").Value, CultureInfo.InvariantCulture); if (imageNode.GetAttribute("trans") != null) { string color = imageNode.GetAttribute("trans").Value; string r = color.Substring(0, 2); string g = color.Substring(2, 2); string b = color.Substring(4, 2); tsi.ColorKey = new Color((byte)Convert.ToInt32(r, 16), (byte)Convert.ToInt32(g, 16), (byte)Convert.ToInt32(b, 16)); } // alter the tile objects, if any, to use this image's width and height as its TileWidth and TileHeight values // used for ImageCollections, where tiles can be of different sizes inside the same tileset if (tileObjects != null) { for (int i = 0; i < tileObjects.Count; i++) { tileObjects[i].TileWidth = tsi.Width; tileObjects[i].TileHeight = tsi.Height; } } TileSetImages.Add(tsi); }
/// <summary> /// Creates a TileObject from node /// </summary> /// <param name="node">XML node to parse</param> public TileObject(NanoXMLNode node, int tileWidth, int tileHeight) : base(node) { TileWidth = tileWidth; TileHeight = tileHeight; }
/// <summary> /// Creates a TileObject from node /// </summary> /// <param name="node">XML node to parse</param> public TileObject(NanoXMLNode node) : base(node) { }
/// <summary> /// Load an external TileSet /// </summary> /// <param name="node">TileSet's NanoXMLNode</param> /// <param name="mapPath">Map's root directory</param> /// <param name="firstID">TileSet's firstID (external TileSet does not save this info)</param> /// <returns>is loaded or not</returns> IEnumerator LoadExternalTileSet(NanoXMLNode node, string mapPath, int firstID = 1) { string externalTileSetData = node.GetAttribute("source").Value; string filePath = mapPath; if (Application.isWebPlayer) { filePath = Path.Combine(filePath, Path.GetFileName(externalTileSetData)); } else { if (Path.GetDirectoryName(externalTileSetData).Length > 0) filePath += Path.GetDirectoryName(externalTileSetData) + Path.AltDirectorySeparatorChar; if (filePath.Equals("/")) filePath = ""; // if there's no :// assume we are using StreamingAssets path if (!filePath.Contains("://")) filePath = string.Concat("file://", Path.Combine(filePath, Path.GetFileName(externalTileSetData))); } WWW www = new WWW(filePath); yield return www; externalTileSetData = www.text; BuildExternalTileSet(externalTileSetData, mapPath, firstID); }
/// <summary> /// Creates an Image Layer from node /// </summary> /// <param name="node">XML node to parse</param> /// <param name="map">ImageLayer parent Map</param> /// <param name="mapPath">Map's directory path</param> /// <param name="baseMaterial">Material to use on this SpriteRenderer</param> public ImageLayer(NanoXMLNode node, Map map, string mapPath, Material baseMaterial) : base(node) { NanoXMLNode imageNode = node["image"]; this.Image = imageNode.GetAttribute("source").Value; if (node.GetAttribute("x") != null) { Position.x = float.Parse(node.GetAttribute("x").Value, NumberStyles.Float) / (float)map.TileWidth; } if (node.GetAttribute("y") != null) { Position.y = -float.Parse(node.GetAttribute("y").Value, NumberStyles.Float) / (float)map.TileHeight; } // if the image is in any director up from us, just take the filename //if (this.Image.StartsWith("..")) // this.Image = Path.GetFileName(this.Image); if (imageNode.GetAttribute("trans") != null) { string color = imageNode.GetAttribute("trans").Value; string r = color.Substring(0, 2); string g = color.Substring(2, 2); string b = color.Substring(4, 2); this.ColorKey = new Color((byte)Convert.ToInt32(r, 16), (byte)Convert.ToInt32(g, 16), (byte)Convert.ToInt32(b, 16)); } SortingOrder = map.DefaultSortingOrder - LayerDepth; Parent = map.MapObject.transform; TileWidth = map.TileWidth; string texturePath = mapPath; if (!map.UsingStreamingAssetsPath) { // Parse the path if (Image.StartsWith("../")) { string path = Image; string rootPath = Directory.GetParent(mapPath).FullName; string appPath = Path.GetFullPath(Application.dataPath.Replace("/Assets", "")); while (path.StartsWith("../")) { rootPath = Directory.GetParent(rootPath).FullName; path = path.Remove(0, 3); } rootPath = rootPath.Replace(appPath, ""); path = Path.GetDirectoryName(path) + Path.AltDirectorySeparatorChar + Path.GetFileNameWithoutExtension(path); if (path.StartsWith("/")) path = path.Remove(0, 1); rootPath = rootPath.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); if (rootPath.Length > 0) rootPath += Path.AltDirectorySeparatorChar; texturePath = rootPath + path; } else { if (Path.GetDirectoryName(this.Image).Length > 0) texturePath += Path.GetDirectoryName(this.Image) + Path.AltDirectorySeparatorChar; texturePath += Path.GetFileNameWithoutExtension(this.Image); } this.Texture = Resources.Load<Texture2D>(texturePath); BuildGameObject(); } else { if (!texturePath.Contains("://")) texturePath = "file://" + texturePath + Path.GetFileName(this.Image); // Run Coroutine for WWW using TaskManager. new X_UniTMX.Utils.Task(LoadImageTexture(texturePath), true); } }