Inheritance: PropertyBag, ILoadable
コード例 #1
0
        public override void MapLoaded(TeeEngine engine, TiledMap map, MapEventArgs mapEventArgs)
        {
            LightShader lightShader = (LightShader)engine.GetPostGameShader("LightShader");
            lightShader.Enabled = true;

            base.MapLoaded(engine, map, mapEventArgs);
        }
コード例 #2
0
        public virtual void MapLoaded(TeeEngine engine, TiledMap map, MapEventArgs mapEventArgs)
        {
            if (mapEventArgs.HasProperty("Target"))
            {
                Hero player = new Hero();
                MapEntrance targetEntrance = (MapEntrance)engine.GetEntity(mapEventArgs.GetProperty("Target"));

                player.Pos = targetEntrance.Pos + new Vector2(targetEntrance.Width, targetEntrance.Height) / 2;

                engine.AddEntity("Player", player);
            }
        }
コード例 #3
0
        public override void MapLoaded(TeeEngine engine, TiledMap map, MapEventArgs mapEventArgs)
        {
            LightShader lightShader = (LightShader)engine.GetPostGameShader("LightShader");
            lightShader.Enabled = false;

            Random random = new Random();

            for (int i = 0; i < 50; i++)
            {
                int px = (int)Math.Ceiling(random.NextDouble() * engine.Map.pxWidth);
                int py = (int)Math.Ceiling(random.NextDouble() * engine.Map.pxHeight);

                Bat bat = new Bat(px, py);
                Coin coin = new Coin(px, py, 100, (CoinType)random.Next(3));

                // Switch between adding bats and coins to the map.
                if (i % 2 == 0)
                    engine.AddEntity(bat);
                else
                    engine.AddEntity(coin);
            }

            base.MapLoaded(engine, map, mapEventArgs);
        }
コード例 #4
0
 public virtual void MapUnloaded(TeeEngine engine, TiledMap map)
 {
 }
コード例 #5
0
ファイル: AStar.cs プロジェクト: behindcurtain3/Some-2D-RPG
 private bool ValidPos(TiledMap map, int x, int y)
 {
     return (x > 0 && x < map.txWidth && y > 0 && y < map.txHeight);
 }
コード例 #6
0
ファイル: AStar.cs プロジェクト: behindcurtain3/Some-2D-RPG
 public AStar(TiledMap map)
 {
     Initialize(map);
 }
