public BlockInfo[,] RandCrossBlockInfoByChunk(ChunkInfoCross crossChunk) { var up = crossChunk.Up; var down = crossChunk.Down; var left = crossChunk.Left; var right = crossChunk.Right; return(RandCrossBlockInfo(up, down, left, right)); }
private static void BuildInitCross() { // 根据关卡描述的生成欲望尝试生成次数,公式如下 var tryBuildCrossTime = (LevelDescription.MaxChunkX * LevelDescription.MaxChunkY / 200.0 * LevelDescription.CrossRate); // 尝试生成路口,用来提供更平滑的道路连接 for (int i = 0; i < tryBuildCrossTime; i++) { var centerX = RNG.RandInt(Constant.OverBorderChunkSize, LevelDescription.MaxChunkX - 1 - LevelDescription.MaxRoomSize / 2 - Constant.OverBorderChunkSize); var centerY = RNG.RandInt(Constant.OverBorderChunkSize, LevelDescription.MaxChunkY - 1 - LevelDescription.MaxRoomSize / 2 - Constant.OverBorderChunkSize); // 检测是否被占据,如果否直接添加路口 if (ChunkMap[centerX, centerY].ChunkType == "None") { ChunkMap[centerX, centerY] = new ChunkInfoCross(centerX, centerY); } } }
private static void BuildInitRoom() { // 初始化房间记录 RoomGenerator.Reset(); // 根据关卡描述的生成欲望尝试生成次数,公式如下 var tryBuildRoomTime = (int)(LevelDescription.MaxChunkX * LevelDescription.MaxChunkY / 5.0 * LevelDescription.RoomRate); var tryBuildDoorTime = (int)(RNG.RandInt(2, 4) * LevelDescription.DoorRate); // 尝试生成房间 for (int i = 0; i < tryBuildRoomTime; i++) { // 禁止在边界一圈区块生成房间,因此排除边界点。房间向右上生长,因此右上保留空间 var centerX = RNG.RandInt(1 + Constant.OverBorderChunkSize, LevelDescription.MaxChunkX - 2 - LevelDescription.MaxRoomSize); var centerY = RNG.RandInt(1 + Constant.OverBorderChunkSize, LevelDescription.MaxChunkY - 2 - LevelDescription.MaxRoomSize); var roomInfo = WeightListUtils.HitWeightListByBinary(LevelDescription.RoomWeightList) as RoomChunkWeightInfo; // 保证目标区域为空 var flag = true; for (int x = centerX; x < centerX + roomInfo.X; x++) { for (int y = centerY; y < centerY + roomInfo.Y; y++) { if (ChunkMap[x, y].ChunkType != "None") { flag = false; } } } if (flag) { // 记录房间信息供后续生成 RoomGenerator.Add(centerX * Constant.ChunkSize, centerY * Constant.ChunkSize, (centerX + roomInfo.X) * Constant.ChunkSize, (centerY + roomInfo.Y) * Constant.ChunkSize); // 填充目标区域为房间区块 for (int x = centerX; x < centerX + roomInfo.X; x++) { for (int y = centerY; y < centerY + roomInfo.Y; y++) { ChunkMap[x, y] = new ChunkInfoRoom(); } } for (int j = 0; j < tryBuildDoorTime; j++) { var randDir = RNG.RandInt(1, 4); var randPos = 0; switch (randDir) { case 1: randPos = RNG.RandInt(0, roomInfo.X - 1); if ((ChunkMap[centerX + randPos, centerY + roomInfo.Y - 1] as ChunkInfoRoom).Dir != 0) { break; } (ChunkMap[centerX + randPos, centerY + roomInfo.Y - 1] as ChunkInfoRoom).Dir = 1; // 保证邻接房间下也会生成对应的门 if (ChunkMap[centerX + randPos, centerY + roomInfo.Y - 1 + 1] is ChunkInfoRoom) { (ChunkMap[centerX + randPos, centerY + roomInfo.Y - 1 + 1] as ChunkInfoRoom).Dir = 2; } // 否则在门口生成路口点 else { ChunkMap[centerX + randPos, centerY + roomInfo.Y - 1 + 1] = new ChunkInfoCross(centerX + randPos, centerY + roomInfo.Y - 1 + 1); } break; case 2: randPos = RNG.RandInt(0, roomInfo.X - 1); if ((ChunkMap[centerX + randPos, centerY] as ChunkInfoRoom).Dir != 0) { break; } (ChunkMap[centerX + randPos, centerY] as ChunkInfoRoom).Dir = 2; // 保证邻接房间下也会生成对应的门 if (ChunkMap[centerX + randPos, centerY - 1] is ChunkInfoRoom) { (ChunkMap[centerX + randPos, centerY - 1] as ChunkInfoRoom).Dir = 1; } // 否则在门口生成路口点 else { ChunkMap[centerX + randPos, centerY - 1] = new ChunkInfoCross(centerX + randPos, centerY - 1); } break; case 3: randPos = RNG.RandInt(0, roomInfo.Y - 1); if ((ChunkMap[centerX, centerY + randPos] as ChunkInfoRoom).Dir != 0) { break; } (ChunkMap[centerX, centerY + randPos] as ChunkInfoRoom).Dir = 3; // 保证邻接房间下也会生成对应的门 if (ChunkMap[centerX - 1, centerY + randPos] is ChunkInfoRoom) { (ChunkMap[centerX - 1, centerY + randPos] as ChunkInfoRoom).Dir = 4; } // 否则在门口生成路口点 else { ChunkMap[centerX - 1, centerY + randPos] = new ChunkInfoCross(centerX - 1, centerY + randPos); } break; case 4: randPos = RNG.RandInt(0, roomInfo.Y - 1); if ((ChunkMap[centerX + roomInfo.X - 1, centerY + randPos] as ChunkInfoRoom).Dir != 0) { break; } (ChunkMap[centerX + roomInfo.X - 1, centerY + randPos] as ChunkInfoRoom).Dir = 4; // 保证邻接房间下也会生成对应的门 if (ChunkMap[centerX + roomInfo.X - 1 + 1, centerY + randPos] is ChunkInfoRoom) { (ChunkMap[centerX + roomInfo.X - 1 + 1, centerY + randPos] as ChunkInfoRoom).Dir = 3; } // 否则在门口生成路口点 else { ChunkMap[centerX + roomInfo.X - 1 + 1, centerY + randPos] = new ChunkInfoCross(centerX + roomInfo.X - 1 + 1, centerY + randPos); } break; } } } } }
private static void ConnectCross() { var obstacleBuildTimeTotal = LevelDescription.ObstacleRate * 10; for (int buildTime = 0; buildTime <= obstacleBuildTimeTotal; buildTime++) { // 一种简易的填充方式,遍历所有相邻四点,若均为道路或空则随机生成障碍,合法的新障碍不能分割连接性 for (int i = Constant.OverBorderChunkSize; i < LevelDescription.MaxChunkX - Constant.OverBorderChunkSize; i++) { for (int j = Constant.OverBorderChunkSize; j < LevelDescription.MaxChunkY - Constant.OverBorderChunkSize; j++) { // 检查是否为空旷四区块 var isOpenSpace = true; for (int deltaI = 0; deltaI < 2; deltaI++) { for (int deltaJ = 0; deltaJ < 2; deltaJ++) { var chunkType = ChunkMap[i + deltaI, j + deltaJ].ChunkType; if (chunkType == "Room" || chunkType == "Obstacle" || chunkType == "OverNone") { isOpenSpace = false; } } } if (isOpenSpace) { // 随机选择一个区块 var delta = RNG.RandInt(0, 3); var deltaI = delta / 2; var deltaJ = delta % 2; // 检测新障碍是否合法,只要毗邻的8格子之存在一个连接体 var PosOffsetOfPoint = new Tuple <int, int> [9]; PosOffsetOfPoint[0] = new Tuple <int, int>(-1, -1); PosOffsetOfPoint[1] = new Tuple <int, int>(-1, 0); PosOffsetOfPoint[2] = new Tuple <int, int>(-1, 1); PosOffsetOfPoint[3] = new Tuple <int, int>(0, 1); PosOffsetOfPoint[4] = new Tuple <int, int>(1, 1); PosOffsetOfPoint[5] = new Tuple <int, int>(1, 0); PosOffsetOfPoint[6] = new Tuple <int, int>(1, -1); PosOffsetOfPoint[7] = new Tuple <int, int>(0, -1); PosOffsetOfPoint[8] = new Tuple <int, int>(-1, -1); var crossToObstacleCount = 0; for (int p = 0; p < 8; p++) { var nowX = i + deltaI + PosOffsetOfPoint[p].Item1; var nowY = j + deltaJ + PosOffsetOfPoint[p].Item2; var nowChunk = ChunkMap[nowX, nowY]; var nowChunkType = nowChunk.ChunkType; var nextX = i + deltaI + PosOffsetOfPoint[p + 1].Item1; var nextY = j + deltaJ + PosOffsetOfPoint[p + 1].Item2; var nextChunkType = ChunkMap[nextX, nextY].ChunkType; if ((nowChunkType == "None" || nowChunkType == "Cross") && (nextChunkType == "Obstacle" || nextChunkType == "Room" || nextChunkType == "OverNone")) { crossToObstacleCount++; } // 禁止在门附近生成障碍 if ((nowChunkType == "Room" && (nowChunk as ChunkInfoRoom).Dir != 0)) { crossToObstacleCount += 10; } } if (crossToObstacleCount < 2) { ChunkMap[i + deltaI, j + deltaJ] = new ChunkInfoObstacle(i + deltaI, j + deltaJ); } } } } } // 将剩余空白用道路填充 for (int i = Constant.OverBorderChunkSize; i < LevelDescription.MaxChunkX - Constant.OverBorderChunkSize; i++) { for (int j = Constant.OverBorderChunkSize; j < LevelDescription.MaxChunkY - Constant.OverBorderChunkSize; j++) { if (ChunkMap[i, j].ChunkType == "None") { ChunkMap[i, j] = new ChunkInfoCross(i, j); } } } }