Exemplo n.º 1
0
        /// <summary>
        /// Initializes, Reads this Map's XML info
        /// </summary>
        /// <param name="document">NanoXMLDocument containing Map's XML</param>
        void ParseMapXML(NanoXMLDocument document)
        {
            MapNode = document.RootNode;
            Orientation orientation = (Orientation)Enum.Parse(typeof(Orientation), MapNode.GetAttribute("orientation").Value, true);
            int width = int.Parse(MapNode.GetAttribute("width").Value, CultureInfo.InvariantCulture);
            int height = int.Parse(MapNode.GetAttribute("height").Value, CultureInfo.InvariantCulture);
            int tileWidth = int.Parse(MapNode.GetAttribute("tilewidth").Value, CultureInfo.InvariantCulture);
            int tileHeight = int.Parse(MapNode.GetAttribute("tileheight").Value, CultureInfo.InvariantCulture);

            if (MapNode.GetAttribute("version") != null)
            {
                Version = MapNode.GetAttribute("version").Value;
            }
            else
                Version = string.Empty;

            RenderOrder mapRenderOrder = RenderOrder.Right_Down;

            if (MapNode.GetAttribute("renderorder") != null)
            {
                string renderOrder = MapNode.GetAttribute("renderorder").Value;
                mapRenderOrder = (RenderOrder)Enum.Parse(typeof(RenderOrder), renderOrder.Replace('-', '_'), true);
            }

            StaggerAxis mapStaggerAxis = StaggerAxis.Y;

            if (MapNode.GetAttribute("staggeraxis") != null)
            {
                string staggeraxis = MapNode.GetAttribute("staggeraxis").Value;
                mapStaggerAxis = (StaggerAxis)Enum.Parse(typeof(StaggerAxis), staggeraxis, true);
            }

            StaggerIndex mapStaggerIndex = StaggerIndex.Odd;

            if (MapNode.GetAttribute("staggerindex") != null)
            {
                string staggerindex = MapNode.GetAttribute("staggerindex").Value;
                mapStaggerIndex = (StaggerIndex)Enum.Parse(typeof(StaggerIndex), staggerindex, true);
            }

            int hexSideLength = 0;

            if (MapNode.GetAttribute("hexsidelength") != null)
            {
                hexSideLength = int.Parse(MapNode.GetAttribute("hexsidelength").Value, CultureInfo.InvariantCulture);
            }

            if (MapNode.GetAttribute("nextobjectid") != null)
            {
                NextObjectID = int.Parse(MapNode.GetAttribute("nextobjectid").Value, CultureInfo.InvariantCulture);
            }
            else
                NextObjectID = 0;

            Color32 backgroundColor = new Color32(128, 128, 128, 255);

            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);
                backgroundColor = new Color32(
                    (byte)Convert.ToInt32(r, 16),
                    (byte)Convert.ToInt32(g, 16),
                    (byte)Convert.ToInt32(b, 16),255);
            }

            MapRenderParameter = new MapRenderParameters(orientation, mapRenderOrder, mapStaggerAxis, mapStaggerIndex, width, height, tileWidth, tileHeight, hexSideLength, backgroundColor);

            if (_mapName == null)
                _mapName = "Map";

            if (!_mapPath.EndsWith(Path.AltDirectorySeparatorChar.ToString()))
                _mapPath = _mapPath + Path.AltDirectorySeparatorChar;

            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 = Utils.XUniTMXHelpers.ParsePath(_mapPath, node.GetAttribute("source").Value);

                            TextAsset externalTileSetTextAsset = Resources.Load<TextAsset>(path);

                            BuildExternalTileSet(externalTileSetTextAsset.text, Directory.GetParent(path).ToString(), firstID);
                        }
                    }
                    else
                    {
                        OnFinishedLoadingTileSet(new TileSet(node, _mapPath, this, UsingStreamingAssetsPath));
                    }
                }
            }
        }
        /// <summary>
        /// Scale this object's dimensions using map's tile size.
        /// We need to do this as Tiled saves object dimensions in Pixels, but we need to convert it to Unity's Unit
        /// </summary>
        /// <param name="mrp">The MapRenderParameters to which the object will be scaled</param>
        public static Object ScaleObject(this Object obj, MapRenderParameters mrp)
        {
            float x = 0, y = 0, width = 0, height = 0;
            switch (mrp.Orientation)
            {
                case Orientation.Isometric:
                    // In Isometric maps, we must consider tile width == height for objects so their size can be correctly calculated
                    return ScaleObjectHelper(obj, mrp.TileHeight, mrp.TileHeight);

                case Orientation.Staggered:
                    // In Staggered maps, we must pre-alter object position and size, as it comes mixed between staggered and orthogonal properties
                    x = obj.Bounds.x / (float)mrp.TileWidth;
                    y = obj.Bounds.y / (float)mrp.TileHeight * 2.0f;
                    width = obj.Bounds.width / (float)mrp.TileWidth;
                    height = obj.Bounds.height / (float)mrp.TileWidth;

                    if (mrp.MapStaggerAxis.Equals(StaggerAxis.Y))
                    {
                        if ((mrp.MapStaggerIndex.Equals(StaggerIndex.Odd) && Mathf.FloorToInt(Mathf.Abs(y)) % 2 > 0) ||
                            (mrp.MapStaggerIndex.Equals(StaggerIndex.Even) && Mathf.FloorToInt(Mathf.Abs(y)) % 2 < 1))
                            x -= 0.5f;
                    }
                    else
                    {
                        x *= 2;
                        y /= 2;
                        if ((mrp.MapStaggerIndex.Equals(StaggerIndex.Odd) && Mathf.FloorToInt(Mathf.Abs(x)) % 2 > 0) ||
                            (mrp.MapStaggerIndex.Equals(StaggerIndex.Even) && Mathf.FloorToInt(Mathf.Abs(x)) % 2 < 1))
                            y -= 0.5f;
                    }

                    obj.Bounds = new Rect(x, y, width, height);

                    if (obj.Points != null)
                    {
                        for (int i = 0; i < obj.Points.Count; i++)
                        {
                            obj.Points[i] = new Vector2(obj.Points[i].x / (float)mrp.TileWidth, obj.Points[i].y / (float)mrp.TileHeight * 2.0f);
                        }
                    }
                    return obj;

                case Orientation.Hexagonal:
                    // In Hexagonal maps, we must pre-alter object position and size, as it comes mixed between staggered and orthogonal properties
                    float halfGap = 1;
                    float tileDisplacement = 1;

                    if (mrp.MapStaggerAxis.Equals(StaggerAxis.Y))
                    {
                        halfGap = (mrp.TileHeight - mrp.HexSideLength) / 2.0f;
                        tileDisplacement = halfGap + mrp.HexSideLength;

                        x = obj.Bounds.x / mrp.TileWidth;
                        y = obj.Bounds.y / (tileDisplacement / (float)mrp.TileHeight) / (float)mrp.TileHeight;

                        if (InAStaggeredRowOrColumn(mrp.MapStaggerIndex, y))
                            x -= 0.5f;

                        if (obj.Points != null)
                        {
                            for (int i = 0; i < obj.Points.Count; i++)
                            {
                                obj.Points[i] = new Vector2(
                                    obj.Points[i].x / mrp.TileWidth,
                                    obj.Points[i].y / (tileDisplacement / (float)mrp.TileHeight) / (float)mrp.TileHeight
                                    );

                                if (InAStaggeredRowOrColumn(mrp.MapStaggerIndex, obj.Points[i].y))
                                    obj.Points[i] -= new Vector2(0.5f, 0);
                            }
                        }
                    }
                    else
                    {
                        halfGap = (mrp.TileWidth - mrp.HexSideLength) / 2.0f;
                        tileDisplacement = halfGap + mrp.HexSideLength;

                        x = obj.Bounds.x / tileDisplacement;
                        y = obj.Bounds.y / (mrp.TileHeight / (float)mrp.TileWidth) / (float)mrp.TileHeight;

                        if (InAStaggeredRowOrColumn(mrp.MapStaggerIndex, x))
                            y -= 0.5f * (mrp.TileHeight / (float)mrp.TileWidth);

                        if (obj.Points != null)
                        {
                            for (int i = 0; i < obj.Points.Count; i++)
                            {
                                obj.Points[i] = new Vector2(
                                    obj.Points[i].x / tileDisplacement,
                                    obj.Points[i].y / (mrp.TileHeight / (float)mrp.TileWidth) / (float)mrp.TileHeight
                                    );

                                if (InAStaggeredRowOrColumn(mrp.MapStaggerIndex, obj.Points[i].x))
                                    obj.Points[i] -= new Vector2(0, 0.5f * (mrp.TileHeight / (float)mrp.TileWidth));
                            }
                        }
                    }

                    width = obj.Bounds.width / (float)mrp.TileWidth;
                    height = obj.Bounds.height / (float)mrp.TileHeight;

                    obj.Bounds = new Rect(x, y, width, height);

                    return obj;

                default:
                    return ScaleObjectHelper(obj, mrp.TileWidth, mrp.TileHeight);
            }
        }