コード例 #7
0
ファイル: AStar.cs プロジェクト: behindcurtain3/Some-2D-RPG
        /// <summary>
        /// Rebuilds the List of neighbors for each node. Useful in case the map changes after it was originally loaded.
        /// </summary>
        /// <param name="map">TiledMap that you wish to pathfind on</param>
        public void RebuildNeighbors(TiledMap map)
        {
            // Remove any existing neighbors on each node
            for (int y = 0; y < map.txHeight; y++)
                for (int x = 0; x < map.txWidth; x++)
                    Nodes[x, y].Neighbors.Clear();

            // Setup new neighbors
            for (int y = 0; y < map.txHeight; y++)
            {
                for (int x = 0; x < map.txWidth; x++)
                {
                    Tile tile = map.GetTxTopMostTile(x, y);
                    Tile neighbor;

                    // If the tile at this location is impassable don't add any neighbors
                    if (tile == null || tile.HasProperty("Impassable"))
                        continue;

                    // Check each entry point to build a list of neighbors
                    List<string> entryPoints = new List<string>(tile.GetProperty("Entry", "Top Bottom Left Right").Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));
                    bool left, right, up, down = false;

                    left = entryPoints.Contains("Left");
                    right = entryPoints.Contains("Right");
                    up = entryPoints.Contains("Top");
                    down = entryPoints.Contains("Bottom");

                    // Ortho neighbors
                    if (left)
                        if (ValidPos(map, x - 1, y))
                        {
                            // Check to see if the neighbor is a valid link
                            neighbor = map.GetTxTopMostTile(x - 1, y);

                            if (!neighbor.HasProperty("Impassable") && HasEntry(neighbor, "Right"))
                                Nodes[x, y].Neighbors.Add(Nodes[x - 1, y]);
                            else
                                left = false; // left is not a valid neighbor, this rules out some diagonals
                        }
                    if (right)
                        if (ValidPos(map, x + 1, y))
                        {
                            neighbor = map.GetTxTopMostTile(x + 1, y);

                            if (!neighbor.HasProperty("Impassable") && HasEntry(neighbor, "Left"))
                                Nodes[x, y].Neighbors.Add(Nodes[x + 1, y]);
                            else
                                right = false;
                        }
                    if (up)
                        if (ValidPos(map, x, y - 1))
                        {
                            neighbor = map.GetTxTopMostTile(x, y - 1);

                            if (!neighbor.HasProperty("Impassable") && HasEntry(neighbor, "Bottom"))
                                Nodes[x, y].Neighbors.Add(Nodes[x, y - 1]);
                            else
                                up = false;
                        }
                    if (down)
                        if (ValidPos(map, x, y + 1))
                        {
                            neighbor = map.GetTxTopMostTile(x, y + 1);

                            if (!neighbor.HasProperty("Impassable") && HasEntry(neighbor, "Top"))
                                Nodes[x, y].Neighbors.Add(Nodes[x, y + 1]);
                            else
                                down = false;
                        }

                    // Diagonal neighbors
                    if (left && up)
                        if (ValidPos(map, x - 1, y - 1))
                        {
                            neighbor = map.GetTxTopMostTile(x - 1, y - 1);

                            if (!neighbor.HasProperty("Impassable") && HasEntry(neighbor, "Bottom") && HasEntry(neighbor, "Right"))
                                Nodes[x, y].Neighbors.Add(Nodes[x - 1, y - 1]);
                        }
                    if (right && up)
                        if (ValidPos(map, x + 1, y - 1))
                        {
                            neighbor = map.GetTxTopMostTile(x + 1, y - 1);

                            if (!neighbor.HasProperty("Impassable") && HasEntry(neighbor, "Bottom") && HasEntry(neighbor, "Left"))
                                Nodes[x, y].Neighbors.Add(Nodes[x + 1, y - 1]);
                        }
                    if (right && down)
                        if (ValidPos(map, x + 1, y + 1))
                        {
                            neighbor = map.GetTxTopMostTile(x + 1, y + 1);

                            if (!neighbor.HasProperty("Impassable") && HasEntry(neighbor, "Top") && HasEntry(neighbor, "Left"))
                                Nodes[x, y].Neighbors.Add(Nodes[x + 1, y + 1]);
                        }
                    if (left && down)
                        if (ValidPos(map, x - 1, y + 1))
                        {
                            neighbor = map.GetTxTopMostTile(x - 1, y + 1);

                            if (!neighbor.HasProperty("Impassable") && HasEntry(neighbor, "Top") && HasEntry(neighbor, "Right"))
                                Nodes[x, y].Neighbors.Add(Nodes[x - 1, y + 1]);
                        }
                }
            }
        }
コード例 #8
0
ファイル: AStar.cs プロジェクト: behindcurtain3/Some-2D-RPG
        /// <summary>
        /// Initialize builds the array of ANodes and their list of neighbors, must be called before a path is generated
        /// </summary>
        /// <param name="map">TiledMap that you wish to pathfind on</param>
        public void Initialize(TiledMap map)
        {
            // SETUP PATHFINDING NODES
            Nodes = new ANode[map.txWidth, map.txHeight];

            for (int y = 0; y < map.txHeight; y++)
            {
                for (int x = 0; x < map.txWidth; x++)
                {
                    ANode node = new ANode();
                    node.TX = x;
                    node.TY = y;
                    node.Center = new Vector2(map.TileWidth * x + map.TileWidth / 2, map.TileHeight * y + map.TileHeight / 2);

                    Nodes[x, y] = node;
                }
            }

            // Build the neighbors
            RebuildNeighbors(map);
        }
コード例 #9
0
 public override void MapUnloaded(TeeEngine engine, TiledMap map)
 {
     base.MapUnloaded(engine, map);
 }
