public static List <Vec3i> AllPointsInside(this CaveRoom room) { List <Vec3i> inside = new List <Vec3i>(100); int check = 0; int valid = 0; for (int x = (int)-room.Size.x; x <= room.Size.x; x++) { for (int y = (int)-room.Size.y; y <= room.Size.y; y++) { for (int z = (int)-room.Size.z; z <= room.Size.z; z++) { Vec3i pos = new Vec3i(room.Position.x + x, room.Position.y + y, room.Position.z + z); check++; if (room.PointInside(pos)) { valid++; inside.Add(pos); } } } } Debug.Log("Chcked " + check); Debug.Log("Valid " + valid); return(inside); }
public static bool PointInside(this CaveRoom room, Vec3i point, float noise = 1) { float x_a = (room.Position.x - point.x) * (room.Position.x - point.x) / (room.Size.x * room.Size.x); float y_a = (room.Position.y - point.y) * (room.Position.y - point.y) / (room.Size.y * room.Size.y); float z_a = (room.Position.z - point.z) * (room.Position.z - point.z) / (room.Size.z * room.Size.z); return(x_a + y_a + z_a <= noise); }
//创建两个房间的通道。 private void CreatePassage(CaveRoom roomA, CaveRoom roomB, CaveCoord tileA, CaveCoord tileB) { CaveRoom.ConnectRooms(roomA, roomB); //Debug.DrawLine(CoordToWorldPoint(tileA), CoordToWorldPoint(tileB), Color.green, 100); List <CaveCoord> line = GetLine(tileA, tileB); foreach (CaveCoord coord in line) { DrawCircle(coord, passageWidth); } }
public static LevelBuildData CreateNewLevel(Theme theme) { currentTheme = theme; levelBuildData = new LevelBuildData(); CaveRoom.CreateBaseLevel(levelBuildData, theme); SpawnEnemies(); AddSpawnRoom(); AddBossCatwalk(); return(levelBuildData); }
public void SetupRoom(int roomColumns, int roomRows, int roomSmoothness, float roomWallQuant, int roomMinLenght, int roomMaxLenght, RoomType roomType, int roomChanceOfCorridor) { columns = roomColumns; rows = roomRows; smoothness = roomSmoothness; wallQuant = roomWallQuant; minLenght = roomMinLenght; maxLenght = roomMaxLenght; chanceOfCorridor = roomChanceOfCorridor; InitializeTilesArray(); switch (roomType) { case RoomType.Cave: Debug.Log("Fazendo Sala tipo Caverna"); CaveRoom caveRoom = new CaveRoom(); caveRoom.SetupRoom(columns, rows, smoothness, wallQuant); tiles = caveRoom.tiles; break; case RoomType.Cross: Debug.Log("Fazendo Sala tipo Cross"); CrossRoom crossRoom = new CrossRoom(); crossRoom.SetupRoom(columns, rows, minLenght, maxLenght); tiles = crossRoom.tiles; break; default: Debug.Log("Caso Default: não deu certo"); break; } GetHighestXandY(); GetLowestXandY(); Debug.Log("Sala criada. Tipo: " + roomType.ToString()); Debug.Log("Dimensões: " + lowestX.ToString() + " " + lowestY.ToString() + " " + highestX.ToString() + " " + highestY.ToString()); AddDoors(); //Chance de spawnar um corredor /*if (Random.Range(0, 100) < chanceOfCorridor) * { * AddCorridor(); * GetHighestXandY(); * GetLowestXandY(); * }*/ }
public CaveRoom GenerateRoom(Vec3i position, Vector3 size) { CaveRoom cr = new CaveRoom(position, size, new Vec3i(0, 0, 0), new Vec3i(0, 0, 0)); List <Vec3i> points = cr.AllPointsInside(); float perlinLim = Mathf.Clamp(GenRan.GaussianFloat(0.4f, 0.2f), 0.1f, 0.5f); foreach (Vec3i v in points) { float perlin = GenRan.PerlinNoise3D(v, 0.1f); if (perlin < 0.6f) { ClearVoxelNode(v.x, v.y, v.z); } } return(cr); }
private List <CaveRoom> OrderRooms(List <CaveRoom> rooms) { List <CaveRoom> orderedRooms = new List <CaveRoom>(); orderedRooms.Add(rooms[0]); rooms.Remove(rooms[0]); int curCount = rooms.Count; CaveRoom curRoom = orderedRooms[0]; for (int i = 0; i < curCount - 1; i++) { int currentIndexDistance = -1; int currentRoomIndex = -1; for (int j = 0; j < rooms.Count; j++) { if (currentRoomIndex == -1) { currentRoomIndex = i; currentIndexDistance = curRoom.Position.SquareDist(rooms[j].Position); } else { int jDist = curRoom.Position.SquareDist(rooms[j].Position); if (jDist < currentIndexDistance) { currentIndexDistance = jDist; currentRoomIndex = j; } } } orderedRooms.Add(rooms[currentRoomIndex]); curRoom = rooms[currentRoomIndex]; rooms.RemoveAt(currentRoomIndex); } return(orderedRooms); }
//连接各个房间。每个房间两两比较,找到最近房间(相对前一个房间)连接之,对第二个房间来说不一定就是最近的。 //第二个参数为False时,第一步操作:为所有房间都连接到最近房间。 //第二个参数为True时,第二步操作:就是把所有房间都连接到主房间。 private void ConnectClosestRooms(List <CaveRoom> allRooms, bool forceAccessibilityFromMainRoom = false) { #region 属于第二步操作:roomListA 是还没连接到主房间的房间队列, roomListB 是已经连接到房间B的队列。 List <CaveRoom> roomListA = new List <CaveRoom>(); List <CaveRoom> roomListB = new List <CaveRoom>(); if (forceAccessibilityFromMainRoom) //是否需要强制连接(直接或间接)到主房间。 { foreach (CaveRoom room in allRooms) { if (room.isAccessibleFromMainRoom) { roomListB.Add(room); //已经连接到主房间的加到ListB。 } else { roomListA.Add(room); //没有连接到主房间的加到ListA。为空时将结束递归。 } } } else { roomListA = allRooms; roomListB = allRooms; } #endregion int bestDistance = 0; CaveCoord bestTileA = new CaveCoord(); CaveCoord bestTileB = new CaveCoord(); CaveRoom bestRoomA = new CaveRoom(); CaveRoom bestRoomB = new CaveRoom(); bool possibleConnectionFound = false; foreach (CaveRoom roomA in roomListA) //遍历没连接到主房间的ListA。 { if (!forceAccessibilityFromMainRoom) //第一步:如果没有要求连到主房间。 { possibleConnectionFound = false; //那就不能完成连接任务,需要不止一次连接。 if (roomA.connectedRooms.Count > 0) //有连接房间,跳过,继续找下一个连接房间。 { continue; } } #region 遍历roomListB,找到距离当前roomA最近的roomB。 foreach (CaveRoom roomB in roomListB) { if (roomA == roomB || roomA.IsConnected(roomB)) { continue; } for (int tileIndexA = 0; tileIndexA < roomA.edgeTiles.Count; tileIndexA++) { for (int tileIndexB = 0; tileIndexB < roomB.edgeTiles.Count; tileIndexB++) { CaveCoord tileA = roomA.edgeTiles[tileIndexA]; CaveCoord tileB = roomB.edgeTiles[tileIndexB]; int distanceBetweenRooms = (int)tileA.SqrMagnitude(tileB); //如果找到更近的(相对roomA)房间,更新最短路径。 if (distanceBetweenRooms < bestDistance || !possibleConnectionFound) { bestDistance = distanceBetweenRooms; possibleConnectionFound = true; bestTileA = tileA; bestTileB = tileB; bestRoomA = roomA; bestRoomB = roomB; } } } } #endregion //第一步:找到新的两个连接房间,但是没有要求连接主房间。创建通道。 if (possibleConnectionFound && !forceAccessibilityFromMainRoom) { CreatePassage(bestRoomA, bestRoomB, bestTileA, bestTileB); } } //第一步到第二步:当连接完所有房间,但是还没有要求全部连接到主房间,那就开始连接到主房间。 if (!forceAccessibilityFromMainRoom) { ConnectClosestRooms(allRooms, true); } //第二步:当成功找到能连接到主房间,通路,继续找一下个能需要连到主房间的房间。 if (possibleConnectionFound && forceAccessibilityFromMainRoom) { CreatePassage(bestRoomA, bestRoomB, bestTileA, bestTileB); ConnectClosestRooms(allRooms, true); } }