diff --git a/DungeonShooting_Godot/src/framework/SerializeVector2.cs b/DungeonShooting_Godot/src/framework/SerializeVector2.cs
new file mode 100644
index 0000000..f4e53c7
--- /dev/null
+++ b/DungeonShooting_Godot/src/framework/SerializeVector2.cs
@@ -0,0 +1,53 @@
+
+using System.Text.Json.Serialization;
+using Godot;
+
+///
+/// 可序列化的 Vector2 对象
+///
+public class SerializeVector2
+{
+ public SerializeVector2(float x, float y)
+ {
+ X = x;
+ Y = y;
+ }
+
+ public SerializeVector2(Vector2 v)
+ {
+ X = v.X;
+ Y = v.Y;
+ }
+
+ public SerializeVector2(Vector2I v)
+ {
+ X = v.X;
+ Y = v.Y;
+ }
+
+ public SerializeVector2()
+ {
+
+ }
+
+ [JsonInclude]
+ public float X { get; private set; }
+ [JsonInclude]
+ public float Y { get; private set; }
+
+ ///
+ /// 转为 Vector2
+ ///
+ public Vector2 AsVector2()
+ {
+ return new Vector2(X, Y);
+ }
+
+ ///
+ /// 转为 Vector2I
+ ///
+ public Vector2I AsVector2I()
+ {
+ return new Vector2I((int)X, (int)Y);
+ }
+}
\ 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 ea79836..ade5c71 100644
--- a/DungeonShooting_Godot/src/framework/map/DungeonTile.cs
+++ b/DungeonShooting_Godot/src/framework/map/DungeonTile.cs
@@ -35,9 +35,11 @@
private readonly List _polygonDataList = new List();
//----------------------------------------------------
-
- private TileMap _tileRoot;
+ private TileMap _tileRoot;
+ //地面地砖在 Atlas 的位置
+ private List _floorAtlasCoords;
+
public DungeonTile(TileMap tileRoot)
{
_tileRoot = tileRoot;
@@ -56,7 +58,7 @@
//铺房间
if (roomInfo.RoomSplit == null)
{
- FillRect(FloorMapLayer, config.Ground, roomInfo.Position + Vector2.One,
+ FillRect(FloorMapLayer, config.Floor, roomInfo.Position + Vector2.One,
roomInfo.Size - new Vector2(2, 2));
FillRect(TopMapLayer, config.IN_LT, roomInfo.Position, Vector2.One);
@@ -234,7 +236,7 @@
break;
}
- FillRect(FloorMapLayer, config.Ground, doorInfo.Cross + Vector2.One,
+ FillRect(FloorMapLayer, config.Floor, doorInfo.Cross + Vector2.One,
new Vector2(GenerateDungeon.CorridorWidth - 2, GenerateDungeon.CorridorWidth - 2));
//墙壁, 0横向, 1纵向
@@ -378,39 +380,39 @@
private void FullHorizontalGalleryWall(AutoTileConfig config, Rect2 rect, int type)
{
- FillRect(FloorMapLayer, config.Ground, rect.Position + new Vector2(0, 1), rect.Size - new Vector2(0, 2));
+ FillRect(FloorMapLayer, 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));
FillRect(TopMapLayer, config.B, rect.Position + new Vector2(0, rect.Size.Y - 1), new Vector2(rect.Size.X, 1));
//左
ClearRect(TopMapLayer, rect.Position + new Vector2(-1, 1), new Vector2(1, rect.Size.Y - 2));
if (type == 1)
{
- FillRect(FloorMapLayer, config.Ground, rect.Position + new Vector2(-1, 1), new Vector2(1, rect.Size.Y - 2));
+ FillRect(FloorMapLayer, config.Floor, rect.Position + new Vector2(-1, 1), new Vector2(1, rect.Size.Y - 2));
}
//右
ClearRect(TopMapLayer, rect.Position + new Vector2(rect.Size.X, 1), new Vector2(1, rect.Size.Y - 2));
if (type == 2)
{
- FillRect(FloorMapLayer, config.Ground, rect.Position + new Vector2(rect.Size.X, 1), new Vector2(1, rect.Size.Y - 2));
+ FillRect(FloorMapLayer, config.Floor, rect.Position + new Vector2(rect.Size.X, 1), new Vector2(1, rect.Size.Y - 2));
}
}
private void FullVerticalGalleryWall(AutoTileConfig config, Rect2 rect, int type)
{
- FillRect(FloorMapLayer, config.Ground, rect.Position + new Vector2(1, 0), rect.Size - new Vector2(2, 0));
+ FillRect(FloorMapLayer, 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));
FillRect(TopMapLayer, config.R, rect.Position + new Vector2(rect.Size.X - 1, 0), new Vector2(1, rect.Size.Y));
//上
ClearRect(TopMapLayer, rect.Position + new Vector2(1, -1), new Vector2(rect.Size.X - 2, 1));
if (type == 1)
{
- FillRect(FloorMapLayer, config.Ground, rect.Position + new Vector2(1, -1), new Vector2(rect.Size.X - 2, 1));
+ FillRect(FloorMapLayer, config.Floor, rect.Position + new Vector2(1, -1), new Vector2(rect.Size.X - 2, 1));
}
//下
ClearRect(MiddleMapLayer, rect.Position + new Vector2(1, rect.Size.Y), new Vector2(rect.Size.X - 2, 1));
if (type == 2)
{
- FillRect(FloorMapLayer, config.Ground, rect.Position + new Vector2(1, rect.Size.Y), new Vector2(rect.Size.X - 2, 1));
+ FillRect(FloorMapLayer, config.Floor, rect.Position + new Vector2(1, rect.Size.Y), new Vector2(rect.Size.X - 2, 1));
}
}
@@ -426,11 +428,53 @@
}
///
- /// 计算网格区域, 并将导航区域挂载到 navigationRoot 上
+ /// 计算并动生成导航区域, layer 为需要计算的层级,如果没有设置 floorAtlasCoords,则该 layer 下不为空的地砖都将视为可行走区域
///
- public void GenerateNavigationPolygon(Node2D navigationRoot)
+ public void GenerateNavigationPolygon(int layer)
{
- GenerateNavigationPolygon();
+ var size = new Vector2(_tileRoot.CellQuadrantSize, _tileRoot.CellQuadrantSize);
+
+ var rect = _tileRoot.GetUsedRect();
+
+ var x = rect.Position.X;
+ var y = rect.Position.Y;
+ var w = rect.Size.X;
+ var h = rect.Size.Y;
+
+ for (int j = y; j < h; j++)
+ {
+ for (int i = x; i < w; i++)
+ {
+ if (IsWayTile(layer, i, j))
+ {
+ if (!_usePoints.Contains(new Vector2(i, j)))
+ {
+ NavigationPolygonData polygonData = null;
+
+ if (!IsWayTile(layer, i, j - 1))
+ {
+ polygonData = CalcOutline(layer, i, j, size);
+ }
+ else if (!IsWayTile(layer, i, j + 1))
+ {
+ polygonData = CalcInline(layer, i, j, size);
+ }
+
+ if (polygonData != null)
+ {
+ _polygonDataList.Add(polygonData);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ ///
+ /// 将导航区域挂载到 navigationRoot 上
+ ///
+ public void MountNavigationPolygon(Node2D navigationRoot)
+ {
//TestData();
// 在 Godot4.0_rc6 中 如果将所有点都放在 NavigationPolygon 里面, 即使点是对的, 但调用 MakePolygonsFromOutlines 还是可能会报错, 这应该是个bug
// for (var i = 0; i < _polygonDataList.Count; i++)
@@ -469,67 +513,29 @@
}
///
- /// 返回指定位置的Tile是否为可以行走
+ /// 设置地面的地砖,将影响导航网格计算
///
- public bool IsWayTile(int x, int y)
+ public void SetFloorAtlasCoords(List floorAtlasCoords)
{
- return _tileRoot.GetCellTileData(DungeonTile.FloorMapLayer, new Vector2I(x, y)) != null;
- }
-
- ///
- /// 返回指定坐标下对应的Tile是否为可以行走
- ///
- public bool IsWayPosition(float x, float y)
- {
- var tileMapCellSize = _tileRoot.CellQuadrantSize;
- return IsWayTile((int)(x / tileMapCellSize), (int)(y / tileMapCellSize));
- }
-
- ///
- /// 自动生成导航区域
- ///
- private void GenerateNavigationPolygon()
- {
- var size = new Vector2(_tileRoot.CellQuadrantSize, _tileRoot.CellQuadrantSize);
-
- var rect = _tileRoot.GetUsedRect();
-
- var x = rect.Position.X;
- var y = rect.Position.Y;
- var w = rect.Size.X;
- var h = rect.Size.Y;
-
- for (int j = y; j < h; j++)
- {
- for (int i = x; i < w; i++)
- {
- if (IsWayTile(i, j))
- {
- if (!_usePoints.Contains(new Vector2(i, j)))
- {
- NavigationPolygonData polygonData = null;
-
- if (!IsWayTile(i, j - 1))
- {
- polygonData = CalcOutline(i, j, _tileRoot, size);
- }
- else if (!IsWayTile(i, j + 1))
- {
- polygonData = CalcInline(i, j, _tileRoot, size);
- }
-
- if (polygonData != null)
- {
- _polygonDataList.Add(polygonData);
- }
- }
- }
- }
- }
+ _floorAtlasCoords = floorAtlasCoords;
}
+ ///
+ /// 返回指定位置的Tile是否为可以行走
+ ///
+ private bool IsWayTile(int layer, int x, int y)
+ {
+ if (_floorAtlasCoords == null || _floorAtlasCoords.Count == 0)
+ {
+ return _tileRoot.GetCellTileData(layer, new Vector2I(x, y)) != null;
+ }
+
+ var result = _tileRoot.GetCellAtlasCoords(layer, new Vector2I(x, y));
+ return _floorAtlasCoords.Contains(result);
+ }
+
//计算导航网格外轮廓
- private NavigationPolygonData CalcOutline(int i, int j, TileMap tileMap, Vector2 size)
+ private NavigationPolygonData CalcOutline(int layer, int i, int j, Vector2 size)
{
var polygonData = new NavigationPolygonData();
polygonData.Type = NavigationPolygonType.Out;
@@ -549,7 +555,7 @@
{
case 0: //右
{
- if (IsWayTile(tempI, tempJ - 1)) //先向上找
+ if (IsWayTile(layer, tempI, tempJ - 1)) //先向上找
{
dir = 3;
@@ -565,7 +571,7 @@
tempJ--;
break;
}
- else if (IsWayTile(tempI + 1, tempJ)) //再向右找
+ else if (IsWayTile(layer, tempI + 1, tempJ)) //再向右找
{
if (points.Count == 0)
{
@@ -582,7 +588,7 @@
tempI++;
break;
}
- else if (IsWayTile(tempI, tempJ + 1)) //向下找
+ else if (IsWayTile(layer, tempI, tempJ + 1)) //向下找
{
dir = 1;
@@ -603,7 +609,7 @@
}
case 1: //下
{
- if (IsWayTile(tempI + 1, tempJ)) //先向右找
+ if (IsWayTile(layer, tempI + 1, tempJ)) //先向右找
{
dir = 0;
@@ -619,7 +625,7 @@
tempI++;
break;
}
- else if (IsWayTile(tempI, tempJ + 1)) //再向下找
+ else if (IsWayTile(layer, tempI, tempJ + 1)) //再向下找
{
if (points.Count == 0)
{
@@ -636,7 +642,7 @@
tempJ++;
break;
}
- else if (IsWayTile(tempI - 1, tempJ)) //向左找
+ else if (IsWayTile(layer, tempI - 1, tempJ)) //向左找
{
dir = 2;
@@ -657,7 +663,7 @@
}
case 2: //左
{
- if (IsWayTile(tempI, tempJ + 1)) //先向下找
+ if (IsWayTile(layer, tempI, tempJ + 1)) //先向下找
{
dir = 1;
@@ -673,7 +679,7 @@
tempJ++;
break;
}
- else if (IsWayTile(tempI - 1, tempJ)) //再向左找
+ else if (IsWayTile(layer, tempI - 1, tempJ)) //再向左找
{
if (points.Count == 0)
{
@@ -690,7 +696,7 @@
tempI--;
break;
}
- else if (IsWayTile(tempI, tempJ - 1)) //向上找
+ else if (IsWayTile(layer, tempI, tempJ - 1)) //向上找
{
dir = 3;
@@ -711,7 +717,7 @@
}
case 3: //上
{
- if (IsWayTile(tempI - 1, tempJ)) //先向左找
+ if (IsWayTile(layer, tempI - 1, tempJ)) //先向左找
{
dir = 2;
@@ -727,7 +733,7 @@
tempI--;
break;
}
- else if (IsWayTile(tempI, tempJ - 1)) //再向上找
+ else if (IsWayTile(layer, tempI, tempJ - 1)) //再向上找
{
if (points.Count == 0)
{
@@ -744,7 +750,7 @@
tempJ--;
break;
}
- else if (IsWayTile(tempI + 1, tempJ)) //向右找
+ else if (IsWayTile(layer, tempI + 1, tempJ)) //向右找
{
dir = 0;
@@ -768,7 +774,7 @@
}
//计算导航网格内轮廓
- private NavigationPolygonData CalcInline(int i, int j, TileMap tileMap, Vector2 size)
+ private NavigationPolygonData CalcInline(int layer, int i, int j, Vector2 size)
{
var polygonData = new NavigationPolygonData();
polygonData.Type = NavigationPolygonType.In;
@@ -788,7 +794,7 @@
{
case 0: //右
{
- if (IsWayTile(tempI, tempJ + 1)) //向下找
+ if (IsWayTile(layer, tempI, tempJ + 1)) //向下找
{
dir = 1;
@@ -804,7 +810,7 @@
tempJ++;
break;
}
- else if (IsWayTile(tempI + 1, tempJ)) //再向右找
+ else if (IsWayTile(layer, tempI + 1, tempJ)) //再向右找
{
if (points.Count == 0)
{
@@ -821,7 +827,7 @@
tempI++;
break;
}
- else if (IsWayTile(tempI, tempJ - 1)) //先向上找
+ else if (IsWayTile(layer, tempI, tempJ - 1)) //先向上找
{
dir = 3;
@@ -842,7 +848,7 @@
}
case 1: //下
{
- if (IsWayTile(tempI - 1, tempJ)) //向左找
+ if (IsWayTile(layer, tempI - 1, tempJ)) //向左找
{
dir = 2;
@@ -858,7 +864,7 @@
tempI--;
break;
}
- else if (IsWayTile(tempI, tempJ + 1)) //再向下找
+ else if (IsWayTile(layer, tempI, tempJ + 1)) //再向下找
{
if (points.Count == 0)
{
@@ -875,7 +881,7 @@
tempJ++;
break;
}
- else if (IsWayTile(tempI + 1, tempJ)) //先向右找
+ else if (IsWayTile(layer, tempI + 1, tempJ)) //先向右找
{
dir = 0;
@@ -896,7 +902,7 @@
}
case 2: //左
{
- if (IsWayTile(tempI, tempJ - 1)) //向上找
+ if (IsWayTile(layer, tempI, tempJ - 1)) //向上找
{
dir = 3;
@@ -912,7 +918,7 @@
tempJ--;
break;
}
- else if (IsWayTile(tempI - 1, tempJ)) //再向左找
+ else if (IsWayTile(layer, tempI - 1, tempJ)) //再向左找
{
if (points.Count == 0)
{
@@ -929,7 +935,7 @@
tempI--;
break;
}
- else if (IsWayTile(tempI, tempJ + 1)) //先向下找
+ else if (IsWayTile(layer, tempI, tempJ + 1)) //先向下找
{
dir = 1;
@@ -950,7 +956,7 @@
}
case 3: //上
{
- if (IsWayTile(tempI + 1, tempJ)) //向右找
+ if (IsWayTile(layer, tempI + 1, tempJ)) //向右找
{
dir = 0;
@@ -966,7 +972,7 @@
tempI++;
break;
}
- else if (IsWayTile(tempI, tempJ - 1)) //再向上找
+ else if (IsWayTile(layer, tempI, tempJ - 1)) //再向上找
{
if (points.Count == 0)
{
@@ -983,7 +989,7 @@
tempJ--;
break;
}
- else if (IsWayTile(tempI - 1, tempJ)) //先向左找
+ else if (IsWayTile(layer, tempI - 1, tempJ)) //先向左找
{
dir = 2;
diff --git a/DungeonShooting_Godot/src/framework/map/SerializeVector2.cs b/DungeonShooting_Godot/src/framework/map/SerializeVector2.cs
deleted file mode 100644
index f4e53c7..0000000
--- a/DungeonShooting_Godot/src/framework/map/SerializeVector2.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-
-using System.Text.Json.Serialization;
-using Godot;
-
-///
-/// 可序列化的 Vector2 对象
-///
-public class SerializeVector2
-{
- public SerializeVector2(float x, float y)
- {
- X = x;
- Y = y;
- }
-
- public SerializeVector2(Vector2 v)
- {
- X = v.X;
- Y = v.Y;
- }
-
- public SerializeVector2(Vector2I v)
- {
- X = v.X;
- Y = v.Y;
- }
-
- public SerializeVector2()
- {
-
- }
-
- [JsonInclude]
- public float X { get; private set; }
- [JsonInclude]
- public float Y { get; private set; }
-
- ///
- /// 转为 Vector2
- ///
- public Vector2 AsVector2()
- {
- return new Vector2(X, Y);
- }
-
- ///
- /// 转为 Vector2I
- ///
- public Vector2I AsVector2I()
- {
- return new Vector2I((int)X, (int)Y);
- }
-}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/room/AutoTileConfig.cs b/DungeonShooting_Godot/src/game/room/AutoTileConfig.cs
index 9e12343..fc19a71 100644
--- a/DungeonShooting_Godot/src/game/room/AutoTileConfig.cs
+++ b/DungeonShooting_Godot/src/game/room/AutoTileConfig.cs
@@ -14,7 +14,7 @@
public TileCellInfo L = new TileCellInfo(0, new Vector2I(3, 3));
public TileCellInfo T = new TileCellInfo(0, new Vector2I(2, 7));
public TileCellInfo B = new TileCellInfo(0, new Vector2I(2, 2));
- public TileCellInfo Ground = new TileCellInfo(0, new Vector2I(0, 8));
+ public TileCellInfo Floor = new TileCellInfo(0, new Vector2I(0, 8));
public TileCellInfo OUT_LT = new TileCellInfo(0, new Vector2I(1, 2));
public TileCellInfo OUT_LB = new TileCellInfo(0, new Vector2I(1, 7));
diff --git a/DungeonShooting_Godot/src/game/room/RoomManager.cs b/DungeonShooting_Godot/src/game/room/RoomManager.cs
index 70d5d3b..448f6ed 100644
--- a/DungeonShooting_Godot/src/game/room/RoomManager.cs
+++ b/DungeonShooting_Godot/src/game/room/RoomManager.cs
@@ -60,7 +60,9 @@
_dungeonTile.AutoFillRoomTile(_autoTileConfig, _generateDungeon.StartRoom);
//生成寻路网格
- _dungeonTile.GenerateNavigationPolygon(this);
+ _dungeonTile.GenerateNavigationPolygon(DungeonTile.FloorMapLayer);
+ //挂载导航区域
+ _dungeonTile.MountNavigationPolygon(this);
GD.Print("生成地牢用时: " + (DateTime.Now.Ticks - nowTicks) / 10000 + "毫秒");
//播放bgm