public BSPRoom(Vector2 position, Vector2 size, int degree) { Position = position; Size = size; Left = null; Right = null; Degree = degree; }
public TreeNode(Rect p_rect, TreeNode p_parent) { rect = p_rect; parent = p_parent; //Add Room if (p_parent != null) { room = new BSPRoom(rect); } }
public Vector3 GetPointInRoom(int roomIndex) { BSPRoom room = finalRooms[roomIndex]; int x, y; do { x = (int)(room.Position.x + Random.Range(1, room.Size.x - 1)); y = (int)(room.Position.y + Random.Range(1, room.Size.y - 1)); } while (tileMap[x, y] != 0); return(new Vector3(x, 0.0f, y)); }
public void Divide() { room = null; //If is alraedy divide if (leafs.Count > 0) { foreach (TreeNode node in leafs) { node.Divide(); } } else { Rect[] rooms = GetDivideRoomSize(); leafs.Add(new TreeNode(rooms[0], this)); leafs.Add(new TreeNode(rooms[1], this)); } }
private IEnumerator Spawn(float p_delayTime, List <AIUnit> p_inactiveUnits, BSPRoom p_bspRoom) { yield return(new WaitForSeconds(p_delayTime)); List <Node> emptyNodes = _tilemapReader.GetEmptyNode(); if (emptyNodes != null && emptyNodes.Count > 0) { int randomSpawnUnit = Random.Range(0, 3); for (int i = 0; i < randomSpawnUnit; i++) { if (p_inactiveUnits.Count > 0) { AIUnit unit = p_inactiveUnits[0]; Node randomNode = emptyNodes[Random.Range(0, emptyNodes.Count)]; int randomXIndex = Random.Range(0, Mathf.RoundToInt(p_bspRoom.spaceRect.width)); int randomYIndex = Random.Range(0, Mathf.RoundToInt(p_bspRoom.spaceRect.height)); unit.transform.position = new Vector2(randomXIndex + p_bspRoom.spaceRect.x, randomYIndex + p_bspRoom.spaceRect.y); unit.gameObject.SetActive(true); unit.SetUp(waveIndex.ToString(), projectileHolder, player.transform); unit.OnDestroy += OnAIUnitDestroy; total_aiUnit.Add(unit); p_inactiveUnits.RemoveAt(0); } } } float randomDelayTime = Random.Range(0.3f, 3f); if (p_inactiveUnits.Count > 0) { StartCoroutine(Spawn(randomDelayTime, p_inactiveUnits, p_bspRoom)); } }
public void RenderTile(Vector2Int dungeonSize, List <BSPMapComponent> bspComponents) { map_offset = new Vector2Int(Mathf.RoundToInt(-dungeonSize.x), Mathf.RoundToInt(-dungeonSize.y)); dungeonFullSize = new Vector2Int(dungeonSize.x * 2, dungeonSize.y * 2); //1 = wall , 0 = empty mapDetailData = new BSPTile[dungeonFullSize.x, dungeonFullSize.y]; FloodFillMap(dungeonFullSize, map_offset); for (int i = 0; i < bspComponents.Count; i++) { for (float x = bspComponents[i].spaceRect.xMin; x < bspComponents[i].spaceRect.xMax; x++) { for (float y = bspComponents[i].spaceRect.yMin; y < bspComponents[i].spaceRect.yMax; y++) { int xIndex = Mathf.RoundToInt(dungeonSize.x + x); int yIndex = Mathf.RoundToInt(dungeonSize.y + y); mapDetailData[xIndex, yIndex] = new BSPTile(xIndex, yIndex, xIndex + map_offset.x, yIndex + map_offset.y, "0"); mapDetailData[xIndex, yIndex].bspComponent = bspComponents[i]; if (bspComponents[i].GetType() == typeof(BSPRoom)) { BSPRoom room = (BSPRoom)bspComponents[i]; for (int d = 0; d < room.doorPosition.Count; d++) { Vector2Int offsetPos = room.doorPosition[d] + this.bspMap.dungeonSize; //Debug.Log(offsetPos.x +", "+ offsetPos.y); //mapData[offsetPos.x, offsetPos.y] = "1"; } } } } } RenderToWorldCanvas(map_offset, dungeonFullSize, mapDetailData); }
private void LinkCorridorBetween(BSPRoom left, BSPRoom right) { Rect lroom = left.spaceRect; Rect rroom = right.spaceRect; // Debug.Log("Creating corridor(s) between " + left.debugId + "(" + lroom + ") and " + right.debugId + " (" + rroom + ")"); // attach the corridor to a random point in each room Vector2 lpoint = new Vector2(Mathf.FloorToInt(Random.Range(lroom.x + 1, lroom.xMax - 1)), Mathf.FloorToInt(Random.Range(lroom.y + 1, lroom.yMax - 1))); Vector2 rpoint = new Vector2(Mathf.FloorToInt(Random.Range(rroom.x + 1, rroom.xMax - 1)), Mathf.FloorToInt(Random.Range(rroom.y + 1, rroom.yMax - 1))); //Debug.Log("lPoint " + lpoint +", rPoint " + rpoint); // always be sure that left point is on the left to simplify the code if (lpoint.x > rpoint.x) { Vector2 temp = lpoint; lpoint = rpoint; rpoint = temp; } int w = (int)(lpoint.x - rpoint.x); int h = (int)(lpoint.y - rpoint.y); int corridorSize = 50; // if the points are not aligned horizontally if (w != 0) { // choose at random to go horizontal then vertical or the opposite if (Random.Range(0, 1) > 2) { // add a corridor to the right corridors.Add(new BSPCorridor(new Rect(lpoint.x, lpoint.y, Mathf.Abs(w) + 1, corridorSize))); // if left point is below right point go up // otherwise go down if (h < 0) { corridors.Add(new BSPCorridor(new Rect(rpoint.x, lpoint.y, corridorSize, Mathf.Abs(h)))); } else { corridors.Add(new BSPCorridor(new Rect(rpoint.x, lpoint.y, corridorSize, -Mathf.Abs(h)))); } } else { // go up or down if (h < 0) { corridors.Add(new BSPCorridor(new Rect(lpoint.x, lpoint.y, corridorSize, Mathf.Abs(h)))); } else { corridors.Add(new BSPCorridor(new Rect(lpoint.x, rpoint.y, corridorSize, Mathf.Abs(h)))); } // then go right corridors.Add(new BSPCorridor(new Rect(lpoint.x, rpoint.y, Mathf.Abs(w) + 1, corridorSize))); } } else { //假設 房間的x軸對齊的話 //根據y軸的差距 決定往下 或 往上走 if (h < 0) { corridors.Add(new BSPCorridor(new Rect((int)lpoint.x, (int)lpoint.y, corridorSize, Mathf.Abs(h)))); } else { corridors.Add(new BSPCorridor(new Rect((int)rpoint.x, (int)rpoint.y, corridorSize, Mathf.Abs(h)))); } } foreach (BSPCorridor corridor in corridors) { //Debug.Log ("corridor: " + corridor.spaceRect); } }
public void Split(int maxDegree, ref List <BSPRoom> rooms) { float split_chance = 0.75f + (maxDegree - Degree) * 0.1f; if (Degree >= maxDegree || Random.value >= split_chance) { return; } bool can_split_vert = Size.x > 2 * FloorGenerator.MinRoomSize.x + 3; bool can_split_hori = Size.y > 2 * FloorGenerator.MinRoomSize.y + 3; Vector2 left_start = Vector2.zero; Vector2 right_start = Vector2.zero; Vector2 left_size = FloorGenerator.MinRoomSize; Vector2 right_size = FloorGenerator.MinRoomSize; if (can_split_vert && can_split_hori) { SplitOrientation = (Orientation)Random.Range(0, 2); } else if (can_split_vert) { SplitOrientation = Orientation.Vertical; } else if (can_split_hori) { SplitOrientation = Orientation.Horizontal; } else { return; } if (SplitOrientation == Orientation.Vertical) { int split = Mathf.RoundToInt( Random.Range( FloorGenerator.MinRoomSize.x + 1, Size.x - FloorGenerator.MinRoomSize.x - 1)); left_start = Position; left_size = new Vector2(split, Size.y); right_start = new Vector2(left_start.x + left_size.x + 1, left_start.y); right_size = new Vector2(Size.x - split - 1, Size.y); } else if (SplitOrientation == Orientation.Horizontal) { int split = Mathf.RoundToInt( Random.Range( FloorGenerator.MinRoomSize.y + 1, Size.y - FloorGenerator.MinRoomSize.y - 1)); left_start = Position; left_size = new Vector2(Size.x, split); right_start = new Vector2(left_start.x, left_start.y + left_size.y + 1); right_size = new Vector2(Size.x, Size.y - split - 1); } rooms.Remove(this); Left = new BSPRoom(left_start, left_size, Degree + 1); Right = new BSPRoom(right_start, right_size, Degree + 1); rooms.Add(Left); rooms.Add(Right); Left.Split(maxDegree, ref rooms); Right.Split(maxDegree, ref rooms); }
public int[,] CreateTilemap() { BSPRoom root_room = new BSPRoom(Vector2.zero, FloorSize, 0); List <BSPRoom> rooms = new List <BSPRoom>(); root_room.Split(Degree, ref rooms); finalRooms = new List <BSPRoom>(rooms); int[,] tile_map = new int[(int)FloorSize.x, (int)FloorSize.y]; foreach (BSPRoom room in rooms) { int top = (int)room.Position.y; int bottom = top + (int)room.Size.y - 1; int left = (int)room.Position.x; int right = left + (int)room.Size.x - 1; //Create walls for (int x = 0; x < room.Size.x; x++) { tile_map[left + x, top] = 1; tile_map[left + x, bottom] = 1; } for (int y = 1; y < room.Size.y - 1; y++) { tile_map[left, top + y] = 1; tile_map[right, top + y] = 1; } //Create doors int door_count = Random.Range(1, 3); for (int i = 0; i < door_count; i++) { switch (Random.Range(0, 4)) { //left case 0: if (left != 0) { tile_map[left, top + Random.Range(1, bottom - top - 1)] = 0; } else { i--; } break; //right case 1: if (right != FloorSize.x - 1) { tile_map[right, top + Random.Range(1, bottom - top - 1)] = 0; } else { i--; } break; //top case 2: if (top != 0) { tile_map[left + Random.Range(1, right - left - 1), top] = 0; } else { i--; } break; //bottom case 3: if (bottom != FloorSize.y - 1) { tile_map[left + Random.Range(1, right - left - 1), bottom] = 0; } else { i--; } break; } } } //Create main border for (int x = 0; x < FloorSize.x; x++) { tile_map[x, 0] = 1; tile_map[x, (int)FloorSize.y - 1] = 1; } for (int y = 1; y < FloorSize.y - 1; y++) { tile_map[0, y] = 1; tile_map[(int)FloorSize.x - 1, y] = 1; } tileMap = new int[(int)FloorSize.x, (int)FloorSize.y]; System.Array.Copy(tile_map, tileMap, tile_map.Length); return(tile_map); }