static void addTree(BlockManager blockManager, int baseX, int baseY, int baseZ) { int treeHeight = FakeRandom.Range(10, 15); float radius = FakeRandom.Range(3, 6); for (int y = 0; y < treeHeight; y++) { setBlock(blockManager, baseX + 0, baseY + y, baseZ + 0, (short)Game.BlockType.Log); } for (int x = -5; x < 6; x++) { for (int y = 4; y < treeHeight + treeHeight / 2; y++) { for (int z = -5; z < 6; z++) { int gx = baseX + x; int gy = baseY + y; int gz = baseZ + z; float a = 1 - (x * x + (y - treeHeight) * (y - treeHeight) * 0.5f + z * z) / (radius * radius) - ((y - treeHeight) / (float)treeHeight) * 1.1f; if (getBlock(blockManager, gx, gy, gz) == (short)BlockTypeEnum.Air) { //if (a + getPerlinNoise3D(gx * 0.35, gy * 0.35, gz * 0.35) * 0.5 < 1){ if (a + UnityEngine.Random.Range(-0.1f, 0.1f) > 0.5f) { setBlock(blockManager, gx, gy, gz, (short)Game.BlockType.Leaves); } } } } } }
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); }
public static List <HouseItem> GenerateItems(FloorType[,] layout, int[,] distanceToWall) { int w = layout.GetLength(0); int h = layout.GetLength(1); List <HouseItem> rlt = new List <HouseItem>(); for (int i = 0; i < w; i++) { for (int j = 0; j < h; j++) { if (itemsConfig.ContainsKey(layout[i, j]) && distanceToWall[i, j] == 1) { if (FakeRandom.Range01() < 0.3f) { List <GameItemType> items = itemsConfig[layout[i, j]]; GameItemType randomItem = items[FakeRandom.Range(0, items.Count)]; rlt.Add(new HouseItem(new VecInt3(i, 1, j), randomItem)); } } } } return(rlt); }
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); }
public static Game.BlockType[, ,] CreateBuilding(FloorType[,] layout, bool addRoof) { int w = layout.GetLength(0); int h = 7; int roofHeight = 8; int l = layout.GetLength(1); Game.BlockType[, ,] rlt = new Game.BlockType[w, h + roofHeight, l]; for (int i = 0; i < w; i++) { for (int j = 0; j < l; j++) { FloorType floor = layout[i, j]; FloorType left = i == 0 ? FloorType.Out : layout[i - 1, j]; FloorType right = i == w - 1 ? FloorType.Out : layout[i + 1, j]; FloorType back = j == 0 ? FloorType.Out : layout[i, j - 1]; FloorType front = j == l - 1 ? FloorType.Out : layout[i, j + 1]; if (floor == FloorType.Out) { if (left == FloorType.DoorLeft) { rlt[i, 0, j] = Game.BlockType.StairRight; } else if (right == FloorType.DoorRight) { rlt[i, 0, j] = Game.BlockType.StairLeft; } else if (back == FloorType.DoorDown) { rlt[i, 0, j] = Game.BlockType.StairFront; } else if (front == FloorType.DoorUp) { rlt[i, 0, j] = Game.BlockType.StairBack; } //|| right == FloorType.DoorRight || up == FloorType.DoorUp || down == FloorType.DoorDown) { // rlt[i, 0, j] = Game.BlockType.WoolColoredBlack; //} } else if (floor == FloorType.Wall || floor == FloorType.Window || HouseLayout.IsDoor(floor)) { for (int k = 0; k < h; k++) { if (left == FloorType.Out) { rlt[i, k, j] = Game.BlockType.StoneBrickWhiteWall1; } else if (right == FloorType.Out) { rlt[i, k, j] = Game.BlockType.StoneBrickWhiteWall0; } else if (front == FloorType.Out) { rlt[i, k, j] = Game.BlockType.StoneBrickWhiteWall4; } else if (back == FloorType.Out) { rlt[i, k, j] = Game.BlockType.StoneBrickWhiteWall5; } else { rlt[i, k, j] = Game.BlockType.WhiteStone; } } if (floor == FloorType.Window) { for (int k = 3; k < 5; k++) { rlt[i, k, j] = Game.BlockType.Air; } } else if (HouseLayout.IsDoor(floor)) { rlt[i, 0, j] = Game.BlockType.WoolColoredBlack; for (int k = 1; k < 5; k++) { rlt[i, k, j] = Game.BlockType.Air; } } } else { if (floor == FloorType.Kitchen || floor == FloorType.Bathroom) { rlt[i, 0, j] = Game.BlockType.StoneSlab; } else { rlt[i, 0, j] = Game.BlockType.WoodFloor; } } } } //生成屋顶 if (addRoof) { bool[,] blocks = new bool[w, l]; bool[,] blocksOld = new bool[w, l]; for (int i = 0; i < w; i++) { for (int j = 0; j < l; j++) { blocks[i, j] = layout[i, j] != FloorType.Out; blocksOld[i, j] = blocks[i, j]; } } for (int i = 1; i < w - 1; i++) { for (int j = 1; j < l - 1; j++) { blocks[i, j] = blocksOld[i, j] || blocksOld[i - 1, j] || blocksOld[i, j - 1] || blocksOld[i + 1, j] || blocksOld[i, j + 1] || blocksOld[i - 1, j - 1] || blocksOld[i - 1, j + 1] || blocksOld[i + 1, j - 1] || blocksOld[i + 1, j + 1]; } } for (int i = 0; i < w; i++) { for (int j = 0; j < l; j++) { blocksOld[i, j] = blocks[i, j]; } } Game.BlockType[] roofTypes = { Game.BlockType.HardenedClayStainedBlue, Game.BlockType.RedSand }; Game.BlockType roofType = roofTypes[FakeRandom.Range(0, roofTypes.Length)]; for (int k = 0; k < roofHeight; k++) { for (int i = 0; i < w; i++) { for (int j = 0; j < l; j++) { if (blocks[i, j]) { if (k == 0) { rlt[i, k + h, j] = layout[i, j] == FloorType.Out ? roofType : Game.BlockType.WhiteStone; } else { rlt[i, k + h, j] = roofType; } } } } bool[,] temp = blocksOld; blocksOld = blocks; blocks = temp; for (int i = 1; i < w - 1; i++) { for (int j = 1; j < l - 1; j++) { blocks[i, j] = blocksOld[i, j] && blocksOld[i - 1, j] && blocksOld[i, j - 1] && blocksOld[i + 1, j] && blocksOld[i, j + 1]; } } } } return(rlt); }