чё то высрал ии, переделать
насрал в tryplaceroom
This commit is contained in:
parent
3a3f1ea763
commit
40dbba050c
@ -4,6 +4,7 @@ namespace _Project.Scripts.LevelGenerating
|
|||||||
{
|
{
|
||||||
Start,
|
Start,
|
||||||
Corridor,
|
Corridor,
|
||||||
|
Undefined,
|
||||||
Lift,
|
Lift,
|
||||||
Laboratory,
|
Laboratory,
|
||||||
Boss,
|
Boss,
|
||||||
|
|||||||
@ -122,27 +122,133 @@ namespace _Project.Scripts.LevelGenerating
|
|||||||
|
|
||||||
void TryPlaceRoom(Room corridor)
|
void TryPlaceRoom(Room corridor)
|
||||||
{
|
{
|
||||||
|
// Базовая защита: если коридора нет или у него нет направления выхода
|
||||||
|
if (corridor == null || corridor.exits.Count == 0) return;
|
||||||
|
|
||||||
// Room lastCorridor = LevelManager.Instance.GetLastRoom();
|
ExitsInRoomType corridorDirection = corridor.exits.Last();
|
||||||
if (corridor != null && corridor.exits.Count == 1)
|
|
||||||
{
|
// Создаем новую комнату со случайными размерами
|
||||||
switch (corridor.exits.Last())
|
|
||||||
{
|
|
||||||
case ExitsInRoomType.XAxisP:
|
|
||||||
{
|
|
||||||
if ((lengthFloor - (corridor.Position.x + corridorLength + lengthWallMin) > 0)
|
|
||||||
&& (lengthFloor - (corridor.Position.y + corridorWigth + lengthWallMin) > 0))
|
|
||||||
{
|
|
||||||
Room newRoom = GenerateRandomRoom();
|
Room newRoom = GenerateRandomRoom();
|
||||||
if()
|
newRoom.rt = RoomType.Undefined;
|
||||||
}
|
|
||||||
|
|
||||||
|
Vector2 roomPos = Vector2.zero;
|
||||||
|
EntranceToRoomType entrance = EntranceToRoomType.Null;
|
||||||
|
|
||||||
|
// 1. Стыкуем вход новой комнаты с выходом из коридора
|
||||||
|
switch (corridorDirection)
|
||||||
|
{
|
||||||
|
case ExitsInRoomType.XAxisP: // Коридор шел вправо (+X)
|
||||||
|
roomPos = new Vector2(
|
||||||
|
corridor.Position.x + corridor.Length,
|
||||||
|
corridor.Position.y + (corridor.Wigth - newRoom.Wigth) / 2f
|
||||||
|
);
|
||||||
|
entrance = EntranceToRoomType.XAxisN; // Вход в комнату с левой стены (-X)
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ExitsInRoomType.XAxisN: // Коридор шел влево (-X)
|
||||||
|
roomPos = new Vector2(
|
||||||
|
corridor.Position.x - newRoom.Length,
|
||||||
|
corridor.Position.y + (corridor.Wigth - newRoom.Wigth) / 2f
|
||||||
|
);
|
||||||
|
entrance = EntranceToRoomType.XAxisP; // Вход с правой стены (+X)
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ExitsInRoomType.ZAxisP: // Коридор шел вверх (+Z)
|
||||||
|
roomPos = new Vector2(
|
||||||
|
corridor.Position.x + (corridor.Length - newRoom.Length) / 2f,
|
||||||
|
corridor.Position.y + corridor.Wigth
|
||||||
|
);
|
||||||
|
entrance = EntranceToRoomType.ZAxisN; // Вход с нижней стены (-Z)
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ExitsInRoomType.ZAxisN: // Коридор шел вниз (-Z)
|
||||||
|
roomPos = new Vector2(
|
||||||
|
corridor.Position.x + (corridor.Length - newRoom.Length) / 2f,
|
||||||
|
corridor.Position.y - newRoom.Wigth
|
||||||
|
);
|
||||||
|
entrance = EntranceToRoomType.ZAxisP; // Вход с верхней стены (+Z)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2. Проверяем: влезает ли комната в границы и не накладывается ли на другие комнаты/коридоры
|
||||||
|
if (!IsAreaClear(roomPos, newRoom.Length, newRoom.Wigth))
|
||||||
|
{
|
||||||
|
// Не влезла — эта ветка лабиринта затухает сама
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Если всё чисто, сохраняем параметры и добавляем в список
|
||||||
|
newRoom.Position = roomPos;
|
||||||
|
newRoom.entrance = entrance;
|
||||||
|
LevelManager.Rooms.Add(newRoom);
|
||||||
|
|
||||||
|
// Визуализация новой комнаты (маркеры по углам)
|
||||||
|
Instantiate(GameObjectB, new Vector3(newRoom.Position.x, 0, newRoom.Position.y), Quaternion.identity);
|
||||||
|
Instantiate(GameObjectB, new Vector3(newRoom.Position.x + newRoom.Length, 0, newRoom.Position.y), Quaternion.identity);
|
||||||
|
Instantiate(GameObjectB, new Vector3(newRoom.Position.x + newRoom.Length, 0, newRoom.Position.y + newRoom.Wigth), Quaternion.identity);
|
||||||
|
Instantiate(GameObjectB, new Vector3(newRoom.Position.x, 0, newRoom.Position.y + newRoom.Wigth), Quaternion.identity);
|
||||||
|
|
||||||
|
// 3. РЕКУРСИЯ: получаем 3 свободные стены (все кроме той, где вход)
|
||||||
|
List<ExitsInRoomType> availableSides = GetThreeAvailableSides(entrance);
|
||||||
|
|
||||||
|
// Перемешиваем стороны, чтобы ветвление шло в случайном порядке
|
||||||
|
availableSides = availableSides.OrderBy(x => Random.value).ToList();
|
||||||
|
|
||||||
|
foreach (var exitSide in availableSides)
|
||||||
|
{
|
||||||
|
// Шанс ветвления 65%: чтобы этаж не забивался сплошным ковром комнат,
|
||||||
|
// а оставались тупики и коридорные развилки
|
||||||
|
if (Random.value < 0.65f)
|
||||||
|
{
|
||||||
|
// Пытаемся построить коридор в эту сторону
|
||||||
|
Room nextCorridor = CreateCorridor(newRoom.Position, newRoom.Length, newRoom.Wigth, exitSide);
|
||||||
|
|
||||||
|
if (nextCorridor != null)
|
||||||
|
{
|
||||||
|
// Рекурсивный шаг: пытаемся пристроить комнату к концу нового коридора
|
||||||
|
TryPlaceRoom(nextCorridor);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Вспомогательный метод 1: возвращает 3 стены, исключая стену входа
|
||||||
|
List<ExitsInRoomType> GetThreeAvailableSides(EntranceToRoomType entrance)
|
||||||
|
{
|
||||||
|
List<ExitsInRoomType> sides = new List<ExitsInRoomType>();
|
||||||
|
|
||||||
|
if (entrance != EntranceToRoomType.XAxisN) sides.Add(ExitsInRoomType.XAxisN);
|
||||||
|
if (entrance != EntranceToRoomType.XAxisP) sides.Add(ExitsInRoomType.XAxisP);
|
||||||
|
if (entrance != EntranceToRoomType.ZAxisN) sides.Add(ExitsInRoomType.ZAxisN);
|
||||||
|
if (entrance != EntranceToRoomType.ZAxisP) sides.Add(ExitsInRoomType.ZAxisP);
|
||||||
|
|
||||||
|
return sides;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Вспомогательный метод 2: проверка на границы этажа и пересечение с существующими объектами
|
||||||
|
bool IsAreaClear(Vector2 pos, int length, int wigth)
|
||||||
|
{
|
||||||
|
// Проверка границ этажа [0 .. lengthFloor]
|
||||||
|
if (pos.x < 0 || pos.y < 0 ||
|
||||||
|
pos.x + length > lengthFloor ||
|
||||||
|
pos.y + wigth > lengthFloor)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rect newRect = new Rect(pos.x, pos.y, length, wigth);
|
||||||
|
|
||||||
|
// Проверка наложения на все уже созданные комнаты и коридоры
|
||||||
|
foreach (var existing in LevelManager.Rooms)
|
||||||
|
{
|
||||||
|
Rect existingRect = new Rect(existing.Position.x, existing.Position.y, existing.Length, existing.Wigth);
|
||||||
|
if (newRect.Overlaps(existingRect))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
Room GenerateRandomRoom()
|
Room GenerateRandomRoom()
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user