diff --git a/DungeonShooting_Godot/src/framework/map/DoorNavigationInfo.cs b/DungeonShooting_Godot/src/framework/map/DoorNavigationInfo.cs new file mode 100644 index 0000000..8bdf623 --- /dev/null +++ b/DungeonShooting_Godot/src/framework/map/DoorNavigationInfo.cs @@ -0,0 +1,15 @@ + +using Godot; + +public class DoorNavigationInfo +{ + public DoorNavigationInfo(NavigationRegion2D navigationNode, NavigationPolygonData navigationData) + { + NavigationNode = navigationNode; + NavigationData = navigationData; + } + + public NavigationRegion2D NavigationNode; + + public NavigationPolygonData NavigationData; +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/framework/map/DungeonTile.cs b/DungeonShooting_Godot/src/framework/map/DungeonTile.cs index fcf1cb9..359abea 100644 --- a/DungeonShooting_Godot/src/framework/map/DungeonTile.cs +++ b/DungeonShooting_Godot/src/framework/map/DungeonTile.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; +using System.Linq; using Godot; /// @@ -39,7 +40,19 @@ private readonly List _polygonDataList = new List(); //连接门的导航区域 - private readonly List _connectDoorPolygonDataList = new List(); + private readonly List _connectNavigationItemList = new List(); + + private class DoorNavigationItem + { + public NavigationPolygonData NavigationPolygonData; + public RoomDoorInfo DoorInfo; + + public DoorNavigationItem(NavigationPolygonData navigationPolygonData, RoomDoorInfo doorInfo) + { + NavigationPolygonData = navigationPolygonData; + DoorInfo = doorInfo; + } + } //---------------------------------------------------- @@ -55,12 +68,12 @@ } /// - /// 根据 roomInfo 和 config 数据自动填充 tileMap 参数中的地图数据 + /// 根据 startRoom 和 config 数据自动填充 tileMap 参数中的地图数据 /// - public void AutoFillRoomTile(AutoTileConfig config, RoomInfo roomInfo) + public void AutoFillRoomTile(AutoTileConfig config, RoomInfo startRoom) { - _connectDoorPolygonDataList.Clear(); - _AutoFillRoomTile(config, roomInfo); + _connectNavigationItemList.Clear(); + _AutoFillRoomTile(config, startRoom); } private void _AutoFillRoomTile(AutoTileConfig config, RoomInfo roomInfo) @@ -150,11 +163,11 @@ if (dir == 0) //横向 { - FullHorizontalAisleWall(config, rect, 0); + FullHorizontalAisleWall(doorInfo, config, rect, 0); } else //纵向 { - FullVerticalAisleWall(config, rect, 0); + FullVerticalAisleWall(doorInfo, config, rect, 0); } } else //带交叉点 @@ -257,20 +270,20 @@ //墙壁, 0横向, 1纵向 if (dir1 == 0) { - FullHorizontalAisleWall(config, rect, doorDir1 == DoorDirection.W ? 1: 2); + FullHorizontalAisleWall(doorInfo, config, rect, doorDir1 == DoorDirection.W ? 1: 2); } else { - FullVerticalAisleWall(config, rect, doorDir1 == DoorDirection.N ? 1 : 2); + FullVerticalAisleWall(doorInfo, config, rect, doorDir1 == DoorDirection.N ? 1 : 2); } if (dir2 == 0) { - FullHorizontalAisleWall(config, rect2, doorDir2 == DoorDirection.W ? 1 : 2); + FullHorizontalAisleWall(doorInfo, config, rect2, doorDir2 == DoorDirection.W ? 1 : 2); } else { - FullVerticalAisleWall(config, rect2, doorDir2 == DoorDirection.N ? 1 : 2); + FullVerticalAisleWall(doorInfo, config, rect2, doorDir2 == DoorDirection.N ? 1 : 2); } if ((doorDir1 == DoorDirection.N && doorDir2 == DoorDirection.E) || //↑→ @@ -392,7 +405,7 @@ } } - private void FullHorizontalAisleWall(AutoTileConfig config, Rect2 rect, int type) + private void FullHorizontalAisleWall(RoomDoorInfo doorInfo, AutoTileConfig config, Rect2 rect, int type) { FillRect(AisleFloorMapLayer, config.Floor, rect.Position + new Vector2(0, 1), rect.Size - new Vector2(0, 2)); FillRect(MiddleMapLayer, config.T, rect.Position, new Vector2(rect.Size.X, 1)); @@ -410,6 +423,7 @@ var x = rect.Position.X * GenerateDungeon.TileCellSize; var y = rect.Position.Y * GenerateDungeon.TileCellSize; AddDoorNavigation( + doorInfo, new SerializeVector2(x - GenerateDungeon.TileCellSize * 1.5f, y + GenerateDungeon.TileCellSize * 1.5f), new SerializeVector2(x + GenerateDungeon.TileCellSize * 0.5f, y + GenerateDungeon.TileCellSize * 1.5f), new SerializeVector2(x + GenerateDungeon.TileCellSize * 0.5f, y + GenerateDungeon.TileCellSize * 2.5f), @@ -430,6 +444,7 @@ var x = rect.Position.X * GenerateDungeon.TileCellSize; var y = rect.Position.Y * GenerateDungeon.TileCellSize; AddDoorNavigation( + doorInfo, new SerializeVector2(x - GenerateDungeon.TileCellSize * 1.5f + (rect.Size.X + 1) * GenerateDungeon.TileCellSize, y + GenerateDungeon.TileCellSize * 1.5f), new SerializeVector2(x + GenerateDungeon.TileCellSize * 0.5f + (rect.Size.X + 1) * GenerateDungeon.TileCellSize, y + GenerateDungeon.TileCellSize * 1.5f), new SerializeVector2(x + GenerateDungeon.TileCellSize * 0.5f + (rect.Size.X + 1) * GenerateDungeon.TileCellSize, y + GenerateDungeon.TileCellSize * 2.5f), @@ -438,7 +453,7 @@ } } - private void FullVerticalAisleWall(AutoTileConfig config, Rect2 rect, int type) + private void FullVerticalAisleWall(RoomDoorInfo doorInfo, AutoTileConfig config, Rect2 rect, int type) { FillRect(AisleFloorMapLayer, config.Floor, rect.Position + new Vector2(1, 0), rect.Size - new Vector2(2, 0)); FillRect(TopMapLayer, config.L, rect.Position, new Vector2(1, rect.Size.Y)); @@ -456,6 +471,7 @@ var x = rect.Position.X * GenerateDungeon.TileCellSize; var y = rect.Position.Y * GenerateDungeon.TileCellSize; AddDoorNavigation( + doorInfo, new SerializeVector2(x + GenerateDungeon.TileCellSize * 1.5f, y - GenerateDungeon.TileCellSize * 1.5f), new SerializeVector2(x + GenerateDungeon.TileCellSize * 2.5f, y - GenerateDungeon.TileCellSize * 1.5f), new SerializeVector2(x + GenerateDungeon.TileCellSize * 2.5f, y + GenerateDungeon.TileCellSize * 0.5f), @@ -475,6 +491,7 @@ var x = rect.Position.X * GenerateDungeon.TileCellSize; var y = rect.Position.Y * GenerateDungeon.TileCellSize; AddDoorNavigation( + doorInfo, new SerializeVector2(x + GenerateDungeon.TileCellSize * 1.5f, y - GenerateDungeon.TileCellSize * 1.5f + (rect.Size.Y + 1) * GenerateDungeon.TileCellSize), new SerializeVector2(x + GenerateDungeon.TileCellSize * 2.5f, y - GenerateDungeon.TileCellSize * 1.5f + (rect.Size.Y + 1) * GenerateDungeon.TileCellSize), new SerializeVector2(x + GenerateDungeon.TileCellSize * 2.5f, y + GenerateDungeon.TileCellSize * 0.5f + (rect.Size.Y + 1) * GenerateDungeon.TileCellSize), @@ -483,7 +500,7 @@ } } - private void AddDoorNavigation(SerializeVector2 p1, SerializeVector2 p2, SerializeVector2 p3, SerializeVector2 p4) + private void AddDoorNavigation(RoomDoorInfo doorInfo, SerializeVector2 p1, SerializeVector2 p2, SerializeVector2 p3, SerializeVector2 p4) { var polygonData = new NavigationPolygonData(); polygonData.Type = NavigationPolygonType.Out; @@ -491,7 +508,7 @@ polygonData.Points.Add(p2); polygonData.Points.Add(p3); polygonData.Points.Add(p4); - _connectDoorPolygonDataList.Add(polygonData); + _connectNavigationItemList.Add(new DoorNavigationItem(polygonData, doorInfo)); } //报错数据 @@ -585,14 +602,15 @@ CreateNavigationRegion(navigationRoot, polygonData); } - for (var i = 0; i < _connectDoorPolygonDataList.Count; i++) + for (var i = 0; i < _connectNavigationItemList.Count; i++) { - var polygonData = _connectDoorPolygonDataList[i]; - CreateNavigationRegion(navigationRoot, polygonData); + var item = _connectNavigationItemList[i]; + var node = CreateNavigationRegion(navigationRoot, item.NavigationPolygonData); + item.DoorInfo.Navigation = new DoorNavigationInfo(node, item.NavigationPolygonData); } } - private void CreateNavigationRegion(Node2D navigationRoot, NavigationPolygonData polygonData) + private NavigationRegion2D CreateNavigationRegion(Node2D navigationRoot, NavigationPolygonData polygonData) { var polygon = new NavigationPolygon(); polygon.AddOutline(polygonData.ConvertPointsToVector2Array()); @@ -601,6 +619,7 @@ navigationPolygon.Name = "NavigationRegion" + (navigationRoot.GetChildCount() + 1); navigationPolygon.NavigationPolygon = polygon; navigationRoot.AddChild(navigationPolygon); + return navigationPolygon; } /// @@ -616,7 +635,12 @@ /// public NavigationPolygonData[] GetConnectDoorPolygonData() { - return _connectDoorPolygonDataList.ToArray(); + var array = new NavigationPolygonData[_connectNavigationItemList.Count]; + for (var i = 0; i < _connectNavigationItemList.Count; i++) + { + array[i] = _connectNavigationItemList[i].NavigationPolygonData; + } + return array; } /// diff --git a/DungeonShooting_Godot/src/framework/map/NavigationPolygonData.cs b/DungeonShooting_Godot/src/framework/map/NavigationPolygonData.cs index f97f8ca..7938cff 100644 --- a/DungeonShooting_Godot/src/framework/map/NavigationPolygonData.cs +++ b/DungeonShooting_Godot/src/framework/map/NavigationPolygonData.cs @@ -30,6 +30,16 @@ /// [JsonInclude] public List Points = new List(); + public NavigationPolygonData() + { + } + + public NavigationPolygonData(NavigationPolygonType type, List points) + { + Type = type; + Points = points; + } + /// /// 将 Points 字段转为 Vector2[] 类型数据并返回 /// diff --git a/DungeonShooting_Godot/src/framework/map/RoomDoorInfo.cs b/DungeonShooting_Godot/src/framework/map/RoomDoorInfo.cs index cd5d539..66cfb70 100644 --- a/DungeonShooting_Godot/src/framework/map/RoomDoorInfo.cs +++ b/DungeonShooting_Godot/src/framework/map/RoomDoorInfo.cs @@ -15,12 +15,12 @@ /// 所在的房间 /// public RoomInfo RoomInfo; - + /// /// 连接的门 /// public RoomDoorInfo ConnectDoor; - + /// /// 连接的房间 /// @@ -35,9 +35,14 @@ /// 与下一道门是否有交叉点 /// public bool HasCross; - + /// /// 与下一道门的交叉点 /// public Vector2 Cross; + + /// + /// 导航网格 + /// + public DoorNavigationInfo Navigation; } \ 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 6a9e47b..c4e5be8 100644 --- a/DungeonShooting_Godot/src/game/room/RoomManager.cs +++ b/DungeonShooting_Godot/src/game/room/RoomManager.cs @@ -63,13 +63,13 @@ _dungeonTile = new DungeonTile(TileRoot); _dungeonTile.AutoFillRoomTile(_autoTileConfig, _generateDungeon.StartRoom); - //生成寻路网格 + //生成寻路网格, 这一步操作只生成过道的导航 _dungeonTile.GenerateNavigationPolygon(DungeonTile.AisleFloorMapLayer); - //挂载导航区域 + //挂载过道导航区域 _dungeonTile.MountNavigationPolygon(this); _roomStaticNavigationList.AddRange(_dungeonTile.GetPolygonData()); _roomStaticNavigationList.AddRange(_dungeonTile.GetConnectDoorPolygonData()); - //挂载所有导航区域 + //挂载所有房间的导航区域 _generateDungeon.EachRoom(MountNavFromRoomInfo); GD.Print("生成地牢用时: " + (DateTime.Now.Ticks - nowTicks) / 10000 + "毫秒"); @@ -181,13 +181,15 @@ polygonPointArray[j] = polygonPointArray[j] + (roomInfo.Position + Vector2I.One) * GenerateDungeon.TileCellSize; } polygon.AddOutline(polygonPointArray); - - //存入汇总列表 - _roomStaticNavigationList.Add(new NavigationPolygonData() + + var points = new List(); + for (var j = 0; j < polygonPointArray.Length; j++) { - Type = navigationPolygonData.Type, - Points = polygonPointArray.Select(point => new SerializeVector2(point)).ToList(), - }); + points.Add(new SerializeVector2(polygonPointArray[j])); + } + + //存入汇总列表 + _roomStaticNavigationList.Add(new NavigationPolygonData(navigationPolygonData.Type, points)); } polygon.MakePolygonsFromOutlines(); var navigationPolygon = new NavigationRegion2D();