// Create a random slice inside the QuadTree boundary public bool RandomSlice(int numTry, int maxTries, ref XY output) { if (numTry > maxTries) { return(false); } // Get a random slice point float sliceX = Mathf.Round(Random.Range(boundary.Left(), boundary.Right())); float sliceY = Mathf.Round(Random.Range(boundary.Bottom(), boundary.Top())); // Check if we can fit 4 rooms using that slice, if not just try again until maxTries if (Mathf.Abs(sliceX - boundary.Left()) < roomRealMinSize) { return(RandomSlice(numTry + 1, maxTries, ref output)); } if (Mathf.Abs(boundary.Right() - sliceX) < roomRealMinSize) { return(RandomSlice(numTry + 1, maxTries, ref output)); } if (Mathf.Abs(boundary.Top() - sliceY) < roomRealMinSize) { return(RandomSlice(numTry + 1, maxTries, ref output)); } if (Mathf.Abs(sliceY - boundary.Bottom()) < roomRealMinSize) { return(RandomSlice(numTry + 1, maxTries, ref output)); } output = new XY(sliceX, sliceY); return(true); }
/// <summary> /// Tries to create a random room inside a given box. /// It lefts at least one tile between the box and the room /// </summary> /// <param name="boundaries">The box where to create the new room</param> /// <returns>A new Room or null if the boundaries is too small</returns> public static Room CreateRandomRoom(AABB boundaries) { if (boundaries.half.x < Dungeon.MIN_ROOM_HALFSIZE + Dungeon.MIN_ROOM_MARGIN || boundaries.half.y < Dungeon.MIN_ROOM_HALFSIZE + Dungeon.MIN_ROOM_MARGIN) { return(null); } int maxSizeX = Mathf.Min(boundaries.half.x - Dungeon.MIN_ROOM_MARGIN, Dungeon.MAX_ROOM_HALFSIZE); int maxSizeY = Mathf.Min(boundaries.half.y - Dungeon.MIN_ROOM_MARGIN, Dungeon.MAX_ROOM_HALFSIZE); // Create random width int width = Random.Range(Dungeon.MIN_ROOM_HALFSIZE, maxSizeX); int height = Random.Range(Dungeon.MIN_ROOM_HALFSIZE, maxSizeY); // We don't want the room to go outside the box int maxx = boundaries.Right() - width - (Dungeon.MIN_ROOM_MARGIN - 1); int minx = boundaries.Left() + width + Dungeon.MIN_ROOM_MARGIN; int miny = boundaries.Bottom() + height + Dungeon.MIN_ROOM_MARGIN; int maxy = boundaries.Top() - height - (Dungeon.MIN_ROOM_MARGIN - 1); // Create random center int x = Random.Range(minx, maxx); int y = Random.Range(miny, maxy); return(new Room(new XY(x, y), new XY(width, height))); }
/// <summary> /// Recursively creates the tree by adding the child nodes /// </summary> /// <param name="currentDepth">The current depth of the tree</param> /// <param name="maxDepth">The max depth the tree can have</param> public void BuildTree(int currentDepth, int maxDepth) { // We want to stop if we have reached the max depth if (currentDepth > maxDepth) { return; } // Or if it is not possible to store 4 rooms in the space XY wh = _box.half / 2; if (wh.x < Dungeon.MIN_ROOM_HALFSIZE + 2 * Dungeon.MIN_ROOM_MARGIN || wh.y < Dungeon.MIN_ROOM_HALFSIZE + 2 * Dungeon.MIN_ROOM_MARGIN) { return; } // Make sure they are even numbers int x = _box.Left() + 2 * Random.Range(Dungeon.MIN_ROOM_HALFSIZE + Dungeon.MIN_ROOM_MARGIN, _box.half.x - Dungeon.MIN_ROOM_HALFSIZE - Dungeon.MIN_ROOM_MARGIN); int y = _box.Bottom() + 2 * Random.Range(Dungeon.MIN_ROOM_HALFSIZE + Dungeon.MIN_ROOM_MARGIN, _box.half.y - Dungeon.MIN_ROOM_HALFSIZE - Dungeon.MIN_ROOM_MARGIN); // The half sizes int left = (x - _box.Left()) / 2; int right = (_box.Right() - x) / 2; int up = (_box.Top() - y) / 2; int down = (y - _box.Bottom()) / 2; // Creating each trees and build them _northWest = new Quadtree(new AABB(new XY(x - left, y + up), new XY(left, up))); _northWest.BuildTree(currentDepth + 1, maxDepth); _northEast = new Quadtree(new AABB(new XY(x + right, y + up), new XY(right, up))); _northEast.BuildTree(currentDepth + 1, maxDepth); _southWest = new Quadtree(new AABB(new XY(x - left, y - down), new XY(left, down))); _southWest.BuildTree(currentDepth + 1, maxDepth); _southEast = new Quadtree(new AABB(new XY(x + right, y - down), new XY(right, down))); _southEast.BuildTree(currentDepth + 1, maxDepth); }