コード例 #10
0
        // TODO: Support for zlib compression of tile data  (Zlib.NET)
        // http://stackoverflow.com/questions/6620655/compression-and-decompression-problem-with-zlib-net
        // Reads and converts and .tmx file to a TiledMap object. Doing so does NOT load appropriate tile textures into memory.
        // In order for textures to be loaded, the LoadContent(ContentManager) method must be called. This is usually automatically
        // performed by the TeeEngine when calling its LoadMap(TiledMap) method. However, it may be called independently if needs be.
        public static TiledMap LoadTmxFile(string file)
        {
            if (File.Exists(file))
            {
                // Find the working directory of this file so that any external files may use the same path.
                int dirIndex = file.LastIndexOfAny(new char[] { '/', '\\' });
                string workingDirectory = (dirIndex > 0) ? file.Substring(0, dirIndex) : "";

                XmlDocument document = new XmlDocument();
                document.Load(file);

                XmlNode mapNode = document.SelectSingleNode("map");

                TiledMap map = new TiledMap();
                map.txWidth = XmlExtensions.GetAttributeValue<int>(mapNode, "width", -1, true);
                map.txHeight = XmlExtensions.GetAttributeValue<int>(mapNode, "height", -1, true);
                map.TileWidth = XmlExtensions.GetAttributeValue<int>(mapNode, "tilewidth", -1, true);
                map.TileHeight = XmlExtensions.GetAttributeValue<int>(mapNode, "tileheight", -1, true);
                map.TileDiagonalLength = Math.Sqrt(Math.Pow(map.TileWidth, 2) + Math.Pow(map.TileHeight, 2));

                map.Background = ColorExtensions.ToColor(
                    XmlExtensions.GetAttributeValue(
                        mapNode, "backgroundcolor", "#000000"
                    )
                );
                map.LoadProperties(mapNode);

                // OBJECT LAYERS
                foreach (XmlNode objectLayerNode in mapNode.SelectNodes("objectgroup"))
                {
                    TiledObjectLayer mapObjectLayer = new TiledObjectLayer();
                    mapObjectLayer.Width = XmlExtensions.GetAttributeValue<int>(objectLayerNode, "width", 1);
                    mapObjectLayer.Height = XmlExtensions.GetAttributeValue<int>(objectLayerNode, "height", 1);
                    mapObjectLayer.Name = XmlExtensions.GetAttributeValue(objectLayerNode, "name");

                    foreach (XmlNode objectNode in objectLayerNode.SelectNodes("object"))
                    {
                        TiledObject mapObject = new TiledObject();
                        mapObject.Name = XmlExtensions.GetAttributeValue(objectNode, "name");
                        mapObject.Type = XmlExtensions.GetAttributeValue(objectNode, "type");
                        mapObject.X = XmlExtensions.GetAttributeValue<int>(objectNode, "x", 0);
                        mapObject.Y = XmlExtensions.GetAttributeValue<int>(objectNode, "y", 0);
                        mapObject.Width = XmlExtensions.GetAttributeValue<int>(objectNode, "width", 0);
                        mapObject.Height = XmlExtensions.GetAttributeValue<int>(objectNode, "height", 0);
                        mapObject.Gid = XmlExtensions.GetAttributeValue<int>(objectNode, "gid", -1);

                        XmlNode polygonNode = objectNode.SelectSingleNode("polygon");
                        if (polygonNode != null)
                            mapObject.Points = ConvertToPointsList(XmlExtensions.GetAttributeValue(polygonNode, "points"));

                        mapObject.LoadProperties(objectNode);

                        mapObjectLayer.TiledObjects.Add(mapObject);
                    }

                    map.TiledObjectLayers.Add(mapObjectLayer);
                }

                // TILESETS
                foreach (XmlNode tilesetNode in mapNode.SelectNodes("tileset"))
                {
                    XmlNode actualTilesetNode;
                    int firstGID = XmlExtensions.GetAttributeValue<int>(tilesetNode, "firstgid", -1, true);

                    // If the tileset comes from an external .tsx file, load the node from that file.
                    if (XmlExtensions.HasAttribute(tilesetNode, "source"))
                    {
                        XmlDocument tilesetDocument = new XmlDocument();
                        tilesetDocument.Load(
                            string.Format("{0}/{1}",
                                workingDirectory, XmlExtensions.GetAttributeValue(tilesetNode, "source")));

                        actualTilesetNode = tilesetDocument.SelectSingleNode("tileset");
                    }
                    else
                        actualTilesetNode = tilesetNode;

                    string tilesetName = XmlExtensions.GetAttributeValue(actualTilesetNode, "name");
                    int tileHeight = XmlExtensions.GetAttributeValue<int>(actualTilesetNode, "tileheight", -1, true);
                    int tileWidth = XmlExtensions.GetAttributeValue<int>(actualTilesetNode, "tilewidth", -1, true);

                    TileSet tileset = new TileSet();
                    tileset.LoadProperties(actualTilesetNode);

                    tileset.Name = tilesetName;
                    tileset.TileWidth = tileWidth;
                    tileset.TileHeight = tileHeight;
                    tileset.ContentTexturePath = tileset.GetProperty("Content");    // Content Texture Path for XNA. REQUIRED.

                    map.TileSets.Add(tileset);

                    XmlNode imageNode = actualTilesetNode.SelectSingleNode("image");
                    int imageWidth = XmlExtensions.GetAttributeValue<int>(imageNode, "width", -1, true);
                    int imageHeight = XmlExtensions.GetAttributeValue<int>(imageNode, "height", -1, true);
                    string sourceTexturePath = XmlExtensions.GetAttributeValue<string>(imageNode, "source", "", true);

                    // PreBuild the tiles from the tileset information.
                    int i = 0;
                    while (true)
                    {
                        int tx = (i * tileWidth) % imageWidth;
                        int ty = tileHeight * ((i * tileWidth) / imageWidth);

                        // This check is performed in the case where image width is not
                        // an exact multiple of the tile width specified.
                        if (tx + tileWidth > imageWidth)
                        {
                            tx = 0;
                            ty += tileHeight;
                        }

                        // If we have exceeded the image height, we are done.
                        if (ty + tileHeight > imageHeight)
                            break;

                        Tile tile = new Tile();
                        tile.SourceTexturePath = sourceTexturePath;                             // Path to the actual file being referred.
                        tile.SourceRectangle = new Rectangle(tx, ty, tileWidth, tileHeight);
                        tile.TileGid = i + firstGID;
                        tile.TileId = i;
                        tile.TileSet = tileset;

                        map.Tiles.Add(tile.TileGid, tile);
                        tileset.Tiles.Add(i, tile);
                        i++;
                    }

                    // Add any individual properties to the tiles we have created
                    foreach (XmlNode tileNode in actualTilesetNode.SelectNodes("tile"))
                    {
                        int tileGid = firstGID + XmlExtensions.GetAttributeValue<int>(tileNode, "id", -1, true);
                        Tile tile = map.Tiles[tileGid];
                        tile.LoadProperties(tileNode);

                        // BUILT INS
                        // Adjust the draw origin based on the tile property 'DrawOrigin'
                        string[] drawOrigin = tile.GetProperty("DrawOrigin", "0, 1").Split(',');
                        tile.Origin = new Vector2(
                            (float)Convert.ToDouble(drawOrigin[0]),
                            (float)Convert.ToDouble(drawOrigin[1])
                            );
                    }
                }

                // TILE LAYERS
                foreach (XmlNode layerNode in mapNode.SelectNodes("layer"))
                {
                    int width = XmlExtensions.GetAttributeValue<int>(layerNode, "width", 0);
                    int height = XmlExtensions.GetAttributeValue<int>(layerNode, "height", 0);

                    TileLayer tileLayer = new TileLayer(width, height);
                    tileLayer.Name = XmlExtensions.GetAttributeValue(layerNode, "name");
                    tileLayer.LoadProperties(layerNode);

                    // SET BUILTIN PROPERTIES
                    tileLayer.Color = ColorExtensions.ToColor(
                        tileLayer.GetProperty<string>("Color", "#ffffff")
                        );
                    tileLayer.Opacity = tileLayer.GetProperty<float>("Opacity", 1.0f);

                    XmlNode dataNode = layerNode.SelectSingleNode("data");
                    string[] tokens = dataNode.InnerText.Split(
                        new char[] { '\n', ',', '\r' },
                        StringSplitOptions.RemoveEmptyEntries
                    );

                    for (int index = 0; index < tokens.Length; index++)
                        tileLayer[index] = Convert.ToInt32(tokens[index]);

                    map.TileLayers.Add(tileLayer);
                }

                return map;
            }
            else throw new IOException(string.Format("The Map File '{0}' does not exist.", file));
        }
