private int GetSplitPoint(BSPTreeNodeBounds bounds, BSPSplitDirection splitDir, float splitRange) { int max = 0; int min = 0; float delta_high = 0.5f + splitRange / 2; float delta_low = 0.5f - splitRange / 2; int range; switch (splitDir) { case BSPSplitDirection.VERTICAL: range = bounds.max_x - bounds.min_x; min = bounds.min_x + (int)(range * delta_low); max = bounds.min_x + (int)(range * delta_high); break; case BSPSplitDirection.HORIZONTAL: range = bounds.max_y - bounds.min_y; min = bounds.min_y + (int)(range * delta_low); max = bounds.min_y + (int)(range * delta_high); break; } if (min == 0) { min = 1; // Cannot be too small! } return(DungeonGenerator.Random.Instance.Next(min, max)); }
public int maxCorridorWidth = 2; // [1,2] // bool ONE_DOOR_PER_CORRIDOR = true; override protected void GenerateWithAlgorithm(VirtualMap map, VirtualMap vmapBelow) { // Start full of rocks map.ResetToRocks(); //return; // Pick the cell to start from CellLocation starting_location = default(CellLocation); if (vmapBelow != null) { starting_location = vmapBelow.end; } else { starting_location = CellLocation.INVALID; } //Debug.Log(starting_location); // We start our tree with the full dungeon bounds (only counting FLOOR cells) BSPTree tree = new BSPTree(); tree.root = new BSPTreeNode(0, 0, map.ActualWidth, map.ActualHeight); // Pick a random initial direction BSPSplitDirection splitDir = (BSPSplitDirection)DungeonGenerator.Random.Instance.Next(0, (int)BSPSplitDirection.MAX - 1); // Start the algorithm List <BSPTreeNode> leafNodes = new List <BSPTreeNode>(); SplitNode(tree.root, splitDir, splitRange, nSplits, leafNodes); // Create the rooms RoomGenerator roomGenerator = new RoomGenerator(); map.rooms = new List <VirtualRoom>(); foreach (BSPTreeNode node in leafNodes) { VirtualRoom room = CreateRoom(map, roomGenerator, node, starting_location); if (room != null) { room.sequentialId = map.rooms.Count; map.rooms.Add(room); } } // Create the corridors LinkCorridors(tree.root, map, 0); }
void SplitNode(BSPTreeNode node, BSPSplitDirection splitDir, float splitRange, int recursionLevel, List <BSPTreeNode> leafNodes) { // Split a node so that we get a new range [min_x,min_y,max_x,max_y] so that a room can be created with these bounds // Note that these are bounds on the indices of the virtual map and that they are left-inclusive! //Debug.Log("LEVEL " + recursionLevel + " [" + node.areaBounds.min_x + "," + node.areaBounds.max_x + "] [" + node.areaBounds.min_y + "," + node.areaBounds.max_y + "]"); if (recursionLevel == 0) { leafNodes.Add(node); return; } int splitPoint; // Pick a random coordinate on that direction splitPoint = GetSplitPoint(node.areaBounds, splitDir, splitRange); node.splitDirection = splitDir; //Debug.Log("ON " + splitDir + " CHOSEN SPLIT: " + splitPoint); // Create child nodes from that split point switch (splitDir) { case BSPSplitDirection.VERTICAL: node.left = new BSPTreeNode(node.areaBounds.min_x, node.areaBounds.min_y, splitPoint, node.areaBounds.max_y); node.right = new BSPTreeNode(splitPoint, node.areaBounds.min_y, node.areaBounds.max_x, node.areaBounds.max_y); break; case BSPSplitDirection.HORIZONTAL: node.left = new BSPTreeNode(node.areaBounds.min_x, node.areaBounds.min_y, node.areaBounds.max_x, splitPoint); node.right = new BSPTreeNode(node.areaBounds.min_x, splitPoint, node.areaBounds.max_x, node.areaBounds.max_y); break; } // Next pass: go through child nodes recursionLevel--; splitDir = (BSPSplitDirection)Mathf.Repeat((int)(splitDir + 1), (int)BSPSplitDirection.MAX); SplitNode(node.left, splitDir, splitRange, recursionLevel, leafNodes); SplitNode(node.right, splitDir, splitRange, recursionLevel, leafNodes); }