private Tiled.Tileset.TilePropertyList GetTileProperties(Tiled.Map map, int tileId) { foreach (Tiled.Tileset t in map.Tilesets.Values) { Tiled.Tileset.TilePropertyList props = t.GetTileProperties(tileId); if (props != null) { return(props); } } return(null); }
/// <summary> /// Load a map from file and create collision objects for it. Appends map horizontally if one exists. /// </summary> /// <param name="filename">File to load map from.</param> public void LoadOrExtendMap(string filename, bool spawnPlayer = false) { Tiled.Map map = Tiled.Map.Load(Path.Combine(Controller.Content.RootDirectory, filename), Controller.Content); // Destroy and re-create collision body for map. if (CollisionBody == null) { CreateCollisionBody(CollisionWorld, Physics.Dynamics.BodyType.Static); } Vector2 tileHalfSize = new Vector2(map.TileWidth, map.TileHeight) / 2; Vector2 tileSize = new Vector2(map.TileWidth, map.TileHeight); bool[,] levelCollision = new bool[map.Width, map.Height]; float defaultZVal = ZSettings.Ground; // 2 = collision. 1 = no collision. 0 = unknown. List <byte> collision = new List <byte>(); foreach (KeyValuePair <string, Tiled.Layer> layer in map.Layers) { defaultZVal -= 0.001f; for (int x = 0; x < layer.Value.Width; ++x) { for (int y = 0; y < layer.Value.Height; ++y) { int tileId = layer.Value.GetTile(x, y); if (tileId >= collision.Count || collision[tileId] == 0) { Tiled.Tileset.TilePropertyList props = GetTileProperties(map, tileId); // The only way to add new elements at arbitrary indices is to fill up the rest of the array. Do so. for (int i = collision.Count; i < tileId + 1; ++i) { collision.Add(0); } if (props != null && props.ContainsKey("collision")) { collision[tileId] = (byte)(props["collision"].Equals("true", StringComparison.OrdinalIgnoreCase) ? 2 : 1); } else { collision[tileId] = 1; } } levelCollision[x, y] |= (collision[tileId] > 1); } } float z = defaultZVal; if (layer.Value.Properties.ContainsKey("zindex")) { if (!float.TryParse(layer.Value.Properties["zindex"], out z)) { z = defaultZVal; } } MapLayer ml = new MapLayer(this, map, layer.Key, z); ml.Position = new Vector2(m_mapStart, 0.0f); AddChild(ml); } // Go through collision and try to create large horizontal collision shapes. for (int y = 0; y < map.Height; ++y) { int firstX = 0; bool hasCollision = false; for (int x = 0; x < map.Width; ++x) { if (levelCollision[x, y]) { if (hasCollision) { continue; } else { hasCollision = true; firstX = x; } } else { if (hasCollision) { hasCollision = false; int tilesWide = x - firstX; if (tilesWide == 1) { continue; } for (int i = firstX; i <= x; ++i) { levelCollision[i, y] = false; } AddCollisionRectangle( tileHalfSize * new Vector2(tilesWide, 1.0f) , new Vector2(tileSize.X * (x - (float)tilesWide / 2) + m_mapStart, tileSize.Y * (y + 0.5f)) ); } } } // Create final collision. if (hasCollision) { for (int i = firstX; i < map.Width; ++i) { levelCollision[i, y] = false; } int tilesWide = map.Width - firstX; AddCollisionRectangle( tileHalfSize * new Vector2(tilesWide, 1.0f) , new Vector2(tileSize.X * (map.Width - (float)tilesWide / 2) + m_mapStart, tileSize.Y * (y + 0.5f)) ); } } // Go through collision and try to create large vertical collision shapes. for (int x = 0; x < map.Width; ++x) { int firstY = 0; bool hasCollision = false; for (int y = 0; y < map.Height; ++y) { if (levelCollision[x, y]) { if (hasCollision) { continue; } else { hasCollision = true; firstY = y; } } else { if (hasCollision) { hasCollision = false; int tilesTall = y - firstY; AddCollisionRectangle( tileHalfSize * new Vector2(1.0f, tilesTall) , new Vector2(tileSize.X * (x + 0.5f), tileSize.Y * (y - (float)tilesTall / 2)) ); } } } // Create final collision. if (hasCollision) { int tilesTall = map.Height - firstY; AddCollisionRectangle( tileHalfSize * new Vector2(1.0f, tilesTall) , new Vector2(tileSize.X * (x + 0.5f), tileSize.Y * (map.Height - (float)tilesTall / 2)) ); } } SpawnController.CreateSpawnPoints(map.ObjectGroups.Values, new Vector2(m_mapStart, 0.0f), spawnPlayer); m_mapStart += map.Width * map.TileWidth; }