コード例 #11
0
        public void MapLoaded(TeeEngine engine, TiledMap map, MapEventArgs args)
        {
            engine.GetPostGameShader("LightShader").Enabled = false;

            _player = (Hero)engine.GetEntity("Player");

            // The player should start with zero intensity
            _player.Intensity = 0;
            _spawners = new List<MobSpawner>();

            List<Entity> entities = new List<Entity>(engine.GetEntities());
            foreach (Entity e in entities)
            {
                if (e is MobSpawner)
                    _spawners.Add((MobSpawner)e);
            }

            // Setup and load the UI
            Hud = new ArenaUI(engine.Game);

            List<Component> hudComponents = Component.LoadComponentsFromXml("HUD/Elements/Components.ui", engine.Game.Content);
            foreach (Component c in hudComponents)
                Hud.AddComponent(c.Name, c);

            // Bind data to components
            if (_player != null)
            {
                Label label = (Label)Hud.GetComponent("HeroLevel");
                if (label != null)
                    label.SetDataBinding("Level", _player);

                label = (Label)Hud.GetComponent("HeroStrength");
                if (label != null)
                    label.SetDataBinding("Strength", _player);

                label = (Label)Hud.GetComponent("HeroDexterity");
                if (label != null)
                    label.SetDataBinding("Dexterity", _player);

                label = (Label)Hud.GetComponent("HeroWisdom");
                if (label != null)
                    label.SetDataBinding("Wisdom", _player);

                Button cheat = (Button)Hud.GetComponent("CheatButton");
                if(cheat != null)
                    cheat.onMouseClick += new Component.MouseEventHandler(delegate(Component sender, MouseState mouse)
                    {
                        _player.LevelUp();
                        _player.HP = _player.MaxHP;
                    });

                _player.onItemEquipped += new NPC.OnItemEquippedEventHandler(NPC_onItemEquiped);
                _player.onItemUnEquipped += new NPC.OnItemUnEquippedEventHandler(NPC_onItemUnEquiped);
                _player.onDeath += new NPC.OnDeathEventHandler(NPC_onDeath);

                // Load the currently equipped items
                foreach (KeyValuePair<ItemType, Item> pair in _player.Equiped)
                {
                    NPC_onItemEquiped(_player, pair.Value);
                }
            }

            _mapLoaded = true;
        }
