public static Room CreateMinRoom(ref FloorType[,] blocks, BlueprintNode blueprint, VecInt2 doorPos, Direction doorDir) { Room room = new Room(doorPos, blueprint.type, FakeRandom.Range(blueprint.sizeMin, blueprint.sizeMax)); room.range = GetRange(doorPos, blueprint.edgeLenghtMin, blueprint.edgeLenghtMin, doorDir); room.dir = doorDir; Array2DTool.SetRange(blocks, room.range, blueprint.type); Array2DTool.SetOne(blocks, room.doorPos.x, room.doorPos.y, doorType[(int)room.dir]); return(room); }
public static bool Extend(ref FloorType[,] blocks, Room room) { Direction[] dirs = GetExtendDirections(room.dir); dirs = RandomSort(dirs, FakeRandom.Range(0, 6)); for (int i = 0; i < 3; i++) { Direction dir = dirs[i]; if (dir == Direction.Left) { RectInt range = new RectInt(room.range.x - 1, room.range.y, 1, room.range.h); if (range.x >= Gap && Array2DTool.RangeIsAll(blocks, range, FloorType.Out)) //边上留空Gap空隙,为了计算方便 { room.range.x -= 1; room.range.w += 1; Array2DTool.SetRange(blocks, range, room.type); return(true); } } else if (dir == Direction.Right) { RectInt range = new RectInt(room.range.x + room.range.w, room.range.y, 1, room.range.h); if (range.x < blocks.GetLength(0) - Gap && Array2DTool.RangeIsAll(blocks, range, FloorType.Out)) { room.range.w += 1; Array2DTool.SetRange(blocks, range, room.type); return(true); } } else if (dir == Direction.Down) { RectInt range = new RectInt(room.range.x, room.range.y - 1, room.range.w, 1); if (range.y >= Gap && Array2DTool.RangeIsAll(blocks, range, FloorType.Out)) { room.range.y -= 1; room.range.h += 1; Array2DTool.SetRange(blocks, range, room.type); return(true); } } else if (dir == Direction.Up) { RectInt range = new RectInt(room.range.x, room.range.y + room.range.h, room.range.w, 1); if (range.y < blocks.GetLength(1) - Gap && Array2DTool.RangeIsAll(blocks, range, FloorType.Out)) { room.range.h += 1; Array2DTool.SetRange(blocks, range, room.type); return(true); } } } return(false); }
private static List <Rect> GetLayerRects(bool[,] layerBlocks) { int size = layerBlocks.GetLength(0); List <Rect> rects = new List <Rect>(); int[,] lineEnd = new int[size, size];//如果水平方向连续格子最后一格,则是连续格子的长度,否则为0 for (int y = 0; y < size; y++) { int startX = 0; for (int x = 0; x <= size; x++) { bool cur = x == size ? false : layerBlocks[x, y]; bool left = x == 0 ? false : layerBlocks[x - 1, y]; if (cur && !left) { startX = x; } else if (!cur && left) { lineEnd[x - 1, y] = x - startX; } } } for (int y = 0; y < size; y++) { for (int x = 0; x < size; x++) { int curEndNum = lineEnd[x, y];//当前记录格子结尾数 if (curEndNum != 0) { for (int ty = y + 1; ty <= size; ty++) { int nextLineEndNum = ty == size ? 0 : lineEnd[x, ty];//下一行的结尾数 if (nextLineEndNum != curEndNum) { RectInt rectInt = new RectInt(x - curEndNum + 1, y, curEndNum, ty - y); Array2DTool.SetRange(lineEnd, x, y, 1, ty - y, 0); rects.Add(new Rect(rectInt.x / (float)size, rectInt.y / (float)size, rectInt.w / (float)size, rectInt.h / (float)size)); break; } } } } } return(rects); }
// Use this for initialization void Start() { float startTime = Time.realtimeSinceStartup; for (int i = 0; i < 10; i++) { FloorType[,] layout = HouseLayout.CreateHouse(HouseType.Small, Direction.Down); FloorType[,] lineMode = LayoutToBuilding.LayoutCellToLine(layout); LayoutToBuilding.AddWindow(lineMode); int[,] distanceToWall = LayoutToBuilding.GetDistanceToWall(lineMode); //Game.BlockType[,,] blocks = LayoutToBuilding.CreateBuilding(lineMode,true); string s = BuildingDebugTools.GetLayoutString(lineMode); Debug.Log(s); string dtw = Array2DTool.GetDebugStringFormat(distanceToWall, "{0:00}", ","); Debug.Log(dtw); } Debug.Log("time = " + (Time.realtimeSinceStartup - startTime)); }
public static List <Room> CreateChildren(ref FloorType[,] blocks, Room room, BlueprintNode blueprint) { List <Room> children = new List <Room>(); for (int i = 0; i < blueprint.children.Count; i++) { BlueprintNode childBlueprint = blueprint.children[i]; VecInt2 childDoorPos = new VecInt2(0, 0); Direction childDoorDir = Direction.Left; bool bValid = false; Direction[] dirs = GetExtendDirections(room.dir); //得到可以产生门的方向 dirs = RandomSort(dirs, FakeRandom.Range(0, 10000)); //打乱顺序 foreach (Direction d in dirs) { for (int t = 0; t < 5; t++) { childDoorPos = GetRandomChildDoorPos(room.range, d);//在随机位置生生成一个门 childDoorDir = d; RectInt childMinRange = GetRange(childDoorPos, childBlueprint.edgeLenghtMin, childBlueprint.edgeLenghtMin, d); if (Array2DTool.RangeIsAll(blocks, childMinRange, FloorType.Out)) //如果是空地 { bValid = true; //则找到了一个有效位置 break; } } if (bValid) { break; } } if (bValid) //如果找到了一个有效的位置 { Room childRoom = CreateMinRoom(ref blocks, childBlueprint, childDoorPos, childDoorDir); //在此位置生成一个最小房间 if (childRoom != null) { childRoom.blueprint = childBlueprint; children.Add(childRoom); } } } while (true) { bool bExtendOne = false; for (int i = 0; i < children.Count; i++) { if (children[i].GetCurrentSize() < children[i].targetSize) //如果房间大小还没到期望值 { bool bExtendOk = Extend(ref blocks, children[i]); //则往随机方向扩大一格 bExtendOne |= bExtendOk; } } if (!bExtendOne) //如果没有任何房间被扩大过,则退出循环 { break; } } //给扩展过的子房间产生下一级房间 for (int i = 0; i < children.Count; i++) { children[i].children = CreateChildren(ref blocks, children[i], children[i].blueprint); } return(children); }