diff --git a/DungeonShooting_Godot/src/framework/map/DungeonGenerator.cs b/DungeonShooting_Godot/src/framework/map/DungeonGenerator.cs
new file mode 100644
index 0000000..0149da8
--- /dev/null
+++ b/DungeonShooting_Godot/src/framework/map/DungeonGenerator.cs
@@ -0,0 +1,1003 @@
+
+using System;
+using System.Collections.Generic;
+using Godot;
+
+///
+/// 地牢生成器
+///
+public class DungeonGenerator
+{
+ ///
+ /// 所有生成的房间, 调用过 Generate() 函数才能获取到值
+ ///
+ public List RoomInfos { get; } = new List();
+
+ ///
+ /// 起始房间
+ ///
+ public RoomInfo StartRoom { get; private set; }
+
+ ///
+ /// 生成的房间数量
+ ///
+ private int _maxCount = 15;
+
+ //用于标记地图上的坐标是否被占用
+ private Grid _roomGrid { get; } = new Grid();
+
+ //当前房间数量
+ private int _count = 0;
+
+ //宽高
+ private int _roomMinWidth = 15;
+ private int _roomMaxWidth = 35;
+ private int _roomMinHeight = 15;
+ private int _roomMaxHeight = 30;
+
+ //间隔
+ private int _roomMinInterval = 6;
+ private int _roomMaxInterval = 10;
+
+ //房间横轴分散程度
+
+ private float _roomHorizontalMinDispersion = 0.3f;
+ private float _roomHorizontalMaxDispersion = 1.2f;
+
+ //房间纵轴分散程度
+ private float _roomVerticalMinDispersion = 0.3f;
+ private float _roomVerticalMaxDispersion = 1.2f;
+
+ //区域限制
+ private bool _enableLimitRange = true;
+ private int _rangeX = 110;
+ private int _rangeY = 110;
+
+ //找房间失败次数, 过大则会关闭区域限制
+ private int _maxFailCount = 10;
+ private int _failCount = 0;
+
+ //最大尝试次数
+ private int _maxTryCount = 10;
+
+ private enum GenerateRoomErrorCode
+ {
+ NoError,
+ //房间已满
+ RoomFull,
+ //超出区域
+ OutArea,
+ //没有合适的位置
+ NoSuitableLocation
+ // //碰到其他房间或过道
+ // HasCollision,
+ // //没有合适的门
+ // NoProperDoor,
+ }
+
+ ///
+ /// 遍历所有房间
+ ///
+ public void EachRoom(Action cb)
+ {
+ EachRoom(StartRoom, cb);
+ }
+
+ private void EachRoom(RoomInfo roomInfo, Action cb)
+ {
+ if (roomInfo == null)
+ {
+ return;
+ }
+
+ cb(roomInfo);
+ foreach (var next in roomInfo.Next)
+ {
+ EachRoom(next, cb);
+ }
+ }
+
+ ///
+ /// 生成房间
+ ///
+ public void Generate()
+ {
+ if (StartRoom != null) return;
+
+ //第一个房间
+ GenerateRoom(null, 0, out var startRoom);
+ StartRoom = startRoom;
+
+ //如果房间数量不够, 就一直生成
+ while (_count < _maxCount)
+ {
+ var room = Utils.RandomChoose(RoomInfos);
+ var errorCode = GenerateRoom(room, Utils.RandomRangeInt(0, 3), out var nextRoom);
+ if (errorCode == GenerateRoomErrorCode.NoError)
+ {
+ _failCount = 0;
+ room.Next.Add(nextRoom);
+ }
+ else
+ {
+ GD.Print("生成第" + (_count + 1) + "个房间失败! 失败原因: " + errorCode);
+ if (errorCode == GenerateRoomErrorCode.OutArea)
+ {
+ _failCount++;
+ GD.Print("超出区域失败次数: " + _failCount);
+ if (_failCount >= _maxFailCount)
+ {
+ _enableLimitRange = false;
+ GD.Print("生成房间失败次数过多, 关闭区域限制!");
+ }
+ }
+ }
+ }
+
+ _roomGrid.Clear();
+ }
+
+ //生成房间
+ private GenerateRoomErrorCode GenerateRoom(RoomInfo prevRoomInfo, int direction, out RoomInfo resultRoom)
+ {
+ if (_count >= _maxCount)
+ {
+ resultRoom = null;
+ return GenerateRoomErrorCode.RoomFull;
+ }
+
+ //随机选择一个房间
+ var roomSplit = Utils.RandomChoose(GameApplication.Instance.RoomConfig);
+ //var roomSplit = GameApplication.Instance.RoomConfig[1];
+ var room = new RoomInfo(_count, roomSplit);
+
+ //房间大小
+ room.Size = new Vector2I((int)roomSplit.RoomInfo.Size.X, (int)roomSplit.RoomInfo.Size.Y);
+
+ if (prevRoomInfo != null) //表示这不是第一个房间, 就得判断当前位置下的房间是否被遮挡
+ {
+ //生成的位置可能会和上一个房间对不上, 需要多次尝试
+ var tryCount = 0; //当前尝试次数
+ for (; tryCount < _maxTryCount; tryCount++)
+ {
+ //房间间隔
+ var space = Utils.RandomRangeInt(_roomMinInterval, _roomMaxInterval);
+ //中心偏移
+ int offset;
+ if (direction == 0 || direction == 2)
+ {
+ offset = Utils.RandomRangeInt(-(int)(prevRoomInfo.Size.X * _roomVerticalMinDispersion),
+ (int)(prevRoomInfo.Size.X * _roomVerticalMaxDispersion));
+ }
+ else
+ {
+ offset = Utils.RandomRangeInt(-(int)(prevRoomInfo.Size.Y * _roomHorizontalMinDispersion),
+ (int)(prevRoomInfo.Size.Y * _roomHorizontalMaxDispersion));
+ }
+
+ //计算房间位置
+ if (direction == 0) //上
+ {
+ room.Position = new Vector2I(prevRoomInfo.Position.X + offset,
+ prevRoomInfo.Position.Y - room.Size.Y - space);
+ }
+ else if (direction == 1) //右
+ {
+ room.Position = new Vector2I(prevRoomInfo.Position.X + prevRoomInfo.Size.Y + space,
+ prevRoomInfo.Position.Y + offset);
+ }
+ else if (direction == 2) //下
+ {
+ room.Position = new Vector2I(prevRoomInfo.Position.X + offset,
+ prevRoomInfo.Position.Y + prevRoomInfo.Size.Y + space);
+ }
+ else if (direction == 3) //左
+ {
+ room.Position = new Vector2I(prevRoomInfo.Position.X - room.Size.X - space,
+ prevRoomInfo.Position.Y + offset);
+ }
+
+ //是否在限制区域内
+ if (_enableLimitRange)
+ {
+ if (room.GetHorizontalStart() < -_rangeX || room.GetHorizontalEnd() > _rangeX ||
+ room.GetVerticalStart() < -_rangeY || room.GetVerticalEnd() > _rangeY)
+ {
+ //超出区域, 直接跳出尝试的循环, 返回 null
+ resultRoom = null;
+ return GenerateRoomErrorCode.OutArea;
+ }
+ }
+
+ //是否碰到其他房间或者过道
+ if (_roomGrid.RectCollision(room.Position - new Vector2(GameConfig.RoomSpace, GameConfig.RoomSpace), room.Size + new Vector2(GameConfig.RoomSpace * 2, GameConfig.RoomSpace * 2)))
+ {
+ //碰到其他墙壁, 再一次尝试
+ continue;
+ //return GenerateRoomErrorCode.HasCollision;
+ }
+
+ _roomGrid.AddRect(room.Position, room.Size, true);
+
+ //找门, 与上一个房间是否能连通
+ if (!ConnectDoor(prevRoomInfo, room))
+ {
+ _roomGrid.RemoveRect(room.Position, room.Size);
+ //房间过道没有连接上, 再一次尝试
+ continue;
+ //return GenerateRoomErrorCode.NoProperDoor;
+ }
+ break;
+ }
+
+ //尝试次数用光了, 还没有找到合适的位置
+ if (tryCount >= _maxTryCount)
+ {
+ resultRoom = null;
+ return GenerateRoomErrorCode.NoSuitableLocation;
+ }
+ }
+
+ _count++;
+ RoomInfos.Add(room);
+ if (prevRoomInfo == null)
+ {
+ _roomGrid.AddRect(room.Position, room.Size, true);
+ }
+
+ //下一个房间
+ //0上, 1右, 2下, 3左
+ var dirList = new List(new[] { 0, 1, 2, 3 });
+ if (prevRoomInfo != null)
+ {
+ dirList.Remove(GetReverseDirection(direction));
+ }
+
+ //这条线有一定概率不生成下一个房间
+ if (Utils.RandomRangeInt(0, 2) != 0)
+ {
+ while (dirList.Count > 0)
+ {
+ var randDir = Utils.RandomChoose(dirList);
+ GenerateRoom(room, randDir, out var nextRoom);
+ if (nextRoom == null)
+ {
+ break;
+ }
+
+ nextRoom.Prev = room;
+ room.Next.Add(nextRoom);
+
+ dirList.Remove(randDir);
+ }
+ }
+
+ resultRoom = room;
+ return GenerateRoomErrorCode.NoError;
+ }
+
+ ///
+ /// 找两个房间的门
+ ///
+ private bool ConnectDoor(RoomInfo room, RoomInfo nextRoom)
+ {
+ //门描述
+ var roomDoor = new RoomDoorInfo();
+ var nextRoomDoor = new RoomDoorInfo();
+ roomDoor.RoomInfo = room;
+ nextRoomDoor.RoomInfo = nextRoom;
+ roomDoor.ConnectRoom = nextRoom;
+ roomDoor.ConnectDoor = nextRoomDoor;
+ nextRoomDoor.ConnectRoom = room;
+ nextRoomDoor.ConnectDoor = roomDoor;
+
+ //先寻找直通门
+ if (Utils.RandomBoolean())
+ {
+ //直行通道, 优先横轴
+ if (TryConnectHorizontalDoor(room, roomDoor, nextRoom, nextRoomDoor)
+ || TryConnectVerticalDoor(room, roomDoor, nextRoom, nextRoomDoor))
+ {
+ return true;
+ }
+ }
+ else
+ {
+ //直行通道, 优先纵轴
+ if (TryConnectVerticalDoor(room, roomDoor, nextRoom, nextRoomDoor)
+ || TryConnectHorizontalDoor(room, roomDoor, nextRoom, nextRoomDoor))
+ {
+ return true;
+ }
+ }
+
+ //包含拐角的通道
+ return TryConnectCrossDoor(room, roomDoor, nextRoom, nextRoomDoor);
+ }
+
+ ///
+ /// 尝试寻找横轴方向上两个房间的连通的门, 只查找直线通道, 返回是否找到
+ ///
+ private bool TryConnectHorizontalDoor(RoomInfo room, RoomDoorInfo roomDoor, RoomInfo nextRoom, RoomDoorInfo nextRoomDoor)
+ {
+ var overlapX = Mathf.Min(room.GetHorizontalEnd(), nextRoom.GetHorizontalEnd()) -
+ Mathf.Max(room.GetHorizontalStart(), nextRoom.GetHorizontalStart());
+ //这种情况下x轴有重叠
+ if (overlapX >= 6)
+ {
+ //找到重叠区域
+ var rangeList = FindPassage(room, nextRoom,
+ room.GetVerticalStart() < nextRoom.GetVerticalStart() ? DoorDirection.S : DoorDirection.N);
+
+ while (rangeList.Count > 0)
+ {
+ //找到重叠区域
+ var range = Utils.RandomChooseAndRemove(rangeList);
+ var x = Utils.RandomRangeInt(range.X, range.Y);
+
+ if (room.GetVerticalStart() < nextRoom.GetVerticalStart()) //room在上, nextRoom在下
+ {
+ roomDoor.Direction = DoorDirection.S;
+ nextRoomDoor.Direction = DoorDirection.N;
+ roomDoor.OriginPosition = new Vector2(x, room.GetVerticalEnd());
+ nextRoomDoor.OriginPosition = new Vector2(x, nextRoom.GetVerticalStart());
+ }
+ else //room在下, nextRoom在上
+ {
+ roomDoor.Direction = DoorDirection.N;
+ nextRoomDoor.Direction = DoorDirection.S;
+ roomDoor.OriginPosition = new Vector2(x, room.GetVerticalStart());
+ nextRoomDoor.OriginPosition = new Vector2(x, nextRoom.GetVerticalEnd());
+ }
+
+ //判断门之间的通道是否有物体碰到
+ if (!AddCorridorToGridRange(roomDoor, nextRoomDoor))
+ {
+ //此门不能连通
+ continue;
+ }
+
+ //没有撞到物体
+ room.Doors.Add(roomDoor);
+ nextRoom.Doors.Add(nextRoomDoor);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ ///
+ /// 尝试寻找纵轴方向上两个房间的连通的门, 只查找直线通道, 返回是否找到
+ ///
+ private bool TryConnectVerticalDoor(RoomInfo room, RoomDoorInfo roomDoor, RoomInfo nextRoom, RoomDoorInfo nextRoomDoor)
+ {
+ var overlapY = Mathf.Min(room.GetVerticalEnd(), nextRoom.GetVerticalEnd()) -
+ Mathf.Max(room.GetVerticalStart(), nextRoom.GetVerticalStart());
+ //这种情况下y轴有重叠
+ if (overlapY >= 6)
+ {
+ //找到重叠区域
+ var rangeList = FindPassage(room, nextRoom,
+ room.GetHorizontalStart() < nextRoom.GetHorizontalStart() ? DoorDirection.E : DoorDirection.W);
+
+ while (rangeList.Count > 0)
+ {
+ //找到重叠区域
+ var range = Utils.RandomChooseAndRemove(rangeList);
+ var y = Utils.RandomRangeInt(range.X, range.Y);
+
+ if (room.GetHorizontalStart() < nextRoom.GetHorizontalStart()) //room在左, nextRoom在右
+ {
+ roomDoor.Direction = DoorDirection.E;
+ nextRoomDoor.Direction = DoorDirection.W;
+ roomDoor.OriginPosition = new Vector2(room.GetHorizontalEnd(), y);
+ nextRoomDoor.OriginPosition = new Vector2(nextRoom.GetHorizontalStart(), y);
+ }
+ else //room在右, nextRoom在左
+ {
+ roomDoor.Direction = DoorDirection.W;
+ nextRoomDoor.Direction = DoorDirection.E;
+ roomDoor.OriginPosition = new Vector2(room.GetHorizontalStart(), y);
+ nextRoomDoor.OriginPosition = new Vector2(nextRoom.GetHorizontalEnd(), y);
+ }
+
+ //判断门之间的通道是否有物体碰到
+ if (!AddCorridorToGridRange(roomDoor, nextRoomDoor))
+ {
+ //此门不能连通
+ continue;
+ }
+
+ //没有撞到物体
+ room.Doors.Add(roomDoor);
+ nextRoom.Doors.Add(nextRoomDoor);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ ///
+ /// 尝试寻找包含拐角的两个房间的连通的门, 返回是否找到
+ ///
+ private bool TryConnectCrossDoor(RoomInfo room, RoomDoorInfo roomDoor, RoomInfo nextRoom, RoomDoorInfo nextRoomDoor)
+ {
+ //焦点
+ Vector2 cross = default;
+
+ if (room.GetHorizontalStart() > nextRoom.GetHorizontalStart())
+ {
+ if (room.GetVerticalStart() > nextRoom.GetVerticalStart())
+ {
+ if (Utils.RandomBoolean()) //↑ //→
+ {
+ if (!TryConnect_NE_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross) &&
+ !TryConnect_WS_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross))
+ {
+ return false;
+ }
+ }
+ else //← //↓
+ {
+ if (!TryConnect_WS_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross) &&
+ !TryConnect_NE_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross))
+ {
+ return false;
+ }
+ }
+ }
+ else
+ {
+ if (Utils.RandomBoolean()) //↓ //→
+ {
+ if (!TryConnect_SE_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross) &&
+ !TryConnect_WN_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross))
+ {
+ return false;
+ }
+ }
+ else //← //↑
+ {
+ if (!TryConnect_WN_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross) &&
+ !TryConnect_SE_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross))
+ {
+ return false;
+ }
+ }
+ }
+ }
+ else
+ {
+ if (room.GetVerticalStart() > nextRoom.GetVerticalStart()) //→ //↓
+ {
+ if (Utils.RandomBoolean())
+ {
+ if (!TryConnect_ES_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross) &&
+ !TryConnect_NW_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross))
+ {
+ return false;
+ }
+ }
+ else //↑ //←
+ {
+ if (!TryConnect_NW_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross) &&
+ !TryConnect_ES_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross))
+ {
+ return false;
+ }
+ }
+ }
+ else
+ {
+ if (Utils.RandomBoolean()) //→ //↑
+ {
+ if (!TryConnect_EN_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross) &&
+ !TryConnect_SW_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross))
+ {
+ return false;
+ }
+ }
+ else //↓ //←
+ {
+ if (!TryConnect_SW_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross) &&
+ !TryConnect_EN_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross))
+ {
+ return false;
+ }
+ }
+ }
+ }
+
+ //判断门之间的通道是否有物体碰到
+ if (!AddCorridorToGridRange(roomDoor, nextRoomDoor, cross))
+ {
+ //此门不能连通
+ return false;
+ }
+
+ roomDoor.HasCross = true;
+ roomDoor.Cross = cross;
+ nextRoomDoor.HasCross = true;
+ nextRoomDoor.Cross = cross;
+
+ room.Doors.Add(roomDoor);
+ nextRoom.Doors.Add(nextRoomDoor);
+ return true;
+ }
+
+ private bool FindCrossPassage(RoomInfo room, RoomInfo nextRoom, RoomDoorInfo roomDoor, RoomDoorInfo nextRoomDoor,ref int offset1, ref int offset2)
+ {
+ var room1 = room.RoomSplit.RoomInfo;
+ var room2 = nextRoom.RoomSplit.RoomInfo;
+
+ int? temp1 = null;
+ int? temp2 = null;
+
+ foreach (var areaInfo1 in room1.DoorAreaInfos)
+ {
+ if (areaInfo1.Direction == roomDoor.Direction)
+ {
+ FindCrossPassage_Area(areaInfo1, room, nextRoom, ref temp1);
+ }
+ }
+
+ if (temp1 == null)
+ {
+ return false;
+ }
+
+ foreach (var areaInfo2 in room2.DoorAreaInfos)
+ {
+ if (areaInfo2.Direction == nextRoomDoor.Direction)
+ {
+ FindCrossPassage_Area(areaInfo2, nextRoom, room, ref temp2);
+ }
+ }
+
+ if (temp2 == null)
+ {
+ return false;
+ }
+
+ offset1 = temp1.Value;
+ offset2 = temp2.Value;
+ return true;
+ }
+
+ private void FindCrossPassage_Area(DoorAreaInfo areaInfo, RoomInfo room1, RoomInfo room2, ref int? areaRange)
+ {
+ if (areaInfo.Direction == DoorDirection.N || areaInfo.Direction == DoorDirection.S) //纵向门
+ {
+ var num = room1.GetHorizontalStart();
+ var p1 = num + areaInfo.Start / GameConfig.TileCellSize;
+ var p2 = num + areaInfo.End / GameConfig.TileCellSize;
+
+ if (room1.Position.X > room2.Position.X)
+ {
+ var range = CalcOverlapRange(room2.GetHorizontalEnd() + GameConfig.RoomSpace,
+ room1.GetHorizontalEnd(), p1, p2);
+ //交集范围够生成门
+ if (range.Y - range.X >= GameConfig.CorridorWidth)
+ {
+ // var tempRange = new Vector2I(Mathf.Abs(room1.Position.X - (int)range.X),
+ // Mathf.Abs(room1.Position.X - (int)range.Y) - GameConfig.CorridorWidth);
+
+ var rangeValue = Mathf.Abs(room1.Position.X - (int)range.X);
+
+ if (areaRange == null || rangeValue < areaRange)
+ {
+ areaRange = rangeValue;
+ }
+ }
+ }
+ else
+ {
+ var range = CalcOverlapRange(room1.GetHorizontalStart(),
+ room2.GetHorizontalStart() - + GameConfig.RoomSpace, p1, p2);
+ //交集范围够生成门
+ if (range.Y - range.X >= GameConfig.CorridorWidth)
+ {
+ // var tempRange = new Vector2I(Mathf.Abs(room1.Position.X - (int)range.X),
+ // Mathf.Abs(room1.Position.X - (int)range.Y) - GameConfig.CorridorWidth);
+
+ var rangeValue = Mathf.Abs(room1.Position.X - (int)range.Y) - GameConfig.CorridorWidth;
+
+ if (areaRange == null || rangeValue > areaRange)
+ {
+ areaRange = rangeValue;
+ }
+ }
+ }
+ }
+ else //横向门
+ {
+ var num = room1.GetVerticalStart();
+ var p1 = num + areaInfo.Start / GameConfig.TileCellSize;
+ var p2 = num + areaInfo.End / GameConfig.TileCellSize;
+
+ if (room1.Position.Y > room2.Position.Y)
+ {
+ var range = CalcOverlapRange(room2.GetVerticalEnd() + GameConfig.RoomSpace,
+ room1.GetVerticalEnd(), p1, p2);
+ //交集范围够生成门
+ if (range.Y - range.X >= GameConfig.CorridorWidth)
+ {
+ // var tempRange = new Vector2I(Mathf.Abs(room1.Position.Y - (int)range.X),
+ // Mathf.Abs(room1.Position.Y - (int)range.Y) - GameConfig.CorridorWidth);
+
+ var rangeValue = Mathf.Abs(room1.Position.Y - (int)range.X);
+
+ if (areaRange == null || rangeValue < areaRange)
+ {
+ areaRange = rangeValue;
+ }
+ }
+ }
+ else
+ {
+ var range = CalcOverlapRange(room1.GetVerticalStart(),
+ room2.GetVerticalStart() - GameConfig.RoomSpace, p1, p2);
+ //交集范围够生成门
+ if (range.Y - range.X >= GameConfig.CorridorWidth)
+ {
+ // var tempRange = new Vector2I(Mathf.Abs(room1.Position.Y - (int)range.X),
+ // Mathf.Abs(room1.Position.Y - (int)range.Y) - GameConfig.CorridorWidth);
+
+ var rangeValue = Mathf.Abs(room1.Position.Y - (int)range.Y) - GameConfig.CorridorWidth;
+
+ if (areaRange == null || rangeValue > areaRange)
+ {
+ areaRange = rangeValue;
+ }
+ }
+ }
+ }
+ }
+
+ private bool TryConnect_NE_Door(RoomInfo room, RoomInfo nextRoom, RoomDoorInfo roomDoor, RoomDoorInfo nextRoomDoor, ref Vector2 cross)
+ {
+ var offset1 = 0;
+ var offset2 = 0;
+ roomDoor.Direction = DoorDirection.N; //↑
+ nextRoomDoor.Direction = DoorDirection.E; //→
+
+ if (!FindCrossPassage(room, nextRoom, roomDoor, nextRoomDoor, ref offset1, ref offset2))
+ {
+ return false;
+ }
+
+ roomDoor.OriginPosition = new Vector2(room.GetHorizontalStart() + offset1, room.GetVerticalStart());
+ nextRoomDoor.OriginPosition = new Vector2(nextRoom.GetHorizontalEnd(),
+ nextRoom.GetVerticalStart() + offset2);
+ cross = new Vector2(roomDoor.OriginPosition.X, nextRoomDoor.OriginPosition.Y);
+ return true;
+ }
+
+ private bool TryConnect_WS_Door(RoomInfo room, RoomInfo nextRoom, RoomDoorInfo roomDoor, RoomDoorInfo nextRoomDoor, ref Vector2 cross)
+ {
+ //ok
+ var offset1 = 0;
+ var offset2 = 0;
+ roomDoor.Direction = DoorDirection.W; //←
+ nextRoomDoor.Direction = DoorDirection.S; //↓
+
+ if (!FindCrossPassage(room, nextRoom, roomDoor, nextRoomDoor, ref offset1, ref offset2))
+ {
+ return false;
+ }
+
+ roomDoor.OriginPosition = new Vector2(room.GetHorizontalStart(), room.GetVerticalStart() + offset1);
+ nextRoomDoor.OriginPosition = new Vector2(nextRoom.GetHorizontalStart() + offset2, nextRoom.GetVerticalEnd());
+ cross = new Vector2(nextRoomDoor.OriginPosition.X, roomDoor.OriginPosition.Y);
+ return true;
+ }
+
+ private bool TryConnect_SE_Door(RoomInfo room, RoomInfo nextRoom, RoomDoorInfo roomDoor, RoomDoorInfo nextRoomDoor, ref Vector2 cross)
+ {
+ var offset1 = 0;
+ var offset2 = 0;
+ roomDoor.Direction = DoorDirection.S; //↓
+ nextRoomDoor.Direction = DoorDirection.E; //→
+
+ if (!FindCrossPassage(room, nextRoom, roomDoor, nextRoomDoor, ref offset1, ref offset2))
+ {
+ return false;
+ }
+
+ roomDoor.OriginPosition = new Vector2(room.GetHorizontalStart() + offset1, room.GetVerticalEnd());
+ nextRoomDoor.OriginPosition = new Vector2(nextRoom.GetHorizontalEnd(),
+ nextRoom.GetVerticalStart() + offset2);
+ cross = new Vector2(roomDoor.OriginPosition.X, nextRoomDoor.OriginPosition.Y);
+ return true;
+ }
+
+ private bool TryConnect_WN_Door(RoomInfo room, RoomInfo nextRoom, RoomDoorInfo roomDoor, RoomDoorInfo nextRoomDoor, ref Vector2 cross)
+ {
+ var offset1 = 0;
+ var offset2 = 0;
+ roomDoor.Direction = DoorDirection.W; //←
+ nextRoomDoor.Direction = DoorDirection.N; //↑
+
+ if (!FindCrossPassage(room, nextRoom, roomDoor, nextRoomDoor, ref offset1, ref offset2))
+ {
+ return false;
+ }
+
+ roomDoor.OriginPosition =
+ new Vector2(room.GetHorizontalStart(), room.GetVerticalStart() + offset1); //
+ nextRoomDoor.OriginPosition = new Vector2(nextRoom.GetHorizontalStart() + offset2,
+ nextRoom.GetVerticalStart());
+ cross = new Vector2(nextRoomDoor.OriginPosition.X, roomDoor.OriginPosition.Y);
+ return true;
+ }
+
+ private bool TryConnect_ES_Door(RoomInfo room, RoomInfo nextRoom, RoomDoorInfo roomDoor, RoomDoorInfo nextRoomDoor, ref Vector2 cross)
+ {
+ var offset1 = 0;
+ var offset2 = 0;
+ roomDoor.Direction = DoorDirection.E; //→
+ nextRoomDoor.Direction = DoorDirection.S; //↓
+
+ if (!FindCrossPassage(room, nextRoom, roomDoor, nextRoomDoor, ref offset1, ref offset2))
+ {
+ return false;
+ }
+
+ roomDoor.OriginPosition = new Vector2(room.GetHorizontalEnd(), room.GetVerticalStart() + offset1);
+ nextRoomDoor.OriginPosition = new Vector2(nextRoom.GetHorizontalStart() + offset2,
+ nextRoom.GetVerticalEnd());
+ cross = new Vector2(nextRoomDoor.OriginPosition.X, roomDoor.OriginPosition.Y);
+ return true;
+ }
+
+ private bool TryConnect_NW_Door(RoomInfo room, RoomInfo nextRoom, RoomDoorInfo roomDoor, RoomDoorInfo nextRoomDoor, ref Vector2 cross)
+ {
+ var offset1 = 0;
+ var offset2 = 0;
+ roomDoor.Direction = DoorDirection.N; //↑
+ nextRoomDoor.Direction = DoorDirection.W; //←
+
+ if (!FindCrossPassage(room, nextRoom, roomDoor, nextRoomDoor, ref offset1, ref offset2))
+ {
+ return false;
+ }
+
+ roomDoor.OriginPosition = new Vector2(room.GetHorizontalStart() + offset1, room.GetVerticalStart());
+ nextRoomDoor.OriginPosition = new Vector2(nextRoom.GetHorizontalStart(),
+ nextRoom.GetVerticalStart() + offset2);
+ cross = new Vector2(roomDoor.OriginPosition.X, nextRoomDoor.OriginPosition.Y);
+ return true;
+ }
+
+ private bool TryConnect_EN_Door(RoomInfo room, RoomInfo nextRoom, RoomDoorInfo roomDoor, RoomDoorInfo nextRoomDoor, ref Vector2 cross)
+ {
+ var offset1 = 0;
+ var offset2 = 0;
+ roomDoor.Direction = DoorDirection.E; //→
+ nextRoomDoor.Direction = DoorDirection.N; //↑
+
+ if (!FindCrossPassage(room, nextRoom, roomDoor, nextRoomDoor, ref offset1, ref offset2))
+ {
+ return false;
+ }
+
+ roomDoor.OriginPosition = new Vector2(room.GetHorizontalEnd(),
+ room.GetVerticalStart() + offset1);
+ nextRoomDoor.OriginPosition = new Vector2(nextRoom.GetHorizontalStart() + offset2, nextRoom.GetVerticalStart());
+ cross = new Vector2(nextRoomDoor.OriginPosition.X, roomDoor.OriginPosition.Y);
+ return true;
+ }
+
+ private bool TryConnect_SW_Door(RoomInfo room, RoomInfo nextRoom, RoomDoorInfo roomDoor, RoomDoorInfo nextRoomDoor, ref Vector2 cross)
+ {
+ var offset1 = 0;
+ var offset2 = 0;
+ roomDoor.Direction = DoorDirection.S; //↓
+ nextRoomDoor.Direction = DoorDirection.W; //←
+
+ if (!FindCrossPassage(room, nextRoom, roomDoor, nextRoomDoor, ref offset1, ref offset2))
+ {
+ return false;
+ }
+
+ roomDoor.OriginPosition = new Vector2(room.GetHorizontalStart() + offset1,
+ room.GetVerticalEnd());
+ nextRoomDoor.OriginPosition = new Vector2(nextRoom.GetHorizontalStart(), nextRoom.GetVerticalStart() + offset2);
+ cross = new Vector2(roomDoor.OriginPosition.X, nextRoomDoor.OriginPosition.Y);
+ return true;
+ }
+
+ ///
+ /// 查找房间的连接通道, 函数返回是否找到对应的门, 通过 result 返回 x/y 轴坐标
+ ///
+ /// 第一个房间
+ /// 第二个房间
+ /// 第一个房间连接方向
+ private List FindPassage(RoomInfo room, RoomInfo nextRoom, DoorDirection direction)
+ {
+ var room1 = room.RoomSplit.RoomInfo;
+ var room2 = nextRoom.RoomSplit.RoomInfo;
+
+ //用于存储符合生成条件的区域
+ var rangeList = new List();
+
+ foreach (var doorAreaInfo1 in room1.DoorAreaInfos)
+ {
+ if (doorAreaInfo1.Direction == direction)
+ {
+ //第二个门的方向
+ var direction2 = GetReverseDirection(direction);
+
+ foreach (var doorAreaInfo2 in room2.DoorAreaInfos)
+ {
+ if (doorAreaInfo2.Direction == direction2)
+ {
+ Vector2 range;
+ if (direction == DoorDirection.E || direction == DoorDirection.W) //第二个门向← 或者 第二个门向→
+ {
+ range = CalcOverlapRange(
+ room.GetVerticalStart() * GameConfig.TileCellSize + doorAreaInfo1.Start, room.GetVerticalStart() * GameConfig.TileCellSize + doorAreaInfo1.End,
+ nextRoom.GetVerticalStart() * GameConfig.TileCellSize + doorAreaInfo2.Start, nextRoom.GetVerticalStart() * GameConfig.TileCellSize + doorAreaInfo2.End
+ );
+ }
+ else //第二个门向↑ 或者 第二个门向↓
+ {
+ range = CalcOverlapRange(
+ room.GetHorizontalStart() * GameConfig.TileCellSize + doorAreaInfo1.Start, room.GetHorizontalStart() * GameConfig.TileCellSize + doorAreaInfo1.End,
+ nextRoom.GetHorizontalStart() * GameConfig.TileCellSize + doorAreaInfo2.Start, nextRoom.GetHorizontalStart() * GameConfig.TileCellSize + doorAreaInfo2.End
+ );
+ }
+ //交集范围够生成门
+ if (range.Y - range.X >= GameConfig.CorridorWidth * GameConfig.TileCellSize)
+ {
+ rangeList.Add(new Vector2I((int)(range.X / 16), (int)(range.Y / 16) - GameConfig.CorridorWidth));
+ }
+ }
+ }
+ }
+ }
+
+ return rangeList;
+ }
+
+ ///
+ /// 用于计算重叠区域坐标, 可以理解为一维轴上4个点的中间两个点, 返回的x为起始点, y为结束点
+ ///
+ private Vector2 CalcOverlapRange(float start1, float end1, float start2, float end2)
+ {
+ return new Vector2(Mathf.Max(start1, start2), Mathf.Min(end1, end2));
+ }
+
+ ///
+ /// 返回 p1 - p2 是否在 start - end 范围内
+ ///
+ private bool IsInRange(float start, float end, float p1, float p2)
+ {
+ return p1 >= start && p2 <= end;
+ }
+
+ //返回指定方向的反方向
+ //0上, 1右, 2下, 3左
+ private int GetReverseDirection(int direction)
+ {
+ switch (direction)
+ {
+ case 0: return 2;
+ case 1: return 3;
+ case 2: return 0;
+ case 3: return 1;
+ }
+
+ return 2;
+ }
+
+ //返回参数方向的反方向
+ private DoorDirection GetReverseDirection(DoorDirection direction)
+ {
+ switch (direction)
+ {
+ case DoorDirection.E:
+ return DoorDirection.W;
+ case DoorDirection.W:
+ return DoorDirection.E;
+ case DoorDirection.S:
+ return DoorDirection.N;
+ case DoorDirection.N:
+ return DoorDirection.S;
+ }
+
+ return DoorDirection.S;
+ }
+
+ //将两个门间的过道占用数据存入RoomGrid
+ private bool AddCorridorToGridRange(RoomDoorInfo door1, RoomDoorInfo door2)
+ {
+ var point1 = door1.OriginPosition;
+ var point2 = door2.OriginPosition;
+ var pos = new Vector2(Mathf.Min(point1.X, point2.X), Mathf.Min(point1.Y, point2.Y));
+ var size = new Vector2(
+ point1.X == point2.X ? GameConfig.CorridorWidth : Mathf.Abs(point1.X - point2.X),
+ point1.Y == point2.Y ? GameConfig.CorridorWidth : Mathf.Abs(point1.Y - point2.Y)
+ );
+
+ Vector2 collPos;
+ Vector2 collSize;
+ if (point1.X == point2.X) //纵向加宽, 防止贴到其它墙
+ {
+ collPos = new Vector2(pos.X - GameConfig.RoomSpace, pos.Y);
+ collSize = new Vector2(size.X + GameConfig.RoomSpace * 2, size.Y);
+ }
+ else //横向加宽, 防止贴到其它墙
+ {
+ collPos = new Vector2(pos.X, pos.Y - GameConfig.RoomSpace);
+ collSize = new Vector2(size.X, size.Y + GameConfig.RoomSpace * 2);
+ }
+
+ if (_roomGrid.RectCollision(collPos, collSize))
+ {
+ return false;
+ }
+
+ _roomGrid.AddRect(pos, size, true);
+ return true;
+ }
+
+ //将两个门间的过道占用数据存入RoomGrid, 该重载加入拐角点
+ private bool AddCorridorToGridRange(RoomDoorInfo door1, RoomDoorInfo door2, Vector2 cross)
+ {
+ var point1 = door1.OriginPosition;
+ var point2 = door2.OriginPosition;
+ var pos1 = new Vector2(Mathf.Min(point1.X, cross.X), Mathf.Min(point1.Y, cross.Y));
+ var size1 = new Vector2(
+ point1.X == cross.X ? GameConfig.CorridorWidth : Mathf.Abs(point1.X - cross.X),
+ point1.Y == cross.Y ? GameConfig.CorridorWidth : Mathf.Abs(point1.Y - cross.Y)
+ );
+ var pos2 = new Vector2(Mathf.Min(point2.X, cross.X), Mathf.Min(point2.Y, cross.Y));
+ var size2 = new Vector2(
+ point2.X == cross.X ? GameConfig.CorridorWidth : Mathf.Abs(point2.X - cross.X),
+ point2.Y == cross.Y ? GameConfig.CorridorWidth : Mathf.Abs(point2.Y - cross.Y)
+ );
+
+ Vector2 collPos1;
+ Vector2 collSize1;
+ if (point1.X == cross.X) //纵向加宽, 防止贴到其它墙
+ {
+ collPos1 = new Vector2(pos1.X - GameConfig.RoomSpace, pos1.Y);
+ collSize1 = new Vector2(size1.X + GameConfig.RoomSpace * 2, size1.Y);
+ }
+ else //横向加宽, 防止贴到其它墙
+ {
+ collPos1 = new Vector2(pos1.X, pos1.Y - GameConfig.RoomSpace);
+ collSize1 = new Vector2(size1.X, size1.Y + GameConfig.RoomSpace * 2);
+ }
+
+ if (_roomGrid.RectCollision(collPos1, collSize1))
+ {
+ return false;
+ }
+
+ Vector2 collPos2;
+ Vector2 collSize2;
+ if (point2.X == cross.X) //纵向加宽, 防止贴到其它墙
+ {
+ collPos2 = new Vector2(pos2.X - GameConfig.RoomSpace, pos2.Y);
+ collSize2 = new Vector2(size2.X + GameConfig.RoomSpace * 2, size2.Y);
+ }
+ else //横向加宽, 防止贴到其它墙
+ {
+ collPos2 = new Vector2(pos2.X, pos2.Y - GameConfig.RoomSpace);
+ collSize2 = new Vector2(size2.X, size2.Y + GameConfig.RoomSpace * 2);
+ }
+
+ if (_roomGrid.RectCollision(collPos2, collSize2))
+ {
+ return false;
+ }
+
+ _roomGrid.AddRect(pos1, size1, true);
+ _roomGrid.AddRect(pos2, size2, true);
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/framework/map/GenerateDungeon.cs b/DungeonShooting_Godot/src/framework/map/GenerateDungeon.cs
deleted file mode 100644
index 51cc5d1..0000000
--- a/DungeonShooting_Godot/src/framework/map/GenerateDungeon.cs
+++ /dev/null
@@ -1,1003 +0,0 @@
-
-using System;
-using System.Collections.Generic;
-using Godot;
-
-///
-/// 地牢生成器
-///
-public class GenerateDungeon
-{
- ///
- /// 所有生成的房间, 调用过 Generate() 函数才能获取到值
- ///
- public List RoomInfos { get; } = new List();
-
- ///
- /// 起始房间
- ///
- public RoomInfo StartRoom { get; private set; }
-
- ///
- /// 生成的房间数量
- ///
- private int _maxCount = 15;
-
- //用于标记地图上的坐标是否被占用
- private Grid _roomGrid { get; } = new Grid();
-
- //当前房间数量
- private int _count = 0;
-
- //宽高
- private int _roomMinWidth = 15;
- private int _roomMaxWidth = 35;
- private int _roomMinHeight = 15;
- private int _roomMaxHeight = 30;
-
- //间隔
- private int _roomMinInterval = 6;
- private int _roomMaxInterval = 10;
-
- //房间横轴分散程度
-
- private float _roomHorizontalMinDispersion = 0.3f;
- private float _roomHorizontalMaxDispersion = 1.2f;
-
- //房间纵轴分散程度
- private float _roomVerticalMinDispersion = 0.3f;
- private float _roomVerticalMaxDispersion = 1.2f;
-
- //区域限制
- private bool _enableLimitRange = true;
- private int _rangeX = 110;
- private int _rangeY = 110;
-
- //找房间失败次数, 过大则会关闭区域限制
- private int _maxFailCount = 10;
- private int _failCount = 0;
-
- //最大尝试次数
- private int _maxTryCount = 10;
-
- private enum GenerateRoomErrorCode
- {
- NoError,
- //房间已满
- RoomFull,
- //超出区域
- OutArea,
- //没有合适的位置
- NoSuitableLocation
- // //碰到其他房间或过道
- // HasCollision,
- // //没有合适的门
- // NoProperDoor,
- }
-
- ///
- /// 遍历所有房间
- ///
- public void EachRoom(Action cb)
- {
- EachRoom(StartRoom, cb);
- }
-
- private void EachRoom(RoomInfo roomInfo, Action cb)
- {
- if (roomInfo == null)
- {
- return;
- }
-
- cb(roomInfo);
- foreach (var next in roomInfo.Next)
- {
- EachRoom(next, cb);
- }
- }
-
- ///
- /// 生成房间
- ///
- public void Generate()
- {
- if (StartRoom != null) return;
-
- //第一个房间
- GenerateRoom(null, 0, out var startRoom);
- StartRoom = startRoom;
-
- //如果房间数量不够, 就一直生成
- while (_count < _maxCount)
- {
- var room = Utils.RandomChoose(RoomInfos);
- var errorCode = GenerateRoom(room, Utils.RandomRangeInt(0, 3), out var nextRoom);
- if (errorCode == GenerateRoomErrorCode.NoError)
- {
- _failCount = 0;
- room.Next.Add(nextRoom);
- }
- else
- {
- GD.Print("生成第" + (_count + 1) + "个房间失败! 失败原因: " + errorCode);
- if (errorCode == GenerateRoomErrorCode.OutArea)
- {
- _failCount++;
- GD.Print("超出区域失败次数: " + _failCount);
- if (_failCount >= _maxFailCount)
- {
- _enableLimitRange = false;
- GD.Print("生成房间失败次数过多, 关闭区域限制!");
- }
- }
- }
- }
-
- _roomGrid.Clear();
- }
-
- //生成房间
- private GenerateRoomErrorCode GenerateRoom(RoomInfo prevRoomInfo, int direction, out RoomInfo resultRoom)
- {
- if (_count >= _maxCount)
- {
- resultRoom = null;
- return GenerateRoomErrorCode.RoomFull;
- }
-
- //随机选择一个房间
- var roomSplit = Utils.RandomChoose(GameApplication.Instance.RoomConfig);
- //var roomSplit = GameApplication.Instance.RoomConfig[1];
- var room = new RoomInfo(_count, roomSplit);
-
- //房间大小
- room.Size = new Vector2I((int)roomSplit.RoomInfo.Size.X, (int)roomSplit.RoomInfo.Size.Y);
-
- if (prevRoomInfo != null) //表示这不是第一个房间, 就得判断当前位置下的房间是否被遮挡
- {
- //生成的位置可能会和上一个房间对不上, 需要多次尝试
- var tryCount = 0; //当前尝试次数
- for (; tryCount < _maxTryCount; tryCount++)
- {
- //房间间隔
- var space = Utils.RandomRangeInt(_roomMinInterval, _roomMaxInterval);
- //中心偏移
- int offset;
- if (direction == 0 || direction == 2)
- {
- offset = Utils.RandomRangeInt(-(int)(prevRoomInfo.Size.X * _roomVerticalMinDispersion),
- (int)(prevRoomInfo.Size.X * _roomVerticalMaxDispersion));
- }
- else
- {
- offset = Utils.RandomRangeInt(-(int)(prevRoomInfo.Size.Y * _roomHorizontalMinDispersion),
- (int)(prevRoomInfo.Size.Y * _roomHorizontalMaxDispersion));
- }
-
- //计算房间位置
- if (direction == 0) //上
- {
- room.Position = new Vector2I(prevRoomInfo.Position.X + offset,
- prevRoomInfo.Position.Y - room.Size.Y - space);
- }
- else if (direction == 1) //右
- {
- room.Position = new Vector2I(prevRoomInfo.Position.X + prevRoomInfo.Size.Y + space,
- prevRoomInfo.Position.Y + offset);
- }
- else if (direction == 2) //下
- {
- room.Position = new Vector2I(prevRoomInfo.Position.X + offset,
- prevRoomInfo.Position.Y + prevRoomInfo.Size.Y + space);
- }
- else if (direction == 3) //左
- {
- room.Position = new Vector2I(prevRoomInfo.Position.X - room.Size.X - space,
- prevRoomInfo.Position.Y + offset);
- }
-
- //是否在限制区域内
- if (_enableLimitRange)
- {
- if (room.GetHorizontalStart() < -_rangeX || room.GetHorizontalEnd() > _rangeX ||
- room.GetVerticalStart() < -_rangeY || room.GetVerticalEnd() > _rangeY)
- {
- //超出区域, 直接跳出尝试的循环, 返回 null
- resultRoom = null;
- return GenerateRoomErrorCode.OutArea;
- }
- }
-
- //是否碰到其他房间或者过道
- if (_roomGrid.RectCollision(room.Position - new Vector2(GameConfig.RoomSpace, GameConfig.RoomSpace), room.Size + new Vector2(GameConfig.RoomSpace * 2, GameConfig.RoomSpace * 2)))
- {
- //碰到其他墙壁, 再一次尝试
- continue;
- //return GenerateRoomErrorCode.HasCollision;
- }
-
- _roomGrid.AddRect(room.Position, room.Size, true);
-
- //找门, 与上一个房间是否能连通
- if (!ConnectDoor(prevRoomInfo, room))
- {
- _roomGrid.RemoveRect(room.Position, room.Size);
- //房间过道没有连接上, 再一次尝试
- continue;
- //return GenerateRoomErrorCode.NoProperDoor;
- }
- break;
- }
-
- //尝试次数用光了, 还没有找到合适的位置
- if (tryCount >= _maxTryCount)
- {
- resultRoom = null;
- return GenerateRoomErrorCode.NoSuitableLocation;
- }
- }
-
- _count++;
- RoomInfos.Add(room);
- if (prevRoomInfo == null)
- {
- _roomGrid.AddRect(room.Position, room.Size, true);
- }
-
- //下一个房间
- //0上, 1右, 2下, 3左
- var dirList = new List(new[] { 0, 1, 2, 3 });
- if (prevRoomInfo != null)
- {
- dirList.Remove(GetReverseDirection(direction));
- }
-
- //这条线有一定概率不生成下一个房间
- if (Utils.RandomRangeInt(0, 2) != 0)
- {
- while (dirList.Count > 0)
- {
- var randDir = Utils.RandomChoose(dirList);
- GenerateRoom(room, randDir, out var nextRoom);
- if (nextRoom == null)
- {
- break;
- }
-
- nextRoom.Prev = room;
- room.Next.Add(nextRoom);
-
- dirList.Remove(randDir);
- }
- }
-
- resultRoom = room;
- return GenerateRoomErrorCode.NoError;
- }
-
- ///
- /// 找两个房间的门
- ///
- private bool ConnectDoor(RoomInfo room, RoomInfo nextRoom)
- {
- //门描述
- var roomDoor = new RoomDoorInfo();
- var nextRoomDoor = new RoomDoorInfo();
- roomDoor.RoomInfo = room;
- nextRoomDoor.RoomInfo = nextRoom;
- roomDoor.ConnectRoom = nextRoom;
- roomDoor.ConnectDoor = nextRoomDoor;
- nextRoomDoor.ConnectRoom = room;
- nextRoomDoor.ConnectDoor = roomDoor;
-
- //先寻找直通门
- if (Utils.RandomBoolean())
- {
- //直行通道, 优先横轴
- if (TryConnectHorizontalDoor(room, roomDoor, nextRoom, nextRoomDoor)
- || TryConnectVerticalDoor(room, roomDoor, nextRoom, nextRoomDoor))
- {
- return true;
- }
- }
- else
- {
- //直行通道, 优先纵轴
- if (TryConnectVerticalDoor(room, roomDoor, nextRoom, nextRoomDoor)
- || TryConnectHorizontalDoor(room, roomDoor, nextRoom, nextRoomDoor))
- {
- return true;
- }
- }
-
- //包含拐角的通道
- return TryConnectCrossDoor(room, roomDoor, nextRoom, nextRoomDoor);
- }
-
- ///
- /// 尝试寻找横轴方向上两个房间的连通的门, 只查找直线通道, 返回是否找到
- ///
- private bool TryConnectHorizontalDoor(RoomInfo room, RoomDoorInfo roomDoor, RoomInfo nextRoom, RoomDoorInfo nextRoomDoor)
- {
- var overlapX = Mathf.Min(room.GetHorizontalEnd(), nextRoom.GetHorizontalEnd()) -
- Mathf.Max(room.GetHorizontalStart(), nextRoom.GetHorizontalStart());
- //这种情况下x轴有重叠
- if (overlapX >= 6)
- {
- //找到重叠区域
- var rangeList = FindPassage(room, nextRoom,
- room.GetVerticalStart() < nextRoom.GetVerticalStart() ? DoorDirection.S : DoorDirection.N);
-
- while (rangeList.Count > 0)
- {
- //找到重叠区域
- var range = Utils.RandomChooseAndRemove(rangeList);
- var x = Utils.RandomRangeInt(range.X, range.Y);
-
- if (room.GetVerticalStart() < nextRoom.GetVerticalStart()) //room在上, nextRoom在下
- {
- roomDoor.Direction = DoorDirection.S;
- nextRoomDoor.Direction = DoorDirection.N;
- roomDoor.OriginPosition = new Vector2(x, room.GetVerticalEnd());
- nextRoomDoor.OriginPosition = new Vector2(x, nextRoom.GetVerticalStart());
- }
- else //room在下, nextRoom在上
- {
- roomDoor.Direction = DoorDirection.N;
- nextRoomDoor.Direction = DoorDirection.S;
- roomDoor.OriginPosition = new Vector2(x, room.GetVerticalStart());
- nextRoomDoor.OriginPosition = new Vector2(x, nextRoom.GetVerticalEnd());
- }
-
- //判断门之间的通道是否有物体碰到
- if (!AddCorridorToGridRange(roomDoor, nextRoomDoor))
- {
- //此门不能连通
- continue;
- }
-
- //没有撞到物体
- room.Doors.Add(roomDoor);
- nextRoom.Doors.Add(nextRoomDoor);
- return true;
- }
- }
-
- return false;
- }
-
- ///
- /// 尝试寻找纵轴方向上两个房间的连通的门, 只查找直线通道, 返回是否找到
- ///
- private bool TryConnectVerticalDoor(RoomInfo room, RoomDoorInfo roomDoor, RoomInfo nextRoom, RoomDoorInfo nextRoomDoor)
- {
- var overlapY = Mathf.Min(room.GetVerticalEnd(), nextRoom.GetVerticalEnd()) -
- Mathf.Max(room.GetVerticalStart(), nextRoom.GetVerticalStart());
- //这种情况下y轴有重叠
- if (overlapY >= 6)
- {
- //找到重叠区域
- var rangeList = FindPassage(room, nextRoom,
- room.GetHorizontalStart() < nextRoom.GetHorizontalStart() ? DoorDirection.E : DoorDirection.W);
-
- while (rangeList.Count > 0)
- {
- //找到重叠区域
- var range = Utils.RandomChooseAndRemove(rangeList);
- var y = Utils.RandomRangeInt(range.X, range.Y);
-
- if (room.GetHorizontalStart() < nextRoom.GetHorizontalStart()) //room在左, nextRoom在右
- {
- roomDoor.Direction = DoorDirection.E;
- nextRoomDoor.Direction = DoorDirection.W;
- roomDoor.OriginPosition = new Vector2(room.GetHorizontalEnd(), y);
- nextRoomDoor.OriginPosition = new Vector2(nextRoom.GetHorizontalStart(), y);
- }
- else //room在右, nextRoom在左
- {
- roomDoor.Direction = DoorDirection.W;
- nextRoomDoor.Direction = DoorDirection.E;
- roomDoor.OriginPosition = new Vector2(room.GetHorizontalStart(), y);
- nextRoomDoor.OriginPosition = new Vector2(nextRoom.GetHorizontalEnd(), y);
- }
-
- //判断门之间的通道是否有物体碰到
- if (!AddCorridorToGridRange(roomDoor, nextRoomDoor))
- {
- //此门不能连通
- continue;
- }
-
- //没有撞到物体
- room.Doors.Add(roomDoor);
- nextRoom.Doors.Add(nextRoomDoor);
- return true;
- }
- }
-
- return false;
- }
-
- ///
- /// 尝试寻找包含拐角的两个房间的连通的门, 返回是否找到
- ///
- private bool TryConnectCrossDoor(RoomInfo room, RoomDoorInfo roomDoor, RoomInfo nextRoom, RoomDoorInfo nextRoomDoor)
- {
- //焦点
- Vector2 cross = default;
-
- if (room.GetHorizontalStart() > nextRoom.GetHorizontalStart())
- {
- if (room.GetVerticalStart() > nextRoom.GetVerticalStart())
- {
- if (Utils.RandomBoolean()) //↑ //→
- {
- if (!TryConnect_NE_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross) &&
- !TryConnect_WS_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross))
- {
- return false;
- }
- }
- else //← //↓
- {
- if (!TryConnect_WS_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross) &&
- !TryConnect_NE_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross))
- {
- return false;
- }
- }
- }
- else
- {
- if (Utils.RandomBoolean()) //↓ //→
- {
- if (!TryConnect_SE_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross) &&
- !TryConnect_WN_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross))
- {
- return false;
- }
- }
- else //← //↑
- {
- if (!TryConnect_WN_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross) &&
- !TryConnect_SE_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross))
- {
- return false;
- }
- }
- }
- }
- else
- {
- if (room.GetVerticalStart() > nextRoom.GetVerticalStart()) //→ //↓
- {
- if (Utils.RandomBoolean())
- {
- if (!TryConnect_ES_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross) &&
- !TryConnect_NW_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross))
- {
- return false;
- }
- }
- else //↑ //←
- {
- if (!TryConnect_NW_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross) &&
- !TryConnect_ES_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross))
- {
- return false;
- }
- }
- }
- else
- {
- if (Utils.RandomBoolean()) //→ //↑
- {
- if (!TryConnect_EN_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross) &&
- !TryConnect_SW_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross))
- {
- return false;
- }
- }
- else //↓ //←
- {
- if (!TryConnect_SW_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross) &&
- !TryConnect_EN_Door(room, nextRoom, roomDoor, nextRoomDoor, ref cross))
- {
- return false;
- }
- }
- }
- }
-
- //判断门之间的通道是否有物体碰到
- if (!AddCorridorToGridRange(roomDoor, nextRoomDoor, cross))
- {
- //此门不能连通
- return false;
- }
-
- roomDoor.HasCross = true;
- roomDoor.Cross = cross;
- nextRoomDoor.HasCross = true;
- nextRoomDoor.Cross = cross;
-
- room.Doors.Add(roomDoor);
- nextRoom.Doors.Add(nextRoomDoor);
- return true;
- }
-
- private bool FindCrossPassage(RoomInfo room, RoomInfo nextRoom, RoomDoorInfo roomDoor, RoomDoorInfo nextRoomDoor,ref int offset1, ref int offset2)
- {
- var room1 = room.RoomSplit.RoomInfo;
- var room2 = nextRoom.RoomSplit.RoomInfo;
-
- int? temp1 = null;
- int? temp2 = null;
-
- foreach (var areaInfo1 in room1.DoorAreaInfos)
- {
- if (areaInfo1.Direction == roomDoor.Direction)
- {
- FindCrossPassage_Area(areaInfo1, room, nextRoom, ref temp1);
- }
- }
-
- if (temp1 == null)
- {
- return false;
- }
-
- foreach (var areaInfo2 in room2.DoorAreaInfos)
- {
- if (areaInfo2.Direction == nextRoomDoor.Direction)
- {
- FindCrossPassage_Area(areaInfo2, nextRoom, room, ref temp2);
- }
- }
-
- if (temp2 == null)
- {
- return false;
- }
-
- offset1 = temp1.Value;
- offset2 = temp2.Value;
- return true;
- }
-
- private void FindCrossPassage_Area(DoorAreaInfo areaInfo, RoomInfo room1, RoomInfo room2, ref int? areaRange)
- {
- if (areaInfo.Direction == DoorDirection.N || areaInfo.Direction == DoorDirection.S) //纵向门
- {
- var num = room1.GetHorizontalStart();
- var p1 = num + areaInfo.Start / GameConfig.TileCellSize;
- var p2 = num + areaInfo.End / GameConfig.TileCellSize;
-
- if (room1.Position.X > room2.Position.X)
- {
- var range = CalcOverlapRange(room2.GetHorizontalEnd() + GameConfig.RoomSpace,
- room1.GetHorizontalEnd(), p1, p2);
- //交集范围够生成门
- if (range.Y - range.X >= GameConfig.CorridorWidth)
- {
- // var tempRange = new Vector2I(Mathf.Abs(room1.Position.X - (int)range.X),
- // Mathf.Abs(room1.Position.X - (int)range.Y) - GameConfig.CorridorWidth);
-
- var rangeValue = Mathf.Abs(room1.Position.X - (int)range.X);
-
- if (areaRange == null || rangeValue < areaRange)
- {
- areaRange = rangeValue;
- }
- }
- }
- else
- {
- var range = CalcOverlapRange(room1.GetHorizontalStart(),
- room2.GetHorizontalStart() - + GameConfig.RoomSpace, p1, p2);
- //交集范围够生成门
- if (range.Y - range.X >= GameConfig.CorridorWidth)
- {
- // var tempRange = new Vector2I(Mathf.Abs(room1.Position.X - (int)range.X),
- // Mathf.Abs(room1.Position.X - (int)range.Y) - GameConfig.CorridorWidth);
-
- var rangeValue = Mathf.Abs(room1.Position.X - (int)range.Y) - GameConfig.CorridorWidth;
-
- if (areaRange == null || rangeValue > areaRange)
- {
- areaRange = rangeValue;
- }
- }
- }
- }
- else //横向门
- {
- var num = room1.GetVerticalStart();
- var p1 = num + areaInfo.Start / GameConfig.TileCellSize;
- var p2 = num + areaInfo.End / GameConfig.TileCellSize;
-
- if (room1.Position.Y > room2.Position.Y)
- {
- var range = CalcOverlapRange(room2.GetVerticalEnd() + GameConfig.RoomSpace,
- room1.GetVerticalEnd(), p1, p2);
- //交集范围够生成门
- if (range.Y - range.X >= GameConfig.CorridorWidth)
- {
- // var tempRange = new Vector2I(Mathf.Abs(room1.Position.Y - (int)range.X),
- // Mathf.Abs(room1.Position.Y - (int)range.Y) - GameConfig.CorridorWidth);
-
- var rangeValue = Mathf.Abs(room1.Position.Y - (int)range.X);
-
- if (areaRange == null || rangeValue < areaRange)
- {
- areaRange = rangeValue;
- }
- }
- }
- else
- {
- var range = CalcOverlapRange(room1.GetVerticalStart(),
- room2.GetVerticalStart() - GameConfig.RoomSpace, p1, p2);
- //交集范围够生成门
- if (range.Y - range.X >= GameConfig.CorridorWidth)
- {
- // var tempRange = new Vector2I(Mathf.Abs(room1.Position.Y - (int)range.X),
- // Mathf.Abs(room1.Position.Y - (int)range.Y) - GameConfig.CorridorWidth);
-
- var rangeValue = Mathf.Abs(room1.Position.Y - (int)range.Y) - GameConfig.CorridorWidth;
-
- if (areaRange == null || rangeValue > areaRange)
- {
- areaRange = rangeValue;
- }
- }
- }
- }
- }
-
- private bool TryConnect_NE_Door(RoomInfo room, RoomInfo nextRoom, RoomDoorInfo roomDoor, RoomDoorInfo nextRoomDoor, ref Vector2 cross)
- {
- var offset1 = 0;
- var offset2 = 0;
- roomDoor.Direction = DoorDirection.N; //↑
- nextRoomDoor.Direction = DoorDirection.E; //→
-
- if (!FindCrossPassage(room, nextRoom, roomDoor, nextRoomDoor, ref offset1, ref offset2))
- {
- return false;
- }
-
- roomDoor.OriginPosition = new Vector2(room.GetHorizontalStart() + offset1, room.GetVerticalStart());
- nextRoomDoor.OriginPosition = new Vector2(nextRoom.GetHorizontalEnd(),
- nextRoom.GetVerticalStart() + offset2);
- cross = new Vector2(roomDoor.OriginPosition.X, nextRoomDoor.OriginPosition.Y);
- return true;
- }
-
- private bool TryConnect_WS_Door(RoomInfo room, RoomInfo nextRoom, RoomDoorInfo roomDoor, RoomDoorInfo nextRoomDoor, ref Vector2 cross)
- {
- //ok
- var offset1 = 0;
- var offset2 = 0;
- roomDoor.Direction = DoorDirection.W; //←
- nextRoomDoor.Direction = DoorDirection.S; //↓
-
- if (!FindCrossPassage(room, nextRoom, roomDoor, nextRoomDoor, ref offset1, ref offset2))
- {
- return false;
- }
-
- roomDoor.OriginPosition = new Vector2(room.GetHorizontalStart(), room.GetVerticalStart() + offset1);
- nextRoomDoor.OriginPosition = new Vector2(nextRoom.GetHorizontalStart() + offset2, nextRoom.GetVerticalEnd());
- cross = new Vector2(nextRoomDoor.OriginPosition.X, roomDoor.OriginPosition.Y);
- return true;
- }
-
- private bool TryConnect_SE_Door(RoomInfo room, RoomInfo nextRoom, RoomDoorInfo roomDoor, RoomDoorInfo nextRoomDoor, ref Vector2 cross)
- {
- var offset1 = 0;
- var offset2 = 0;
- roomDoor.Direction = DoorDirection.S; //↓
- nextRoomDoor.Direction = DoorDirection.E; //→
-
- if (!FindCrossPassage(room, nextRoom, roomDoor, nextRoomDoor, ref offset1, ref offset2))
- {
- return false;
- }
-
- roomDoor.OriginPosition = new Vector2(room.GetHorizontalStart() + offset1, room.GetVerticalEnd());
- nextRoomDoor.OriginPosition = new Vector2(nextRoom.GetHorizontalEnd(),
- nextRoom.GetVerticalStart() + offset2);
- cross = new Vector2(roomDoor.OriginPosition.X, nextRoomDoor.OriginPosition.Y);
- return true;
- }
-
- private bool TryConnect_WN_Door(RoomInfo room, RoomInfo nextRoom, RoomDoorInfo roomDoor, RoomDoorInfo nextRoomDoor, ref Vector2 cross)
- {
- var offset1 = 0;
- var offset2 = 0;
- roomDoor.Direction = DoorDirection.W; //←
- nextRoomDoor.Direction = DoorDirection.N; //↑
-
- if (!FindCrossPassage(room, nextRoom, roomDoor, nextRoomDoor, ref offset1, ref offset2))
- {
- return false;
- }
-
- roomDoor.OriginPosition =
- new Vector2(room.GetHorizontalStart(), room.GetVerticalStart() + offset1); //
- nextRoomDoor.OriginPosition = new Vector2(nextRoom.GetHorizontalStart() + offset2,
- nextRoom.GetVerticalStart());
- cross = new Vector2(nextRoomDoor.OriginPosition.X, roomDoor.OriginPosition.Y);
- return true;
- }
-
- private bool TryConnect_ES_Door(RoomInfo room, RoomInfo nextRoom, RoomDoorInfo roomDoor, RoomDoorInfo nextRoomDoor, ref Vector2 cross)
- {
- var offset1 = 0;
- var offset2 = 0;
- roomDoor.Direction = DoorDirection.E; //→
- nextRoomDoor.Direction = DoorDirection.S; //↓
-
- if (!FindCrossPassage(room, nextRoom, roomDoor, nextRoomDoor, ref offset1, ref offset2))
- {
- return false;
- }
-
- roomDoor.OriginPosition = new Vector2(room.GetHorizontalEnd(), room.GetVerticalStart() + offset1);
- nextRoomDoor.OriginPosition = new Vector2(nextRoom.GetHorizontalStart() + offset2,
- nextRoom.GetVerticalEnd());
- cross = new Vector2(nextRoomDoor.OriginPosition.X, roomDoor.OriginPosition.Y);
- return true;
- }
-
- private bool TryConnect_NW_Door(RoomInfo room, RoomInfo nextRoom, RoomDoorInfo roomDoor, RoomDoorInfo nextRoomDoor, ref Vector2 cross)
- {
- var offset1 = 0;
- var offset2 = 0;
- roomDoor.Direction = DoorDirection.N; //↑
- nextRoomDoor.Direction = DoorDirection.W; //←
-
- if (!FindCrossPassage(room, nextRoom, roomDoor, nextRoomDoor, ref offset1, ref offset2))
- {
- return false;
- }
-
- roomDoor.OriginPosition = new Vector2(room.GetHorizontalStart() + offset1, room.GetVerticalStart());
- nextRoomDoor.OriginPosition = new Vector2(nextRoom.GetHorizontalStart(),
- nextRoom.GetVerticalStart() + offset2);
- cross = new Vector2(roomDoor.OriginPosition.X, nextRoomDoor.OriginPosition.Y);
- return true;
- }
-
- private bool TryConnect_EN_Door(RoomInfo room, RoomInfo nextRoom, RoomDoorInfo roomDoor, RoomDoorInfo nextRoomDoor, ref Vector2 cross)
- {
- var offset1 = 0;
- var offset2 = 0;
- roomDoor.Direction = DoorDirection.E; //→
- nextRoomDoor.Direction = DoorDirection.N; //↑
-
- if (!FindCrossPassage(room, nextRoom, roomDoor, nextRoomDoor, ref offset1, ref offset2))
- {
- return false;
- }
-
- roomDoor.OriginPosition = new Vector2(room.GetHorizontalEnd(),
- room.GetVerticalStart() + offset1);
- nextRoomDoor.OriginPosition = new Vector2(nextRoom.GetHorizontalStart() + offset2, nextRoom.GetVerticalStart());
- cross = new Vector2(nextRoomDoor.OriginPosition.X, roomDoor.OriginPosition.Y);
- return true;
- }
-
- private bool TryConnect_SW_Door(RoomInfo room, RoomInfo nextRoom, RoomDoorInfo roomDoor, RoomDoorInfo nextRoomDoor, ref Vector2 cross)
- {
- var offset1 = 0;
- var offset2 = 0;
- roomDoor.Direction = DoorDirection.S; //↓
- nextRoomDoor.Direction = DoorDirection.W; //←
-
- if (!FindCrossPassage(room, nextRoom, roomDoor, nextRoomDoor, ref offset1, ref offset2))
- {
- return false;
- }
-
- roomDoor.OriginPosition = new Vector2(room.GetHorizontalStart() + offset1,
- room.GetVerticalEnd());
- nextRoomDoor.OriginPosition = new Vector2(nextRoom.GetHorizontalStart(), nextRoom.GetVerticalStart() + offset2);
- cross = new Vector2(roomDoor.OriginPosition.X, nextRoomDoor.OriginPosition.Y);
- return true;
- }
-
- ///
- /// 查找房间的连接通道, 函数返回是否找到对应的门, 通过 result 返回 x/y 轴坐标
- ///
- /// 第一个房间
- /// 第二个房间
- /// 第一个房间连接方向
- private List FindPassage(RoomInfo room, RoomInfo nextRoom, DoorDirection direction)
- {
- var room1 = room.RoomSplit.RoomInfo;
- var room2 = nextRoom.RoomSplit.RoomInfo;
-
- //用于存储符合生成条件的区域
- var rangeList = new List();
-
- foreach (var doorAreaInfo1 in room1.DoorAreaInfos)
- {
- if (doorAreaInfo1.Direction == direction)
- {
- //第二个门的方向
- var direction2 = GetReverseDirection(direction);
-
- foreach (var doorAreaInfo2 in room2.DoorAreaInfos)
- {
- if (doorAreaInfo2.Direction == direction2)
- {
- Vector2 range;
- if (direction == DoorDirection.E || direction == DoorDirection.W) //第二个门向← 或者 第二个门向→
- {
- range = CalcOverlapRange(
- room.GetVerticalStart() * GameConfig.TileCellSize + doorAreaInfo1.Start, room.GetVerticalStart() * GameConfig.TileCellSize + doorAreaInfo1.End,
- nextRoom.GetVerticalStart() * GameConfig.TileCellSize + doorAreaInfo2.Start, nextRoom.GetVerticalStart() * GameConfig.TileCellSize + doorAreaInfo2.End
- );
- }
- else //第二个门向↑ 或者 第二个门向↓
- {
- range = CalcOverlapRange(
- room.GetHorizontalStart() * GameConfig.TileCellSize + doorAreaInfo1.Start, room.GetHorizontalStart() * GameConfig.TileCellSize + doorAreaInfo1.End,
- nextRoom.GetHorizontalStart() * GameConfig.TileCellSize + doorAreaInfo2.Start, nextRoom.GetHorizontalStart() * GameConfig.TileCellSize + doorAreaInfo2.End
- );
- }
- //交集范围够生成门
- if (range.Y - range.X >= GameConfig.CorridorWidth * GameConfig.TileCellSize)
- {
- rangeList.Add(new Vector2I((int)(range.X / 16), (int)(range.Y / 16) - GameConfig.CorridorWidth));
- }
- }
- }
- }
- }
-
- return rangeList;
- }
-
- ///
- /// 用于计算重叠区域坐标, 可以理解为一维轴上4个点的中间两个点, 返回的x为起始点, y为结束点
- ///
- private Vector2 CalcOverlapRange(float start1, float end1, float start2, float end2)
- {
- return new Vector2(Mathf.Max(start1, start2), Mathf.Min(end1, end2));
- }
-
- ///
- /// 返回 p1 - p2 是否在 start - end 范围内
- ///
- private bool IsInRange(float start, float end, float p1, float p2)
- {
- return p1 >= start && p2 <= end;
- }
-
- //返回指定方向的反方向
- //0上, 1右, 2下, 3左
- private int GetReverseDirection(int direction)
- {
- switch (direction)
- {
- case 0: return 2;
- case 1: return 3;
- case 2: return 0;
- case 3: return 1;
- }
-
- return 2;
- }
-
- //返回参数方向的反方向
- private DoorDirection GetReverseDirection(DoorDirection direction)
- {
- switch (direction)
- {
- case DoorDirection.E:
- return DoorDirection.W;
- case DoorDirection.W:
- return DoorDirection.E;
- case DoorDirection.S:
- return DoorDirection.N;
- case DoorDirection.N:
- return DoorDirection.S;
- }
-
- return DoorDirection.S;
- }
-
- //将两个门间的过道占用数据存入RoomGrid
- private bool AddCorridorToGridRange(RoomDoorInfo door1, RoomDoorInfo door2)
- {
- var point1 = door1.OriginPosition;
- var point2 = door2.OriginPosition;
- var pos = new Vector2(Mathf.Min(point1.X, point2.X), Mathf.Min(point1.Y, point2.Y));
- var size = new Vector2(
- point1.X == point2.X ? GameConfig.CorridorWidth : Mathf.Abs(point1.X - point2.X),
- point1.Y == point2.Y ? GameConfig.CorridorWidth : Mathf.Abs(point1.Y - point2.Y)
- );
-
- Vector2 collPos;
- Vector2 collSize;
- if (point1.X == point2.X) //纵向加宽, 防止贴到其它墙
- {
- collPos = new Vector2(pos.X - GameConfig.RoomSpace, pos.Y);
- collSize = new Vector2(size.X + GameConfig.RoomSpace * 2, size.Y);
- }
- else //横向加宽, 防止贴到其它墙
- {
- collPos = new Vector2(pos.X, pos.Y - GameConfig.RoomSpace);
- collSize = new Vector2(size.X, size.Y + GameConfig.RoomSpace * 2);
- }
-
- if (_roomGrid.RectCollision(collPos, collSize))
- {
- return false;
- }
-
- _roomGrid.AddRect(pos, size, true);
- return true;
- }
-
- //将两个门间的过道占用数据存入RoomGrid, 该重载加入拐角点
- private bool AddCorridorToGridRange(RoomDoorInfo door1, RoomDoorInfo door2, Vector2 cross)
- {
- var point1 = door1.OriginPosition;
- var point2 = door2.OriginPosition;
- var pos1 = new Vector2(Mathf.Min(point1.X, cross.X), Mathf.Min(point1.Y, cross.Y));
- var size1 = new Vector2(
- point1.X == cross.X ? GameConfig.CorridorWidth : Mathf.Abs(point1.X - cross.X),
- point1.Y == cross.Y ? GameConfig.CorridorWidth : Mathf.Abs(point1.Y - cross.Y)
- );
- var pos2 = new Vector2(Mathf.Min(point2.X, cross.X), Mathf.Min(point2.Y, cross.Y));
- var size2 = new Vector2(
- point2.X == cross.X ? GameConfig.CorridorWidth : Mathf.Abs(point2.X - cross.X),
- point2.Y == cross.Y ? GameConfig.CorridorWidth : Mathf.Abs(point2.Y - cross.Y)
- );
-
- Vector2 collPos1;
- Vector2 collSize1;
- if (point1.X == cross.X) //纵向加宽, 防止贴到其它墙
- {
- collPos1 = new Vector2(pos1.X - GameConfig.RoomSpace, pos1.Y);
- collSize1 = new Vector2(size1.X + GameConfig.RoomSpace * 2, size1.Y);
- }
- else //横向加宽, 防止贴到其它墙
- {
- collPos1 = new Vector2(pos1.X, pos1.Y - GameConfig.RoomSpace);
- collSize1 = new Vector2(size1.X, size1.Y + GameConfig.RoomSpace * 2);
- }
-
- if (_roomGrid.RectCollision(collPos1, collSize1))
- {
- return false;
- }
-
- Vector2 collPos2;
- Vector2 collSize2;
- if (point2.X == cross.X) //纵向加宽, 防止贴到其它墙
- {
- collPos2 = new Vector2(pos2.X - GameConfig.RoomSpace, pos2.Y);
- collSize2 = new Vector2(size2.X + GameConfig.RoomSpace * 2, size2.Y);
- }
- else //横向加宽, 防止贴到其它墙
- {
- collPos2 = new Vector2(pos2.X, pos2.Y - GameConfig.RoomSpace);
- collSize2 = new Vector2(size2.X, size2.Y + GameConfig.RoomSpace * 2);
- }
-
- if (_roomGrid.RectCollision(collPos2, collSize2))
- {
- return false;
- }
-
- _roomGrid.AddRect(pos1, size1, true);
- _roomGrid.AddRect(pos2, size2, true);
- return true;
- }
-}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/room/RoomManager.cs b/DungeonShooting_Godot/src/game/room/RoomManager.cs
index a11490f..1afb6b0 100644
--- a/DungeonShooting_Godot/src/game/room/RoomManager.cs
+++ b/DungeonShooting_Godot/src/game/room/RoomManager.cs
@@ -41,7 +41,7 @@
private AutoTileConfig _autoTileConfig;
private Font _font;
- private GenerateDungeon _generateDungeon;
+ private DungeonGenerator _dungeonGenerator;
private int _affiliationIndex = 0;
@@ -62,14 +62,14 @@
var nowTicks = DateTime.Now.Ticks;
//生成地牢房间
- _generateDungeon = new GenerateDungeon();
- _generateDungeon.Generate();
+ _dungeonGenerator = new DungeonGenerator();
+ _dungeonGenerator.Generate();
//填充地牢
_autoTileConfig = new AutoTileConfig();
_dungeonTile = new DungeonTile(TileRoot);
- _dungeonTile.AutoFillRoomTile(_autoTileConfig, _generateDungeon.StartRoom);
+ _dungeonTile.AutoFillRoomTile(_autoTileConfig, _dungeonGenerator.StartRoom);
//生成寻路网格, 这一步操作只生成过道的导航
_dungeonTile.GenerateNavigationPolygon(DungeonTile.AisleFloorMapLayer);
@@ -80,8 +80,8 @@
//门导航区域数据
_roomStaticNavigationList.AddRange(_dungeonTile.GetConnectDoorPolygonData());
//初始化所有房间
- _generateDungeon.EachRoom(InitRoom);
-
+ _dungeonGenerator.EachRoom(InitRoom);
+
GD.Print("生成地牢用时: " + (DateTime.Now.Ticks - nowTicks) / 10000 + "毫秒");
//播放bgm
diff --git a/DungeonShooting_Godot/src/test/TestDungeonGenerator.cs b/DungeonShooting_Godot/src/test/TestDungeonGenerator.cs
new file mode 100644
index 0000000..5fae0a7
--- /dev/null
+++ b/DungeonShooting_Godot/src/test/TestDungeonGenerator.cs
@@ -0,0 +1,109 @@
+
+using Godot;
+
+///
+/// 测试地牢生成
+///
+public partial class TestDungeonGenerator : Node2D
+{
+ [Export] public NodePath TileMapPath;
+ [Export] public NodePath Camera3D;
+
+ private TileMap _tileMap;
+ private Camera2D _camera;
+
+ private DungeonGenerator _dungeonGenerator;
+ private Font _font;
+
+ // public override void _Ready()
+ // {
+ // _tileMap = GetNode(TileMapPath);
+ // _camera = GetNode(Camera3D);
+ //
+ // _font = ResourceManager.Load(ResourcePath.resource_font_cn_font_36_tres);
+ //
+ // _generateDungeon = new GenerateDungeon();
+ // _generateDungeon.Generate();
+ //
+ // foreach (var info in _generateDungeon.RoomInfos)
+ // {
+ // //临时铺上地砖
+ // var id = (int)_tileMap.TileSet.GetTilesIds()[0];
+ // for (int i = 0; i < info.Size.X; i++)
+ // {
+ // for (int j = 0; j < info.Size.Y; j++)
+ // {
+ // _tileMap.SetCell(i + (int)info.Position.X, j + (int)info.Position.Y, id);
+ // }
+ // }
+ // }
+ // }
+ //
+ // public override void _Process(float delta)
+ // {
+ // //移动相机位置
+ // var dir = Input.GetVector("ui_left", "ui_right", "ui_up", "ui_down");
+ // _camera.Position += dir * 1000 * delta;
+ //
+ // Update();
+ // }
+ //
+ // public override void _Draw()
+ // {
+ // DrawRoomInfo(_generateDungeon.StartRoom);
+ //
+ // }
+ //
+ // private void DrawRoomInfo(RoomInfo room)
+ // {
+ // var cellSize = _tileMap.CellSize;
+ // var pos1 = (room.Position + room.Size / 2) * cellSize;
+ // foreach (var nextRoom in room.Next)
+ // {
+ // var pos2 = (nextRoom.Position + nextRoom.Size / 2) * cellSize;
+ // DrawLine(pos1, pos2, Colors.Red);
+ // DrawRoomInfo(nextRoom);
+ // }
+ //
+ // DrawString(_font, pos1, room.Id.ToString(), Colors.Yellow);
+ //
+ // foreach (var roomDoor in room.Doors)
+ // {
+ // var originPos = roomDoor.OriginPosition * cellSize;
+ // switch (roomDoor.Direction)
+ // {
+ // case DoorDirection.E:
+ // DrawLine(originPos, originPos + new Vector2(3, 0) * cellSize, Colors.Yellow);
+ // DrawLine(originPos + new Vector2(0, 4) * cellSize, originPos + new Vector2(3, 4) * cellSize,
+ // Colors.Yellow);
+ // break;
+ // case DoorDirection.W:
+ // DrawLine(originPos, originPos - new Vector2(3, 0) * cellSize, Colors.Yellow);
+ // DrawLine(originPos + new Vector2(0, 4) * cellSize, originPos - new Vector2(3, -4) * cellSize,
+ // Colors.Yellow);
+ // break;
+ // case DoorDirection.S:
+ // DrawLine(originPos, originPos + new Vector2(0, 3) * cellSize, Colors.Yellow);
+ // DrawLine(originPos + new Vector2(4, 0) * cellSize, originPos + new Vector2(4, 3) * cellSize,
+ // Colors.Yellow);
+ // break;
+ // case DoorDirection.N:
+ // DrawLine(originPos, originPos - new Vector2(0, 3) * cellSize, Colors.Yellow);
+ // DrawLine(originPos + new Vector2(4, 0) * cellSize, originPos - new Vector2(-4, 3) * cellSize,
+ // Colors.Yellow);
+ // break;
+ // }
+ //
+ // if (roomDoor.HasCross && roomDoor.RoomInfo.Id < roomDoor.ConnectRoom.Id)
+ // {
+ // DrawRect(new Rect2(roomDoor.Cross * cellSize, cellSize * 4), Colors.Yellow);
+ // }
+ // }
+ //
+ // //绘制地图上被占用的网格
+ // // _generateDungeon.RoomGrid.ForEach((x, y, value) =>
+ // // {
+ // // DrawRect(new Rect2(new Vector2(x, y) * cellSize + new Vector2(6, 6), new Vector2(4, 4)), Colors.Green);
+ // // });
+ // }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/test/TestGenerateDungeon.cs b/DungeonShooting_Godot/src/test/TestGenerateDungeon.cs
deleted file mode 100644
index 2412364..0000000
--- a/DungeonShooting_Godot/src/test/TestGenerateDungeon.cs
+++ /dev/null
@@ -1,109 +0,0 @@
-
-using Godot;
-
-///
-/// 测试地牢生成
-///
-public partial class TestGenerateDungeon : Node2D
-{
- [Export] public NodePath TileMapPath;
- [Export] public NodePath Camera3D;
-
- private TileMap _tileMap;
- private Camera2D _camera;
-
- private GenerateDungeon _generateDungeon;
- private Font _font;
-
- // public override void _Ready()
- // {
- // _tileMap = GetNode(TileMapPath);
- // _camera = GetNode(Camera3D);
- //
- // _font = ResourceManager.Load(ResourcePath.resource_font_cn_font_36_tres);
- //
- // _generateDungeon = new GenerateDungeon();
- // _generateDungeon.Generate();
- //
- // foreach (var info in _generateDungeon.RoomInfos)
- // {
- // //临时铺上地砖
- // var id = (int)_tileMap.TileSet.GetTilesIds()[0];
- // for (int i = 0; i < info.Size.X; i++)
- // {
- // for (int j = 0; j < info.Size.Y; j++)
- // {
- // _tileMap.SetCell(i + (int)info.Position.X, j + (int)info.Position.Y, id);
- // }
- // }
- // }
- // }
- //
- // public override void _Process(float delta)
- // {
- // //移动相机位置
- // var dir = Input.GetVector("ui_left", "ui_right", "ui_up", "ui_down");
- // _camera.Position += dir * 1000 * delta;
- //
- // Update();
- // }
- //
- // public override void _Draw()
- // {
- // DrawRoomInfo(_generateDungeon.StartRoom);
- //
- // }
- //
- // private void DrawRoomInfo(RoomInfo room)
- // {
- // var cellSize = _tileMap.CellSize;
- // var pos1 = (room.Position + room.Size / 2) * cellSize;
- // foreach (var nextRoom in room.Next)
- // {
- // var pos2 = (nextRoom.Position + nextRoom.Size / 2) * cellSize;
- // DrawLine(pos1, pos2, Colors.Red);
- // DrawRoomInfo(nextRoom);
- // }
- //
- // DrawString(_font, pos1, room.Id.ToString(), Colors.Yellow);
- //
- // foreach (var roomDoor in room.Doors)
- // {
- // var originPos = roomDoor.OriginPosition * cellSize;
- // switch (roomDoor.Direction)
- // {
- // case DoorDirection.E:
- // DrawLine(originPos, originPos + new Vector2(3, 0) * cellSize, Colors.Yellow);
- // DrawLine(originPos + new Vector2(0, 4) * cellSize, originPos + new Vector2(3, 4) * cellSize,
- // Colors.Yellow);
- // break;
- // case DoorDirection.W:
- // DrawLine(originPos, originPos - new Vector2(3, 0) * cellSize, Colors.Yellow);
- // DrawLine(originPos + new Vector2(0, 4) * cellSize, originPos - new Vector2(3, -4) * cellSize,
- // Colors.Yellow);
- // break;
- // case DoorDirection.S:
- // DrawLine(originPos, originPos + new Vector2(0, 3) * cellSize, Colors.Yellow);
- // DrawLine(originPos + new Vector2(4, 0) * cellSize, originPos + new Vector2(4, 3) * cellSize,
- // Colors.Yellow);
- // break;
- // case DoorDirection.N:
- // DrawLine(originPos, originPos - new Vector2(0, 3) * cellSize, Colors.Yellow);
- // DrawLine(originPos + new Vector2(4, 0) * cellSize, originPos - new Vector2(-4, 3) * cellSize,
- // Colors.Yellow);
- // break;
- // }
- //
- // if (roomDoor.HasCross && roomDoor.RoomInfo.Id < roomDoor.ConnectRoom.Id)
- // {
- // DrawRect(new Rect2(roomDoor.Cross * cellSize, cellSize * 4), Colors.Yellow);
- // }
- // }
- //
- // //绘制地图上被占用的网格
- // // _generateDungeon.RoomGrid.ForEach((x, y, value) =>
- // // {
- // // DrawRect(new Rect2(new Vector2(x, y) * cellSize + new Vector2(6, 6), new Vector2(4, 4)), Colors.Green);
- // // });
- // }
-}
\ No newline at end of file