IEnumerator GenerateMap(Map map, Location?endTitleLocation) { // начало создание главной дороги которая может периходить из карты в карту bool isFinish = false; Location vectorRoad; Vector2 lastDiraction; if (endTitleLocation == null) // если у нас на прошлой карте не было перехода дороги на новую карту { if (Random.value >= 0.5) { map.cells[sizeMapX - 1, 0] = TypeOfCell.Road; vectorRoad = new Location(sizeMapX - 1, 0); } else { map.cells[(0), 0] = TypeOfCell.Road; vectorRoad = new Location(0, 0); } lastDiraction = Vector2.zero; } else { map.cells[endTitleLocation.Value.x, 0] = TypeOfCell.Road; vectorRoad = new Location(endTitleLocation.Value.x, 0); lastDiraction = Vector2.left; } // зацикливаем и случайно герерируем дорогу while (!isFinish) { if (lastDiraction == Vector2.left || lastDiraction == Vector2.right) { lastDiraction = Vector2.up; } else if (lastDiraction == Vector2.up) { float rand = Random.value; if (rand < 0.45) { lastDiraction = Vector2.up; } else if (rand < 0.75) { lastDiraction = Vector2.left; } else { lastDiraction = Vector2.right; } } else if (lastDiraction == Vector2.zero) { if (vectorRoad.x == 0) { lastDiraction = Vector2.right; } else { lastDiraction = Vector2.left; } } int duration = Random.Range(2, 4); bool isWentAbroad = false; while (duration != 0) { if (lastDiraction == Vector2.left) { if ((vectorRoad.x - 1) >= 0) { map.cells[(vectorRoad.x - 1), (vectorRoad.y)] = TypeOfCell.Road; vectorRoad.x--; if (vectorRoad.x == 0) { isWentAbroad = true; } } else { isWentAbroad = true; break; } } else if (lastDiraction == Vector2.up) { if ((vectorRoad.y + 1) < sizeMapY) { map.cells[(vectorRoad.x), (vectorRoad.y + 1)] = TypeOfCell.Road; vectorRoad.y++; } else { isFinish = true; map.endLocationRoad = vectorRoad; break; } } else if (lastDiraction == Vector2.right) { if ((vectorRoad.x + 1) < sizeMapX) { map.cells[(vectorRoad.x + 1), (vectorRoad.y)] = TypeOfCell.Road; vectorRoad.x++; if (vectorRoad.x == (sizeMapX - 1)) { isWentAbroad = true; } } else { isWentAbroad = true; break; } } duration--; } if (isWentAbroad) { if ((vectorRoad.y + 2) < sizeMapY - 2) { if (Random.value >= 0.5) { map.cells[(sizeMapX - 1), (vectorRoad.y + 2)] = TypeOfCell.Road; vectorRoad.x = (sizeMapX - 1); vectorRoad.y += 2; } else { map.cells[(0), (vectorRoad.y + 2)] = TypeOfCell.Road; vectorRoad.x = 0; vectorRoad.y += 2; } lastDiraction = Vector2.zero; } else { isFinish = true; map.endLocationRoad = null; } } if (vectorRoad.y >= sizeMapY - 1) { isFinish = true; map.endLocationRoad = vectorRoad; } yield return(null); } // generate second road short roadLeft = 0; short roadRight = 0; for (int i = 0; i < sizeMapX; i++) { for (int j = 0; j < sizeMapY; j++) { if (map.cells[i, j] == TypeOfCell.Road) { if (i < (sizeMapX / 2) + 1) { roadLeft++; } else { roadRight++; } } } } float leftKoef = ((float)(roadLeft) / (roadLeft + roadRight)); byte forExit = 10; Location startLocation = new Location(0, 0); // счучайно генерируем точку и проверяем возможно ли там поставить дорогу while (forExit > 0) { if (Random.value >= leftKoef) { //left startLocation = new Location(Random.Range(1, (sizeMapX / 2) + 1), Random.Range(1, sizeMapY - 1)); } else { //right startLocation = new Location(Random.Range((sizeMapX / 2) + 1, sizeMapX - 1), Random.Range(1, sizeMapY - 1)); } CellInformation info = new CellInformation(map, startLocation, TypeOfCell.Road); if (info.IsAllEmpty() && map.cells[startLocation.x, startLocation.y] != TypeOfCell.Road) { map.cells[startLocation.x, startLocation.y] = TypeOfCell.SecondRoad; break; } else { forExit--; } } if (forExit == 0) { yield break; // если у нас не нашло такой точки где свободно то на это карте не будет дополнительной дороги } Location firstCellSecondRoad = new Location(); for (int rep = 0; rep < 2; rep++) // от точки проводим 2 случайно генерации в стороны ( ибо точка центр дороги. А нам нужно начало иконец дороги) { bool isEndGenerateSecondRoad = false; Vector2 roadDirection = Vector2.zero; bool isFirstTime = true; Location currentLocation = new Location(startLocation.x, startLocation.y); Location lastSecondRoad = new Location(currentLocation.x, currentLocation.y); if (rep == 1) { map.cells[startLocation.x, startLocation.y] = TypeOfCell.SecondRoad; map.cells[firstCellSecondRoad.x, firstCellSecondRoad.y] = TypeOfCell.SecondRoad; lastSecondRoad = firstCellSecondRoad; } while (!isEndGenerateSecondRoad) { CellInformation info = new CellInformation(map, currentLocation, TypeOfCell.SecondRoad); List <Vector2> random = new List <Vector2>(); int roadDuration = Random.Range(2, 5); if (!info.isUp && currentLocation.y < map.cells.GetLength(1) - 3) { random.Add(Vector2.up); roadDuration = Random.Range(2, map.cells.GetLength(1) - 2 - currentLocation.y + 1); } if (!info.isDown && currentLocation.y > 2) { random.Add(Vector2.down); roadDuration = Random.Range(2, currentLocation.y); } if (!info.isRight) { random.Add(Vector2.right); } if (!info.isLeft) { random.Add(Vector2.left); } roadDirection = random[Random.Range(0, random.Count)]; for (byte i = 0; i < roadDuration; i++) { CellInformation cell = new CellInformation(map, currentLocation, TypeOfCell.Road); CellInformation cellSecond = new CellInformation(map, currentLocation, TypeOfCell.SecondRoad); Location nextLoc = new Location(currentLocation.x + (int)roadDirection.x, (int)roadDirection.y + currentLocation.y); if ((currentLocation.y == 1 && roadDirection == Vector2.down) || (currentLocation.y == (map.cells.GetLength(1) - 2) && roadDirection == Vector2.up)) { break; } if (!cell.GetValueByVector(roadDirection) && !cellSecond.GetValueByVector(roadDirection) && !map.IsOutOfBounds(nextLoc)) { if (cell.IsBlockNear(roadDirection)) { map.cells[lastSecondRoad.x, lastSecondRoad.y] = TypeOfCell.Road; map.cells[currentLocation.x, currentLocation.y] = TypeOfCell.Road; isEndGenerateSecondRoad = true; break; } if (lastSecondRoad != currentLocation) { map.cells[lastSecondRoad.x, lastSecondRoad.y] = TypeOfCell.Road; } lastSecondRoad = currentLocation; if (isFirstTime) { isFirstTime = false; firstCellSecondRoad = nextLoc; } map.cells[nextLoc.x, nextLoc.y] = TypeOfCell.SecondRoad; currentLocation = nextLoc; } else { map.cells[lastSecondRoad.x, lastSecondRoad.y] = TypeOfCell.Road; map.cells[currentLocation.x, currentLocation.y] = TypeOfCell.Road; isEndGenerateSecondRoad = true; } } yield return(null); } yield return(null); } }