Beispiel #1
0
 internal MapObjectLayer(string name, int width, int height, bool visible, float opacity, PropertyCollection properties, IList <MapObject> objects)
     : base(name, width, height, visible, opacity, properties)
 {
     Objects = new ReadOnlyCollection <MapObject>(objects);
     foreach (var o in objects)
     {
         string oname = o.Name;
         if (namedObjects.ContainsKey(o.Name))
         {
             oname += "-" + Guid.NewGuid();
         }
         namedObjects.Add(oname, o);
     }
 }
Beispiel #2
0
        public MapContent(XmlDocument document, ContentImporterContext context)
        {
            XmlNode mapNode = document["map"];

            Version     = mapNode.Attributes["version"].Value;
            Orientation = (Orientation)Enum.Parse(typeof(Orientation), mapNode.Attributes["orientation"].Value, true);
            Width       = int.Parse(mapNode.Attributes["width"].Value, CultureInfo.InvariantCulture);
            Height      = int.Parse(mapNode.Attributes["height"].Value, CultureInfo.InvariantCulture);
            TileWidth   = int.Parse(mapNode.Attributes["tilewidth"].Value, CultureInfo.InvariantCulture);
            TileHeight  = int.Parse(mapNode.Attributes["tileheight"].Value, CultureInfo.InvariantCulture);

            XmlNode propertiesNode = document.SelectSingleNode("map/properties");

            if (propertiesNode != null)
            {
                Properties = new PropertyCollection(propertiesNode, context);
            }

            foreach (XmlNode tileSet in document.SelectNodes("map/tileset"))
            {
                if (tileSet.Attributes["source"] != null)
                {
                    TileSets.Add(new ExternalTileSetContent(tileSet, context));
                }
                else
                {
                    TileSets.Add(new TileSetContent(tileSet, context));
                }
            }

            foreach (XmlNode layerNode in document.SelectNodes("map/layer|map/objectgroup"))
            {
                LayerContent layerContent;

                if (layerNode.Name == "layer")
                {
                    layerContent = new TileLayerContent(layerNode, context);
                }
                else if (layerNode.Name == "objectgroup")
                {
                    layerContent = new MapObjectLayerContent(layerNode, context);
                }
                else
                {
                    throw new Exception("Unknown layer name: " + layerNode.Name);
                }

                // Layer names need to be unique for our lookup system, but Tiled
                // doesn't require unique names.
                string layerName      = layerContent.Name;
                int    duplicateCount = 2;

                // if a layer already has the same name...
                if (Layers.Find(l => l.Name == layerName) != null)
                {
                    // figure out a layer name that does work
                    do
                    {
                        layerName = string.Format("{0}{1}", layerContent.Name, duplicateCount);
                        duplicateCount++;
                    } while (Layers.Find(l => l.Name == layerName) != null);

                    // log a warning for the user to see
                    context.Logger.LogWarning(string.Empty, new ContentIdentity(), "Renaming layer \"{1}\" to \"{2}\" to make a unique name.", layerContent.Type, layerContent.Name, layerName);

                    // save that name
                    layerContent.Name = layerName;
                }

                Layers.Add(layerContent);
            }
        }
Beispiel #3
0
        internal TileLayer(string name, int width, int height, float layerDepth, bool visible, float opacity, PropertyCollection properties, Map map, uint[] data, bool makeUnique)
            : base(name, width, height, layerDepth, visible, opacity, properties)
        {
            Tiles = new TileGrid(width, height);

            // data is left-to-right, top-to-bottom
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    uint index = data[y * width + x];

                    // compute the SpriteEffects to apply to this tile
                    SpriteEffects spriteEffects = SpriteEffects.None;
                    if ((index & FlippedHorizontallyFlag) != 0)
                    {
                        spriteEffects |= SpriteEffects.FlipHorizontally;
                    }
                    if ((index & FlippedVerticallyFlag) != 0)
                    {
                        spriteEffects |= SpriteEffects.FlipVertically;
                    }

                    // strip out the flip flags to get the real ID
                    int id = (int)(index & ~(FlippedVerticallyFlag | FlippedHorizontallyFlag));

                    // get the tile
                    Tile t = map.Tiles[id];

                    // if the tile is non-null...
                    if (t != null)
                    {
                        // if we want unique instances, clone it
                        if (makeUnique)
                        {
                            t = t.Clone();
                            t.SpriteEffects = spriteEffects;
                        }

                        // otherwise we may need to clone if the tile doesn't have the correct effects
                        // in this world a flipped tile is different than a non-flipped one; just because
                        // they have the same source rect doesn't mean they're equal.
                        else if (t.SpriteEffects != spriteEffects)
                        {
                            t = t.Clone();
                            t.SpriteEffects = spriteEffects;
                        }
                    }

                    // put that tile in our grid
                    Tiles[x, y] = t;
                }
            }
        }
 internal MapObjectLayer(string name, int width, int height, float layerDepth, bool visible, float opacity, PropertyCollection properties, List <MapObject> initialObjects)
     : base(name, width, height, layerDepth, visible, opacity, properties)
 {
     Objects = new ReadOnlyCollection <MapObject>(objects);
     initialObjects.ForEach(AddObject);
 }