コード例 #12
0
        // Automatic Conversion of TiledObjects in a .tmx file to TeeEngine Entities using C# Reflection.
        private void ConvertMapObjects(TiledMap map)
        {
            foreach (TiledObjectLayer objectLayer in map.TiledObjectLayers)
            {
                foreach (TiledObject tiledObject in objectLayer.TiledObjects)
                {
                    Entity entity = null;

                    // Special (Static) Tiled-Object when a Gid is specified.
                    if (tiledObject.Type == null && tiledObject.Gid != -1)
                    {
                        Tile sourceTile = map.Tiles[tiledObject.Gid];

                        entity = new Entity();
                        entity.Drawables.Add("standard", sourceTile);
                        entity.CurrentDrawableState = "standard";
                        entity.Pos = new Vector2(tiledObject.X, tiledObject.Y);

                        // Cater for any difference in origin from Tiled's default Draw Origin of (0,1).
                        entity.Pos.X += (sourceTile.Origin.X - 0.0f) * sourceTile.GetSourceRectangle(0).Width;
                        entity.Pos.Y += (sourceTile.Origin.Y - 1.0f) * sourceTile.GetSourceRectangle(0).Height;
                    }
                    else if(tiledObject.Type != null)
                    {
                        // Try and load Entity types from both the Assembly specified in MapProperties and within the GameEngine.
                        Assembly userAssembly = (map.HasProperty("Assembly")) ? Assembly.Load(map.GetProperty("Assembly")) : null;
                        Assembly engineAssembly = Assembly.GetExecutingAssembly();

                        // Try for user Assembly first - allows default Objects to be overriden if absoluately necessary.
                        object createdObject = null;
                        if (userAssembly != null)
                            createdObject = userAssembly.CreateInstance(tiledObject.Type);

                        if (createdObject == null)
                            createdObject = engineAssembly.CreateInstance(tiledObject.Type);

                        if (createdObject == null)
                            throw new ArgumentException(string.Format("'{0}' does not exist in any of the loaded Assemblies", tiledObject.Type));

                        if (createdObject is Entity)
                        {
                            // Convert to Entity object and assign values.
                            entity = (Entity)createdObject;
                            entity.Pos = new Vector2(tiledObject.X, tiledObject.Y);

                            // If the entity implements the ISizedEntity interface, apply Width and Height.
                            if (entity is ISizedEntity)
                            {
                                ((ISizedEntity)entity).Width = tiledObject.Width;
                                ((ISizedEntity)entity).Height = tiledObject.Height;
                            }

                            if (entity is IPolygonEntity)
                                ((IPolygonEntity)entity).Points = tiledObject.Points;

                            foreach (string propertyKey in tiledObject.PropertyKeys)
                            {
                                // Ignore all properties starting with '.'
                                if (propertyKey.StartsWith("."))
                                    continue;

                                // Bind Events.
                                if (propertyKey.StartsWith("$"))
                                {
                                    string methodName = tiledObject.GetProperty(propertyKey);
                                    string eventName = propertyKey.Substring(1, propertyKey.Length - 1);

                                    MethodInfo methodInfo = MapScript.GetType().GetMethod(methodName);
                                    EventInfo eventInfo = entity.GetType().GetEvent(eventName);
                                    Delegate delegateMethod = Delegate.CreateDelegate(eventInfo.EventHandlerType, MapScript, methodInfo);

                                    eventInfo.AddEventHandler(entity, delegateMethod);
                                }
                                else
                                    // Bind Properties.
                                    ReflectionExtensions.SmartSetProperty(entity, propertyKey, tiledObject.GetProperty(propertyKey));
                            }
                        }
                        else throw new ArgumentException(string.Format("'{0}' is not an Entity object", tiledObject.Type));
                    }

                    if(entity != null ) this.AddEntity(tiledObject.Name, entity);
                }
            }
        }
