private void GenerateFireMap(EntityManager EntityManager, GameEngine engine) { // Fill the whole map with walls for (int x = 0; x < Width; x++) { for (int y = 0; y < Height; y++) { Map[x, y] = TileFactory.CreateDungeonWall(engine); } } // Dig the rooms CreateRoomsAndHallways(engine, 5, 20, 5, 20, 30); // Clear the walls that serve no purpose (makes map look better) ClearWalls(); // Replace all of the generic dungeon walls with fire walls for (int x = 0; x < Width; x++) { for (int y = 0; y < Height; y++) { if (Map[x, y].Name.Equals("Dungeon Wall")) { Map[x, y] = TileFactory.CreateFireDungeonWall(engine); } } } // Add entities to the dungeon Populate(EntityManager, engine); }
/// <summary> /// Dig a rectangle-sized room into the coordinates given. It's assumed the whole space that's going to be /// dug and the surrounding area (1 tile wide) consist of walls /// </summary> /// <param name="roomX"></param> /// <param name="roomY"></param> /// <param name="roomWidth"></param> /// <param name="roomHeight"></param> /// <param name="possibleDoorways"></param> private void DigRoom(int roomX, int roomY, int roomWidth, int roomHeight, List <Point> possibleDoorways, GameEngine engine) { for (int x = roomX; x < roomX + roomWidth; x++) { for (int y = roomY; y < roomY + roomHeight; y++) { Map[x, y] = TileFactory.CreateDungeonFloor(engine); } } }
/// <summary> /// Dig into the map to form rooms. The algorithm works by building an intial room, deciding where /// doors can be plced (pretty much on every wall of the room except the corners) and then building /// a random sized hallway from a random point. The hallway is then expanded to form a room. Repeat /// until the maximum number of rooms or the maximum number of attempts are reached /// </summary> /// <param name="random"></param> private void CreateRoomsAndHallways(GameEngine engine, int minWidth, int maxWidth, int minHeight, int maxHeight, int maxRooms) { // Room properties int maxAttempts = 600; // Generate Initial Room List <Point> possibleDoorways = new List <Point>(); int roomWidth = engine.GetRandomInt(minWidth, maxWidth); int roomHeight = engine.GetRandomInt(minHeight, maxHeight); int roomX = engine.GetRandomInt(1, Width - roomWidth - 1); int roomY = engine.GetRandomInt(1, Height - roomHeight - 1); DigRoom(roomX, roomY, roomWidth, roomHeight, possibleDoorways, engine); // Add other rooms int numRooms = 1; int numAttempts = 0; // Keep working until one of the limits set is reached while (numRooms < maxRooms && numAttempts < maxAttempts) { UpdatePossibleDoorways(possibleDoorways); // Choose a random doorway int index = engine.GetRandomInt(possibleDoorways.Count); Point door = possibleDoorways[index]; // Build a room out of that door if (GrowRoom(door, engine.GetRandomInt(minWidth, maxWidth), engine.GetRandomInt(minHeight, maxHeight), engine)) { numRooms++; } numAttempts++; } // Create a border for the map for (int x = 0; x < Width; x++) { Map[x, 0] = TileFactory.CreateDungeonWall(engine); Map[x, Height - 1] = TileFactory.CreateDungeonWall(engine); } for (int y = 0; y < Height; y++) { Map[0, y] = TileFactory.CreateDungeonWall(engine); Map[Width - 1, y] = TileFactory.CreateDungeonWall(engine); } }
/// <summary> /// Create a single generic level of the dungeon /// </summary> /// <param name="random"></param> private void GenerateGenericMap(EntityManager EntityManager, GameEngine engine) { // Fill the whole map with walls for (int x = 0; x < Width; x++) { for (int y = 0; y < Height; y++) { Map[x, y] = TileFactory.CreateDungeonWall(engine); } } // Dig the rooms CreateRoomsAndHallways(engine, 10, 15, 10, 15, 30); // Clear the walls that serve no purpose (makes map look better) ClearWalls(); // Add entities to the dungeon Populate(EntityManager, engine); }
/// <summary> /// Clear walls that serve no purpose (ie. they are surrounded by walls thus the player will /// never touch them) /// </summary> private void ClearWalls() { // Hold the walls that need to be removed. Need to be removed at the end otherwise other walls // won't be removed as they would be surrounded by floors List <Point> Walls = new List <Point>(); // Iterate through the current map for (int x = 0; x < Width; x++) { for (int y = 0; y < Height; y++) { bool RemoveWall = true; // Check the 8-cardinal directions to make sure the wall is surrounded by walls if (InBounds(x - 1, y)) { if (Map[x - 1, y].Name.Equals("Dungeon Floor")) { RemoveWall = false; } } if (InBounds(x + 1, y)) { if (Map[x + 1, y].Name.Equals("Dungeon Floor")) { RemoveWall = false; } } if (InBounds(x, y - 1)) { if (Map[x, y - 1].Name.Equals("Dungeon Floor")) { RemoveWall = false; } } if (InBounds(x, y + 1)) { if (Map[x, y + 1].Name.Equals("Dungeon Floor")) { RemoveWall = false; } } if (InBounds(x + 1, y + 1)) { if (Map[x + 1, y + 1].Name.Equals("Dungeon Floor")) { RemoveWall = false; } } if (InBounds(x - 1, y + 1)) { if (Map[x - 1, y + 1].Name.Equals("Dungeon Floor")) { RemoveWall = false; } } if (InBounds(x - 1, y - 1)) { if (Map[x - 1, y - 1].Name.Equals("Dungeon Floor")) { RemoveWall = false; } } if (InBounds(x + 1, y - 1)) { if (Map[x + 1, y - 1].Name.Equals("Dungeon Floor")) { RemoveWall = false; } } if (RemoveWall) { Walls.Add(new Point(x, y)); } } } // Now remove all the walls that we found foreach (Point location in Walls) { Map[location.X, location.Y] = TileFactory.CreateAbyss(); } }
/// <summary> /// Create a hallway from a doorway then expand the hallway sideways in order to form another /// room. The room will not be dug unless it is able to grow from the hallway /// </summary> /// <param name="door"></param> /// <param name="width"></param> /// <param name="height"></param> /// <returns></returns> private bool GrowRoom(Point door, int width, int height, GameEngine engine) { // The coordinates to build the room if it's valid List <Point> Room = new List <Point>(); Room.Add(new Point(door.X, door.Y)); // Find which way to grow horizontally int dx = 0; if (Map[door.X + 1, door.Y].Name.Equals("Dungeon Floor")) { dx = -1; } else if (Map[door.X - 1, door.Y].Name.Equals("Dungeon Floor")) { dx = 1; } // Find which way to grow vertically int dy = 0; if (Map[door.X, door.Y + 1].Name.Equals("Dungeon Floor")) { dy = -1; } else if (Map[door.X, door.Y - 1].Name.Equals("Dungeon Floor")) { dy = 1; } // Build horizontally if (dx != 0) { // Check if good to build the room bool GoodToBuild = true; for (int i = 1; i < width; i++) { int newX = door.X + (i * dx); if (!InBounds(newX, door.Y)) { GoodToBuild = false; } else if (!Map[newX, door.Y].Name.Equals("Dungeon Wall")) { GoodToBuild = false; } } // Build the corridor from the doorway if (GoodToBuild) { for (int i = 1; i < width; i++) { int newX = door.X + (i * dx); if (InBounds(newX, door.Y) && Map[newX, door.Y].Name.Equals("Dungeon Wall")) { Room.Add(new Point(newX, door.Y)); } else { return(false); } } } else { return(false); } // Grow the rest of the room from the corridor for (int i = 1; i < height / 2; i++) { for (int n = 1; n < width; n++) { int x = door.X + (n * dx); int yTop = door.Y + i; int yBot = door.Y - i; if (InBounds(x, yTop) && InBounds(x, yBot)) { if (Map[x, yTop].Name.Equals("Dungeon Wall") && Map[x, yBot].Name.Equals("Dungeon Wall")) { Room.Add(new Point(x, yTop)); Room.Add(new Point(x, yBot)); } else { return(false); } } else { return(false); } } } } else if (dy != 0) { // Check if good to build the room bool GoodToBuild = true; for (int i = 1; i < height; i++) { int newY = door.Y + (i * dy); if (!InBounds(door.X, newY)) { GoodToBuild = false; } else if (!Map[door.X, newY].Name.Equals("Dungeon Wall")) { GoodToBuild = false; } } // Build the first bit of the room if (GoodToBuild) { for (int i = 1; i < height; i++) { int newY = door.Y + (i * dy); if (InBounds(door.X, newY) && Map[door.X, newY].Name.Equals("Dungeon Wall")) { Room.Add(new Point(door.X, newY)); } else { return(false); } } } else { return(false); } // Grow the rest of the room from the corridor build for (int i = 1; i < width / 2; i++) { for (int n = 1; n < height; n++) { int xRight = door.X + i; int xLeft = door.X - i; int y = door.Y + (n * dy); if (InBounds(xRight, y) && InBounds(xLeft, y)) { if (Map[xRight, y].Name.Equals("Dungeon Wall") && Map[xLeft, y].Name.Equals("Dungeon Wall")) { Room.Add(new Point(xRight, y)); Room.Add(new Point(xLeft, y)); } else { return(false); } } else { return(false); } } } } // Draw the room foreach (Point roomTile in Room) { Map[roomTile.X, roomTile.Y] = TileFactory.CreateDungeonFloor(engine); } return(true); }