Beispiel #5
0
        public MapObjectContent(XmlNode node, ContentImporterContext context)
        {
            // get the object's name and type
            if (node.Attributes["name"] != null)
            {
                Name = node.Attributes["name"].Value;
            }
            if (node.Attributes["type"] != null)
            {
                Type = node.Attributes["type"].Value;
            }

            // read the object properties
            if (node["properties"] != null)
            {
                Properties = new PropertyCollection(node["properties"], context);
            }

            // parse out the bounds of the object. values default to 0 if the attribute is missing from the node.
            int x = node.Attributes["x"] != null?int.Parse(node.Attributes["x"].Value, CultureInfo.InvariantCulture) : 0;

            int y = node.Attributes["y"] != null?int.Parse(node.Attributes["y"].Value, CultureInfo.InvariantCulture) : 0;

            int width = node.Attributes["width"] != null?int.Parse(node.Attributes["width"].Value, CultureInfo.InvariantCulture) : 0;

            int height = node.Attributes["height"] != null?int.Parse(node.Attributes["height"].Value, CultureInfo.InvariantCulture) : 0;

            Bounds = new Rectangle(x, y, width, height);

            // stores a string of points to parse out if this object is a polygon or polyline
            string pointsAsString = null;

            // if there's a GID, it's a tile object
            if (node.Attributes["gid"] != null)
            {
                ObjectType = MapObjectType.Tile;
                GID        = int.Parse(node.Attributes["gid"].Value, CultureInfo.InvariantCulture);
            }
            // if there's a polygon node, it's a polygon object
            else if (node["polygon"] != null)
            {
                ObjectType     = MapObjectType.Polygon;
                pointsAsString = node["polygon"].Attributes["points"].Value;
            }
            // if there's a polyline node, it's a polyline object
            else if (node["polyline"] != null)
            {
                ObjectType     = MapObjectType.Polyline;
                pointsAsString = node["polyline"].Attributes["points"].Value;
            }

            // if we have some points to parse, we do that now
            if (pointsAsString != null)
            {
                // points are separated first by spaces
                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)));
                }
            }
        }
Beispiel #6
0
        //private Layer collisionLayer;

        internal Map(ContentReader reader)
        {
            // read in the basic map information
            Version     = new Version(reader.ReadString());
            Orientation = (Orientation)reader.ReadByte();
            Width       = reader.ReadInt32();
            Height      = reader.ReadInt32();
            TileWidth   = reader.ReadInt32();
            TileHeight  = reader.ReadInt32();
            Properties  = new PropertyCollection();
            Properties.Read(reader);

            // create a list for our tiles
            List <Tile> tiles = new List <Tile>();

            Tiles = new Collection <Tile>(tiles);

            // read in each tile set
            int numTileSets = reader.ReadInt32();

            for (int i = 0; i < numTileSets; i++)
            {
                // get the id and texture
                int    firstId      = reader.ReadInt32();
                string tilesetName  = reader.ReadString();
                bool   collisionSet = reader.ReadBoolean();

                Texture2D texture      = reader.ReadExternalReference <Texture2D>();
                Texture2D whiteTexture = null;// reader.ReadExternalReference<Texture2D>();

                // Read in color data for collision purposes
                // You'll probably want to limit this to just the tilesets that are used for collision
                // I'm checking for the name of my tileset that contains wall tiles
                // Color data takes up a fair bit of RAM
                Color[] collisionData    = null;
                bool[]  collisionBitData = null;
                if (collisionSet)
                {
                    collisionData    = new Color[texture.Width * texture.Height];
                    collisionBitData = new bool[texture.Width * texture.Height];
                    texture.GetData <Color>(collisionData);
                    for (int col = 0; col < collisionData.Length; col++)
                    {
                        if (collisionData[col].A > 0)
                        {
                            collisionBitData[col] = true;
                        }
                    }
                    collisionData = null;
                }

                // read in each individual tile
                int numTiles = reader.ReadInt32();
                for (int j = 0; j < numTiles; j++)
                {
                    int                id     = firstId + j;
                    Rectangle          source = reader.ReadObject <Rectangle>();
                    PropertyCollection props  = new PropertyCollection();
                    props.Read(reader);

                    Tile t = new Tile(texture, whiteTexture, source, props, collisionBitData);
                    while (id >= tiles.Count)
                    {
                        tiles.Add(null);
                    }
                    tiles.Insert(id, t);
                }
            }

            // read in all the layers
            List <Layer> layers = new List <Layer>();

            Layers = new ReadOnlyCollection <Layer>(layers);
            int numLayers = reader.ReadInt32();

            for (int i = 0; i < numLayers; i++)
            {
                Layer layer = null;

                // read generic layer data
                string             type    = reader.ReadString();
                string             name    = reader.ReadString();
                int                width   = reader.ReadInt32();
                int                height  = reader.ReadInt32();
                bool               visible = reader.ReadBoolean();
                float              opacity = reader.ReadSingle();
                PropertyCollection props   = new PropertyCollection();
                props.Read(reader);

                // using the type, figure out which object to create
                if (type == "layer")
                {
                    int[] data = reader.ReadObject <int[]>();
                    layer = new TileLayer(name, width, height, visible, opacity, props, this, data);
                }
                else if (type == "objectgroup")
                {
                    List <MapObject> objects = new List <MapObject>();

                    // read in all of our objects
                    int numObjects = reader.ReadInt32();
                    for (int j = 0; j < numObjects; j++)
                    {
                        string             objName   = reader.ReadString();
                        string             objType   = reader.ReadString();
                        Rectangle          objLoc    = reader.ReadObject <Rectangle>();
                        List <Point>       objPoints = reader.ReadObject <List <Point> >();
                        PropertyCollection objProps  = new PropertyCollection();
                        objProps.Read(reader);

                        objects.Add(new MapObject(objName, objType, objLoc, objPoints, objProps));
                    }

                    layer = new MapObjectLayer(name, width, height, visible, opacity, props, objects);
                }
                else
                {
                    throw new Exception("Invalid type: " + type);
                }

                layers.Add(layer);
                namedLayers.Add(name, layer);
            }
        }