コード例 #13
0
        public void LoadMap(TiledMap map, MapEventArgs mapLoadedEventArgs=null)
        {
            this.Map = map;
            this.Map.LoadContent(Game.Content);

            // Load Specified Map Scipt (If Any)
            if (this.Map.HasProperty("MapScript"))
            {
                string assemblyName = map.GetProperty("Assembly");
                string mapModel = map.GetProperty("MapScript");

                this.MapScript = (IMapScript)Activator.CreateInstance(assemblyName, mapModel).Unwrap();
            }
            else this.MapScript = null;

            // Convert TiledObjects into Entity objects.
            ConvertMapObjects(map);

            // Set the mapLoaded flag so that the MapLoaded event can be invoked at a later stage.
            _mapLoaded = true;
            _mapLoadedEventArgs = mapLoadedEventArgs;

            // unload previous map here.

            this.Collider.Construct(map.txWidth, map.txHeight, map.TileWidth, map.TileHeight);

            // Setup the pathfinding with the new map
            this.Pathfinding = new AStar(this.Map);
        }
コード例 #14
0
        // TODO: Support for zlib compression of tile data  (Zlib.NET)
        // http://stackoverflow.com/questions/6620655/compression-and-decompression-problem-with-zlib-net
        // Reads and converts and .tmx file to a TiledMap object. Doing so does NOT load appropriate tile textures into memory.
        // In order for textures to be loaded, the LoadContent(ContentManager) method must be called. This is usually automatically
        // performed by the TeeEngine when calling its LoadMap(TiledMap) method. However, it may be called independently if needs be.
        public static TiledMap LoadTmxFile(string file)
        {
            if (File.Exists(file))
            {
                // Find the working directory of this file so that any external files may use the same path.
                int    dirIndex         = file.LastIndexOfAny(new char[] { '/', '\\' });
                string workingDirectory = (dirIndex > 0) ? file.Substring(0, dirIndex) : "";

                XmlDocument document = new XmlDocument();
                document.Load(file);

                XmlNode mapNode = document.SelectSingleNode("map");

                TiledMap map = new TiledMap();
                map.txWidth    = XmlExtensions.GetAttributeValue <int>(mapNode, "width", -1, true);
                map.txHeight   = XmlExtensions.GetAttributeValue <int>(mapNode, "height", -1, true);
                map.TileWidth  = XmlExtensions.GetAttributeValue <int>(mapNode, "tilewidth", -1, true);
                map.TileHeight = XmlExtensions.GetAttributeValue <int>(mapNode, "tileheight", -1, true);
                map.Background = ColorExtensions.ToColor(
                    XmlExtensions.GetAttributeValue(
                        mapNode, "backgroundcolor", "#000000"
                        )
                    );
                map.LoadProperties(mapNode);

                // OBJECT LAYERS
                foreach (XmlNode objectLayerNode in mapNode.SelectNodes("objectgroup"))
                {
                    TiledObjectLayer mapObjectLayer = new TiledObjectLayer();
                    mapObjectLayer.Width  = XmlExtensions.GetAttributeValue <int>(objectLayerNode, "width", 1);
                    mapObjectLayer.Height = XmlExtensions.GetAttributeValue <int>(objectLayerNode, "height", 1);
                    mapObjectLayer.Name   = XmlExtensions.GetAttributeValue(objectLayerNode, "name");

                    foreach (XmlNode objectNode in objectLayerNode.SelectNodes("object"))
                    {
                        TiledObject mapObject = new TiledObject();
                        mapObject.Name   = XmlExtensions.GetAttributeValue(objectNode, "name");
                        mapObject.Type   = XmlExtensions.GetAttributeValue(objectNode, "type");
                        mapObject.X      = XmlExtensions.GetAttributeValue <int>(objectNode, "x", 0);
                        mapObject.Y      = XmlExtensions.GetAttributeValue <int>(objectNode, "y", 0);
                        mapObject.Width  = XmlExtensions.GetAttributeValue <int>(objectNode, "width", 0);
                        mapObject.Height = XmlExtensions.GetAttributeValue <int>(objectNode, "height", 0);
                        mapObject.Gid    = XmlExtensions.GetAttributeValue <int>(objectNode, "gid", -1);

                        XmlNode polygonNode = objectNode.SelectSingleNode("polygon");
                        if (polygonNode != null)
                        {
                            mapObject.Points = ConvertToPointsList(XmlExtensions.GetAttributeValue(polygonNode, "points"));
                        }

                        mapObject.LoadProperties(objectNode);

                        mapObjectLayer.TiledObjects.Add(mapObject);
                    }

                    map.TiledObjectLayers.Add(mapObjectLayer);
                }

                // TILESETS
                foreach (XmlNode tilesetNode in mapNode.SelectNodes("tileset"))
                {
                    XmlNode actualTilesetNode;
                    int     firstGID = XmlExtensions.GetAttributeValue <int>(tilesetNode, "firstgid", -1, true);

                    // If the tileset comes from an external .tsx file, load the node from that file.
                    if (XmlExtensions.HasAttribute(tilesetNode, "source"))
                    {
                        XmlDocument tilesetDocument = new XmlDocument();
                        tilesetDocument.Load(
                            string.Format("{0}/{1}",
                                          workingDirectory, XmlExtensions.GetAttributeValue(tilesetNode, "source")));

                        actualTilesetNode = tilesetDocument.SelectSingleNode("tileset");
                    }
                    else
                    {
                        actualTilesetNode = tilesetNode;
                    }

                    string tilesetName = XmlExtensions.GetAttributeValue(actualTilesetNode, "name");
                    int    tileHeight  = XmlExtensions.GetAttributeValue <int>(actualTilesetNode, "tileheight", -1, true);
                    int    tileWidth   = XmlExtensions.GetAttributeValue <int>(actualTilesetNode, "tilewidth", -1, true);

                    TileSet tileset = new TileSet();
                    tileset.LoadProperties(actualTilesetNode);

                    tileset.Name               = tilesetName;
                    tileset.TileWidth          = tileWidth;
                    tileset.TileHeight         = tileHeight;
                    tileset.ContentTexturePath = tileset.GetProperty("Content");    // Content Texture Path for XNA. REQUIRED.

                    map.TileSets.Add(tileset);

                    XmlNode imageNode         = actualTilesetNode.SelectSingleNode("image");
                    int     imageWidth        = XmlExtensions.GetAttributeValue <int>(imageNode, "width", -1, true);
                    int     imageHeight       = XmlExtensions.GetAttributeValue <int>(imageNode, "height", -1, true);
                    string  sourceTexturePath = XmlExtensions.GetAttributeValue <string>(imageNode, "source", "", true);

                    // PreBuild the tiles from the tileset information.
                    int i = 0;
                    while (true)
                    {
                        int tx = (i * tileWidth) % imageWidth;
                        int ty = tileHeight * ((i * tileWidth) / imageWidth);

                        // This check is performed in the case where image width is not
                        // an exact multiple of the tile width specified.
                        if (tx + tileWidth > imageWidth)
                        {
                            tx  = 0;
                            ty += tileHeight;
                        }

                        // If we have exceeded the image height, we are done.
                        if (ty + tileHeight > imageHeight)
                        {
                            break;
                        }

                        Tile tile = new Tile();
                        tile.SourceTexturePath = sourceTexturePath;                             // Path to the actual file being referred.
                        tile.SourceRectangle   = new Rectangle(tx, ty, tileWidth, tileHeight);
                        tile.TileGid           = i + firstGID;
                        tile.TileId            = i;
                        tile.TileSet           = tileset;

                        map.Tiles.Add(tile.TileGid, tile);
                        tileset.Tiles.Add(i, tile);
                        i++;
                    }

                    // Add any individual properties to the tiles we have created
                    foreach (XmlNode tileNode in actualTilesetNode.SelectNodes("tile"))
                    {
                        int  tileGid = firstGID + XmlExtensions.GetAttributeValue <int>(tileNode, "id", -1, true);
                        Tile tile    = map.Tiles[tileGid];
                        tile.LoadProperties(tileNode);

                        // BUILT INS
                        // Adjust the draw origin based on the tile property 'DrawOrigin'
                        string[] drawOrigin = tile.GetProperty("DrawOrigin", "0, 1").Split(',');
                        tile.Origin = new Vector2(
                            (float)Convert.ToDouble(drawOrigin[0]),
                            (float)Convert.ToDouble(drawOrigin[1])
                            );
                    }
                }

                // TILE LAYERS
                foreach (XmlNode layerNode in mapNode.SelectNodes("layer"))
                {
                    int width  = XmlExtensions.GetAttributeValue <int>(layerNode, "width", 0);
                    int height = XmlExtensions.GetAttributeValue <int>(layerNode, "height", 0);

                    TileLayer tileLayer = new TileLayer(width, height);
                    tileLayer.Name = XmlExtensions.GetAttributeValue(layerNode, "name");
                    tileLayer.LoadProperties(layerNode);

                    // SET BUILTIN PROPERTIES
                    tileLayer.Color = ColorExtensions.ToColor(
                        tileLayer.GetProperty <string>("Color", "#ffffff")
                        );
                    tileLayer.Opacity = tileLayer.GetProperty <float>("Opacity", 1.0f);

                    XmlNode  dataNode = layerNode.SelectSingleNode("data");
                    string[] tokens   = dataNode.InnerText.Split(
                        new char[] { '\n', ',', '\r' },
                        StringSplitOptions.RemoveEmptyEntries
                        );

                    for (int index = 0; index < tokens.Length; index++)
                    {
                        tileLayer[index] = Convert.ToInt32(tokens[index]);
                    }

                    map.TileLayers.Add(tileLayer);
                }

                return(map);
            }
            else
            {
                throw new IOException(string.Format("The Map File '{0}' does not exist.", file));
            }
        }