diff --git a/DungeonShooting_Godot/src/framework/common/Utils.cs b/DungeonShooting_Godot/src/framework/common/Utils.cs
index 1b62786..7df886c 100644
--- a/DungeonShooting_Godot/src/framework/common/Utils.cs
+++ b/DungeonShooting_Godot/src/framework/common/Utils.cs
@@ -28,6 +28,17 @@
}
///
+ /// 根据两个点计算出矩形
+ ///
+ public static Rect2I CalcRect(int start1, int end1, int start2, int end2)
+ {
+ return new Rect2I(
+ Mathf.Min(start1, start2), Mathf.Min(end1, end2),
+ Mathf.Abs(start1 - start2), Mathf.Abs(end1 - end2)
+ );
+ }
+
+ ///
/// 返回碰撞层 mask 是否会检测 layer
///
public static bool CollisionMaskWithLayer(uint mask, uint layer)
diff --git a/DungeonShooting_Godot/src/framework/map/DungeonGenerator.cs b/DungeonShooting_Godot/src/framework/map/DungeonGenerator.cs
index 08beefa..ba37303 100644
--- a/DungeonShooting_Godot/src/framework/map/DungeonGenerator.cs
+++ b/DungeonShooting_Godot/src/framework/map/DungeonGenerator.cs
@@ -52,10 +52,14 @@
//房间横轴分散程度
private float _roomHorizontalMinDispersion = 0f;
private float _roomHorizontalMaxDispersion = 0.5f;
+ // private float _roomHorizontalMinDispersion = 0f;
+ // private float _roomHorizontalMaxDispersion = 2f;
//房间纵轴分散程度
private float _roomVerticalMinDispersion = 0f;
private float _roomVerticalMaxDispersion = 0.5f;
+ // private float _roomVerticalMinDispersion = 0f;
+ // private float _roomVerticalMaxDispersion = 2f;
//区域限制
private bool _enableLimitRange = true;
diff --git a/DungeonShooting_Godot/src/framework/map/DungeonTileMap.cs b/DungeonShooting_Godot/src/framework/map/DungeonTileMap.cs
index bd3aae9..d472b66 100644
--- a/DungeonShooting_Godot/src/framework/map/DungeonTileMap.cs
+++ b/DungeonShooting_Godot/src/framework/map/DungeonTileMap.cs
@@ -139,72 +139,6 @@
roomInfo.RoomPreinstall = roomPreinstall;
//执行预处理操作
roomPreinstall.Pretreatment(random);
-
- //初始化标记
- //roomInfo.RoomSplit.Preinstall.
-
- //roomInfo.RoomSplit.TileInfo.
- // var template = ResourceManager.Load(roomInfo.RoomSplit.ScenePath);
- // var tileInstance = template.Instantiate();
- //
- // //其它物体
- // var childCount = tileInstance.GetChildCount();
- // for (var i = 0; i < childCount; i++)
- // {
- // var item = tileInstance.GetChild(i);
- // if (!(item is ActivityMark))
- // {
- // item.GetParent().RemoveChild(item);
- // item.Owner = null;
- // _tileRoot.AddChild(item);
- // if (item is Node2D node)
- // {
- // node.Position = roomInfo.GetWorldPosition() + (node.GlobalPosition - offset);
- // }
- //
- // i--;
- // childCount--;
- // }
- // }
- //
- // //物体标记
- // var activityMarks = tileInstance.GetMarks();
- // foreach (var activityMark in activityMarks)
- // {
- // var pos = activityMark.Position;
- // activityMark.GetParent().RemoveChild(activityMark);
- // activityMark.Owner = null;
- // //_tileRoot.AddChild(activityMark);
- // activityMark.Position = roomInfo.GetWorldPosition() + (pos - offset);
- // activityMark.TileRoot = _tileRoot;
- // //执行预处理操作
- // activityMark.Pretreatment(random);
- // }
- // roomInfo.ActivityMarks.AddRange(activityMarks);
- //
- // //填充tile操作
- // for (int i = 0; i < rectSize.X; i++)
- // {
- // for (int j = 0; j < rectSize.Y; j++)
- // {
- // var coords = new Vector2I((int)(rectPos.X + i), (int)(rectPos.Y + j));
- // var atlasCoords = tileInstance.GetCellAtlasCoords(0, coords);
- // if (atlasCoords.X != -1 && atlasCoords.Y != -1)
- // {
- // // 在 Godot 4.0 中使用以下这段代码区分层级, 会导致游戏关闭时有概率报错卡死, 目前尚不清楚原因
- // //获取自定义层级
- // // var customData = tileInstance.GetCellSourceId(0, coords).GetCustomData(CustomTileLayerName);
- // // var layer = customData.AsInt32();
- // // layer = Mathf.Clamp(layer, GameConfig.FloorMapLayer, GameConfig.TopMapLayer);
- //
- // var layer = config.GetLayer(atlasCoords);
- // _tileRoot.SetCell(layer, new Vector2I(roomInfo.Position.X + i, roomInfo.Position.Y + j),
- // 0, atlasCoords);
- // }
- // }
- // }
- //
- // tileInstance.CallDeferred(Node.MethodName.QueueFree);
}
var doors = roomInfo.GetForwardDoors();
@@ -216,36 +150,26 @@
var doorDir2 = doorInfo.ConnectDoor.Direction;
if (!doorInfo.HasCross)
{
- var rect = Utils.CalcRect(
- doorInfo.OriginPosition.X,
- doorInfo.OriginPosition.Y,
- doorInfo.ConnectDoor.OriginPosition.X,
- doorInfo.ConnectDoor.OriginPosition.Y
- );
-
+ var rect = doorInfo.GetAisleRect();
switch (doorDir1)
{
case DoorDirection.E:
- rect.Size = new Vector2(rect.Size.X, GameConfig.CorridorWidth);
FullHorizontalAisle(config, rect);
FullHorizontalAisleLeft(config, rect, doorInfo);
FullHorizontalAisleRight(config, rect, doorInfo.ConnectDoor);
break;
case DoorDirection.W:
- rect.Size = new Vector2(rect.Size.X, GameConfig.CorridorWidth);
FullHorizontalAisle(config, rect);
FullHorizontalAisleLeft(config, rect, doorInfo.ConnectDoor);
FullHorizontalAisleRight(config, rect, doorInfo);
break;
case DoorDirection.S:
- rect.Size = new Vector2(GameConfig.CorridorWidth, rect.Size.Y);
FullVerticalAisle(config, rect);
FullVerticalAisleUp(config, rect, doorInfo);
FullVerticalAisleDown(config, rect, doorInfo.ConnectDoor);
break;
case DoorDirection.N:
- rect.Size = new Vector2(GameConfig.CorridorWidth, rect.Size.Y);
FullVerticalAisle(config, rect);
FullVerticalAisleUp(config, rect, doorInfo.ConnectDoor);
FullVerticalAisleDown(config, rect, doorInfo);
@@ -257,98 +181,43 @@
//方向, 0横向, 1纵向
var dir1 = 0;
var dir2 = 0;
-
- Rect2 rect;
- Rect2 rect2;
+
+ var aisleRect = doorInfo.GetCrossAisleRect();
+ var rect = aisleRect.Rect1;
+ var rect2 = aisleRect.Rect2;
//计算范围
switch (doorDir1)
{
case DoorDirection.E: //→
- rect = new Rect2(
- doorInfo.OriginPosition.X,
- doorInfo.OriginPosition.Y,
- doorInfo.Cross.X - doorInfo.OriginPosition.X,
- GameConfig.CorridorWidth
- );
break;
case DoorDirection.W: //←
- rect = new Rect2(
- doorInfo.Cross.X + GameConfig.CorridorWidth,
- doorInfo.Cross.Y,
- doorInfo.OriginPosition.X - (doorInfo.Cross.X + GameConfig.CorridorWidth),
- GameConfig.CorridorWidth
- );
break;
case DoorDirection.S: //↓
dir1 = 1;
- rect = new Rect2(
- doorInfo.OriginPosition.X,
- doorInfo.OriginPosition.Y,
- GameConfig.CorridorWidth,
- doorInfo.Cross.Y - doorInfo.OriginPosition.Y
- );
break;
case DoorDirection.N: //↑
dir1 = 1;
- rect = new Rect2(
- doorInfo.Cross.X,
- doorInfo.Cross.Y + GameConfig.CorridorWidth,
- GameConfig.CorridorWidth,
- doorInfo.OriginPosition.Y - (doorInfo.Cross.Y + GameConfig.CorridorWidth)
- );
- break;
- default:
- rect = new Rect2();
break;
}
switch (doorDir2)
{
case DoorDirection.E: //→
- rect2 = new Rect2(
- doorInfo.ConnectDoor.OriginPosition.X,
- doorInfo.ConnectDoor.OriginPosition.Y,
- doorInfo.Cross.X - doorInfo.ConnectDoor.OriginPosition.X,
- GameConfig.CorridorWidth
- );
break;
case DoorDirection.W: //←
- rect2 = new Rect2(
- doorInfo.Cross.X + GameConfig.CorridorWidth,
- doorInfo.Cross.Y,
- doorInfo.ConnectDoor.OriginPosition.X -
- (doorInfo.Cross.X + GameConfig.CorridorWidth),
- GameConfig.CorridorWidth
- );
break;
case DoorDirection.S: //↓
dir2 = 1;
- rect2 = new Rect2(
- doorInfo.ConnectDoor.OriginPosition.X,
- doorInfo.ConnectDoor.OriginPosition.Y,
- GameConfig.CorridorWidth,
- doorInfo.Cross.Y - doorInfo.ConnectDoor.OriginPosition.Y
- );
break;
case DoorDirection.N: //↑
dir2 = 1;
- rect2 = new Rect2(
- doorInfo.Cross.X,
- doorInfo.Cross.Y + GameConfig.CorridorWidth,
- GameConfig.CorridorWidth,
- doorInfo.ConnectDoor.OriginPosition.Y -
- (doorInfo.Cross.Y + GameConfig.CorridorWidth)
- );
- break;
- default:
- rect2 = new Rect2();
break;
}
- FillRect(GameConfig.AisleFloorMapLayer, config.Floor, doorInfo.Cross + Vector2.One,
- new Vector2(GameConfig.CorridorWidth - 2, GameConfig.CorridorWidth - 2));
-
+ //填充交叉点
+ FillRect(GameConfig.AisleFloorMapLayer, config.Floor, aisleRect.Cross.Position, aisleRect.Cross.Size);
+
//墙壁, 0横向, 1纵向
if (dir1 == 0)
{
diff --git a/DungeonShooting_Godot/src/framework/map/fog/FogMask.cs b/DungeonShooting_Godot/src/framework/map/fog/FogMask.cs
new file mode 100644
index 0000000..61f2f87
--- /dev/null
+++ b/DungeonShooting_Godot/src/framework/map/fog/FogMask.cs
@@ -0,0 +1,247 @@
+
+using Godot;
+
+///
+/// 迷雾遮罩
+///
+public partial class FogMask : PointLight2D, IDestroy
+{
+ public int Width { get; private set; }
+ public int Height { get; private set; }
+
+ public bool IsDestroyed { get; private set; }
+ private bool _init = false;
+
+ private static Image _leftTransition;
+ private static Image _rightTransition;
+ private static Image _topTransition;
+ private static Image _downTransition;
+
+ private static Image _leftTopTransition;
+ private static Image _rightTopTransition;
+ private static Image _leftDownTransition;
+ private static Image _rightDownTransition;
+
+ private static Image _inLeftTopTransition;
+ private static Image _inRightTopTransition;
+ private static Image _inLeftDownTransition;
+ private static Image _inRightDownTransition;
+
+ private static bool _initSprite = false;
+
+ private static void InitSprite()
+ {
+ if (_initSprite)
+ {
+ return;
+ }
+ _initSprite = false;
+
+ var temp = ResourceManager.Load(ResourcePath.resource_sprite_map_WallTransition1_png, false);
+ _leftTransition = temp.GetImage();
+ _rightTransition = temp.GetImage();
+ _rightTransition.Rotate180();
+ _topTransition = temp.GetImage();
+ _topTransition.Rotate90(ClockDirection.Clockwise);
+ _downTransition = temp.GetImage();
+ _downTransition.Rotate90(ClockDirection.Counterclockwise);
+
+ var temp2 = ResourceManager.Load(ResourcePath.resource_sprite_map_WallTransition2_png, false);
+ _leftDownTransition = temp2.GetImage();
+ _leftTopTransition = temp2.GetImage();
+ _leftTopTransition.Rotate90(ClockDirection.Clockwise);
+ _rightDownTransition = temp2.GetImage();
+ _rightDownTransition.Rotate90(ClockDirection.Counterclockwise);
+ _rightTopTransition = temp2.GetImage();
+ _rightTopTransition.Rotate180();
+
+ var temp3 = ResourceManager.Load(ResourcePath.resource_sprite_map_WallTransition3_png, false);
+ _inLeftDownTransition = temp3.GetImage();
+ _inLeftTopTransition = temp3.GetImage();
+ _inLeftTopTransition.Rotate90(ClockDirection.Clockwise);
+ _inRightDownTransition = temp3.GetImage();
+ _inRightDownTransition.Rotate90(ClockDirection.Counterclockwise);
+ _inRightTopTransition = temp3.GetImage();
+ _inRightTopTransition.Rotate180();
+ }
+
+ ///
+ /// 初始化房间迷雾遮罩
+ ///
+ /// 房间对象
+ /// 迷雾所占区域
+ public void InitRoomFog(RoomInfo roomInfo, Rect2I rect2)
+ {
+ if (_init)
+ {
+ return;
+ }
+ InitSprite();
+ GlobalPosition = rect2.Position + rect2.Size / 2;
+
+ //创建光纹理
+ Width = rect2.Size.X;
+ Height = rect2.Size.Y;
+ var img = Image.Create(Width, Height, false, Image.Format.Rgba8);
+ img.Fill(Colors.White);
+
+ //处理边缘过渡
+ HandlerTransition(roomInfo, img);
+ Texture = ImageTexture.CreateFromImage(img);
+ }
+
+ public void InitAisleFog()
+ {
+
+ }
+
+ public void Destroy()
+ {
+ if (IsDestroyed)
+ {
+ return;
+ }
+
+ IsDestroyed = true;
+ QueueFree();
+ }
+
+ private void HandlerTransition(RoomInfo roomInfo, Image image)
+ {
+ var tileMap = GameApplication.Instance.World.TileRoot;
+ var autoConfig = GameApplication.Instance.DungeonManager.AutoTileConfig;
+ var wallCoord = autoConfig.WALL_BLOCK.AutoTileCoord;
+ var (x, y) = roomInfo.Position;
+ var (width, height) = roomInfo.Size;
+ x -= 1;
+ y -= 1;
+ width += 2;
+ height += 2;
+ for (int i = 0; i < width; i++)
+ {
+ for (int j = 0; j < height; j++)
+ {
+ var pos = new Vector2I(i + x, j + y);
+ //说明是外层墙壁
+ if (tileMap.GetCellAtlasCoords(GameConfig.TopMapLayer, pos) == wallCoord)
+ {
+ var left = IsEmptyCell(tileMap, new Vector2I(pos.X - 1, pos.Y));
+ var right = IsEmptyCell(tileMap, new Vector2I(pos.X + 1, pos.Y));
+ var top = IsEmptyCell(tileMap, new Vector2I(pos.X, pos.Y - 1));
+ var down = IsEmptyCell(tileMap, new Vector2I(pos.X, pos.Y + 1));
+
+ var leftTop = IsEmptyCell(tileMap, new Vector2I(pos.X - 1, pos.Y - 1));
+ var leftDown = IsEmptyCell(tileMap, new Vector2I(pos.X - 1, pos.Y + 1));
+ var rightTop = IsEmptyCell(tileMap, new Vector2I(pos.X + 1, pos.Y - 1));
+ var rightDown = IsEmptyCell(tileMap, new Vector2I(pos.X + 1, pos.Y + 1));
+
+ if (!left && !right && !top && !down && !leftTop && !leftDown && !rightTop && !rightDown)
+ {
+ continue;
+ }
+ else if (leftTop && left && top) //外轮廓, 左上
+ {
+ FillTransitionImage(i, j, image, _leftTopTransition);
+ }
+ else if (leftDown && left && down) //外轮廓, 左下
+ {
+ FillTransitionImage(i, j, image, _leftDownTransition);
+ }
+ else if (rightTop && right && top) //外轮廓, 右上
+ {
+ FillTransitionImage(i, j, image, _rightTopTransition);
+ }
+ else if (rightDown && right && down) //外轮廓, 右下
+ {
+ FillTransitionImage(i, j, image, _rightDownTransition);
+ }
+ //-------------------------
+ else if (left) //左
+ {
+ FillTransitionImage(i, j, image, _leftTransition);
+ }
+ else if (right) //右
+ {
+ FillTransitionImage(i, j, image, _rightTransition);
+ }
+ else if (top) //上
+ {
+ FillTransitionImage(i, j, image, _topTransition);
+ }
+ else if (down) //下
+ {
+ FillTransitionImage(i, j, image, _downTransition);
+ }
+ //--------------------------
+ else if (leftTop) //内轮廓, 左上
+ {
+ FillTransitionImage(i, j, image, _inLeftTopTransition);
+ }
+ else if (leftDown) //内轮廓, 左下
+ {
+ FillTransitionImage(i, j, image, _inLeftDownTransition);
+ }
+ else if (rightTop) //内轮廓, 右上
+ {
+ FillTransitionImage(i, j, image, _inRightTopTransition);
+ }
+ else if (rightDown) //内轮廓, 右下
+ {
+ FillTransitionImage(i, j, image, _inRightDownTransition);
+ }
+ //------------------------
+ else //全黑
+ {
+ FillBlock(i, j, image);
+ }
+ }
+ }
+ }
+ }
+
+ //填充一个16*16像素的区域
+ private void FillBlock(int x, int y, Image image)
+ {
+ var endX = (x + 1) * GameConfig.TileCellSize;
+ var endY = (y + 1) * GameConfig.TileCellSize;
+ for (int i = x * GameConfig.TileCellSize; i < endX; i++)
+ {
+ for (int j = y * GameConfig.TileCellSize; j < endY; j++)
+ {
+ image.SetPixel(i, j, new Color(1, 1, 1, 0));
+ }
+ }
+ }
+
+ private void FillTransitionImage(int x, int y, Image image, Image transitionImage)
+ {
+ image.BlitRect(transitionImage,
+ new Rect2I(Vector2I.Zero, 16, 16),
+ new Vector2I(x * GameConfig.TileCellSize, y * GameConfig.TileCellSize)
+ );
+ }
+
+ private bool IsEmptyCell(TileMap tileMap, Vector2I pos)
+ {
+ return tileMap.GetCellSourceId(GameConfig.TopMapLayer, pos) == -1 &&
+ tileMap.GetCellSourceId(GameConfig.MiddleMapLayer, pos) == -1;
+ }
+
+ //判断是否是墙壁
+ private bool IsNotWallCell(TileMap tileMap, Vector2I pos, Vector2I wallCoord)
+ {
+ return tileMap.GetCellAtlasCoords(GameConfig.TopMapLayer, pos) != wallCoord &&
+ tileMap.GetCellAtlasCoords(GameConfig.MiddleMapLayer, pos) != wallCoord &&
+ (tileMap.GetCellSourceId(GameConfig.TopMapLayer, pos) != -1 ||
+ tileMap.GetCellSourceId(GameConfig.MiddleMapLayer, pos) != -1);
+ }
+
+ //判断是否是任意类型的图块
+ private bool IsAnyCell(TileMap tileMap, Vector2I pos)
+ {
+ return tileMap.GetCellSourceId(GameConfig.FloorMapLayer, pos) != -1 ||
+ tileMap.GetCellSourceId(GameConfig.MiddleMapLayer, pos) != -1 ||
+ tileMap.GetCellSourceId(GameConfig.TopMapLayer, pos) != -1 ||
+ tileMap.GetCellSourceId(GameConfig.AisleFloorMapLayer, pos) != -1;
+ }
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/framework/map/fog/RoomFogMask.cs b/DungeonShooting_Godot/src/framework/map/fog/RoomFogMask.cs
deleted file mode 100644
index 37e02e3..0000000
--- a/DungeonShooting_Godot/src/framework/map/fog/RoomFogMask.cs
+++ /dev/null
@@ -1,242 +0,0 @@
-
-using Godot;
-
-///
-/// 迷雾遮罩
-///
-public partial class RoomFogMask : PointLight2D, IDestroy
-{
- public int Width { get; private set; }
- public int Height { get; private set; }
-
- public bool IsDestroyed { get; private set; }
- private bool _init = false;
-
- private static Image _leftTransition;
- private static Image _rightTransition;
- private static Image _topTransition;
- private static Image _downTransition;
-
- private static Image _leftTopTransition;
- private static Image _rightTopTransition;
- private static Image _leftDownTransition;
- private static Image _rightDownTransition;
-
- private static Image _inLeftTopTransition;
- private static Image _inRightTopTransition;
- private static Image _inLeftDownTransition;
- private static Image _inRightDownTransition;
-
- private static bool _initSprite = false;
-
- private static void InitSprite()
- {
- if (_initSprite)
- {
- return;
- }
- _initSprite = false;
-
- var temp = ResourceManager.Load(ResourcePath.resource_sprite_map_WallTransition1_png, false);
- _leftTransition = temp.GetImage();
- _rightTransition = temp.GetImage();
- _rightTransition.Rotate180();
- _topTransition = temp.GetImage();
- _topTransition.Rotate90(ClockDirection.Clockwise);
- _downTransition = temp.GetImage();
- _downTransition.Rotate90(ClockDirection.Counterclockwise);
-
- var temp2 = ResourceManager.Load(ResourcePath.resource_sprite_map_WallTransition2_png, false);
- _leftDownTransition = temp2.GetImage();
- _leftTopTransition = temp2.GetImage();
- _leftTopTransition.Rotate90(ClockDirection.Clockwise);
- _rightDownTransition = temp2.GetImage();
- _rightDownTransition.Rotate90(ClockDirection.Counterclockwise);
- _rightTopTransition = temp2.GetImage();
- _rightTopTransition.Rotate180();
-
- var temp3 = ResourceManager.Load(ResourcePath.resource_sprite_map_WallTransition3_png, false);
- _inLeftDownTransition = temp3.GetImage();
- _inLeftTopTransition = temp3.GetImage();
- _inLeftTopTransition.Rotate90(ClockDirection.Clockwise);
- _inRightDownTransition = temp3.GetImage();
- _inRightDownTransition.Rotate90(ClockDirection.Counterclockwise);
- _inRightTopTransition = temp3.GetImage();
- _inRightTopTransition.Rotate180();
- }
-
- ///
- /// 初始化贩房间迷雾遮罩
- ///
- /// 房间对象
- /// 迷雾所占区域
- public void Init(RoomInfo roomInfo, Rect2I rect2)
- {
- if (_init)
- {
- return;
- }
- InitSprite();
- GlobalPosition = rect2.Position + rect2.Size / 2;
-
- //创建光纹理
- Width = rect2.Size.X;
- Height = rect2.Size.Y;
- var img = Image.Create(Width, Height, false, Image.Format.Rgba8);
- img.Fill(Colors.White);
-
- //处理边缘过渡
- HandlerTransition(roomInfo, img);
- Texture = ImageTexture.CreateFromImage(img);
- }
-
- public void Destroy()
- {
- if (IsDestroyed)
- {
- return;
- }
-
- IsDestroyed = true;
- QueueFree();
- }
-
- private void HandlerTransition(RoomInfo roomInfo, Image image)
- {
- var tileMap = GameApplication.Instance.World.TileRoot;
- var autoConfig = GameApplication.Instance.DungeonManager.AutoTileConfig;
- var wallCoord = autoConfig.WALL_BLOCK.AutoTileCoord;
- var (x, y) = roomInfo.Position;
- var (width, height) = roomInfo.Size;
- x -= 1;
- y -= 1;
- width += 2;
- height += 2;
- for (int i = 0; i < width; i++)
- {
- for (int j = 0; j < height; j++)
- {
- var pos = new Vector2I(i + x, j + y);
- //说明是外层墙壁
- if (tileMap.GetCellAtlasCoords(GameConfig.TopMapLayer, pos) == wallCoord)
- {
- var left = IsEmptyCell(tileMap, new Vector2I(pos.X - 1, pos.Y));
- var right = IsEmptyCell(tileMap, new Vector2I(pos.X + 1, pos.Y));
- var top = IsEmptyCell(tileMap, new Vector2I(pos.X, pos.Y - 1));
- var down = IsEmptyCell(tileMap, new Vector2I(pos.X, pos.Y + 1));
-
- var leftTop = IsEmptyCell(tileMap, new Vector2I(pos.X - 1, pos.Y - 1));
- var leftDown = IsEmptyCell(tileMap, new Vector2I(pos.X - 1, pos.Y + 1));
- var rightTop = IsEmptyCell(tileMap, new Vector2I(pos.X + 1, pos.Y - 1));
- var rightDown = IsEmptyCell(tileMap, new Vector2I(pos.X + 1, pos.Y + 1));
-
- if (!left && !right && !top && !down && !leftTop && !leftDown && !rightTop && !rightDown)
- {
- continue;
- }
- else if (leftTop && left && top) //外轮廓, 左上
- {
- FillTransitionImage(i, j, image, _leftTopTransition);
- }
- else if (leftDown && left && down) //外轮廓, 左下
- {
- FillTransitionImage(i, j, image, _leftDownTransition);
- }
- else if (rightTop && right && top) //外轮廓, 右上
- {
- FillTransitionImage(i, j, image, _rightTopTransition);
- }
- else if (rightDown && right && down) //外轮廓, 右下
- {
- FillTransitionImage(i, j, image, _rightDownTransition);
- }
- //-------------------------
- else if (left) //左
- {
- FillTransitionImage(i, j, image, _leftTransition);
- }
- else if (right) //右
- {
- FillTransitionImage(i, j, image, _rightTransition);
- }
- else if (top) //上
- {
- FillTransitionImage(i, j, image, _topTransition);
- }
- else if (down) //下
- {
- FillTransitionImage(i, j, image, _downTransition);
- }
- //--------------------------
- else if (leftTop) //内轮廓, 左上
- {
- FillTransitionImage(i, j, image, _inLeftTopTransition);
- }
- else if (leftDown) //内轮廓, 左下
- {
- FillTransitionImage(i, j, image, _inLeftDownTransition);
- }
- else if (rightTop) //内轮廓, 右上
- {
- FillTransitionImage(i, j, image, _inRightTopTransition);
- }
- else if (rightDown) //内轮廓, 右下
- {
- FillTransitionImage(i, j, image, _inRightDownTransition);
- }
- //------------------------
- else //全黑
- {
- FillBlock(i, j, image);
- }
- }
- }
- }
- }
-
- //填充一个16*16像素的区域
- private void FillBlock(int x, int y, Image image)
- {
- var endX = (x + 1) * GameConfig.TileCellSize;
- var endY = (y + 1) * GameConfig.TileCellSize;
- for (int i = x * GameConfig.TileCellSize; i < endX; i++)
- {
- for (int j = y * GameConfig.TileCellSize; j < endY; j++)
- {
- image.SetPixel(i, j, new Color(1, 1, 1, 0));
- }
- }
- }
-
- private void FillTransitionImage(int x, int y, Image image, Image transitionImage)
- {
- image.BlitRect(transitionImage,
- new Rect2I(Vector2I.Zero, 16, 16),
- new Vector2I(x * GameConfig.TileCellSize, y * GameConfig.TileCellSize)
- );
- }
-
- private bool IsEmptyCell(TileMap tileMap, Vector2I pos)
- {
- return tileMap.GetCellSourceId(GameConfig.TopMapLayer, pos) == -1 &&
- tileMap.GetCellSourceId(GameConfig.MiddleMapLayer, pos) == -1;
- }
-
- //判断是否是墙壁
- private bool IsNotWallCell(TileMap tileMap, Vector2I pos, Vector2I wallCoord)
- {
- return tileMap.GetCellAtlasCoords(GameConfig.TopMapLayer, pos) != wallCoord &&
- tileMap.GetCellAtlasCoords(GameConfig.MiddleMapLayer, pos) != wallCoord &&
- (tileMap.GetCellSourceId(GameConfig.TopMapLayer, pos) != -1 ||
- tileMap.GetCellSourceId(GameConfig.MiddleMapLayer, pos) != -1);
- }
-
- //判断是否是任意类型的图块
- private bool IsAnyCell(TileMap tileMap, Vector2I pos)
- {
- return tileMap.GetCellSourceId(GameConfig.FloorMapLayer, pos) != -1 ||
- tileMap.GetCellSourceId(GameConfig.MiddleMapLayer, pos) != -1 ||
- tileMap.GetCellSourceId(GameConfig.TopMapLayer, pos) != -1 ||
- tileMap.GetCellSourceId(GameConfig.AisleFloorMapLayer, pos) != -1;
- }
-}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/framework/map/room/CrossAisleRectData.cs b/DungeonShooting_Godot/src/framework/map/room/CrossAisleRectData.cs
new file mode 100644
index 0000000..f047fd8
--- /dev/null
+++ b/DungeonShooting_Godot/src/framework/map/room/CrossAisleRectData.cs
@@ -0,0 +1,21 @@
+
+using Godot;
+
+///
+/// 交叉过道数据
+///
+public class CrossAisleRectData
+{
+ ///
+ /// 第一道门连接的过道区域
+ ///
+ public Rect2 Rect1;
+ ///
+ /// 交叉点区域
+ ///
+ public Rect2 Cross;
+ ///
+ /// 第二道门连接的过道区域
+ ///
+ public Rect2 Rect2;
+}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/framework/map/room/RoomDoorInfo.cs b/DungeonShooting_Godot/src/framework/map/room/RoomDoorInfo.cs
index 6e029fa..02601ba 100644
--- a/DungeonShooting_Godot/src/framework/map/room/RoomDoorInfo.cs
+++ b/DungeonShooting_Godot/src/framework/map/room/RoomDoorInfo.cs
@@ -1,4 +1,5 @@
+using System;
using Godot;
///
@@ -61,4 +62,143 @@
OriginPosition.Y * GameConfig.TileCellSize
);
}
+
+ ///
+ /// 获取直连门过道区域数据, 单位: 格, 如果当前门连接区域带交叉点, 则报错
+ ///
+ public Rect2I GetAisleRect()
+ {
+ if (HasCross)
+ {
+ throw new Exception("当前门连接的过道包含交叉点, 请改用 GetCrossAisleRect() 函数!");
+ }
+
+ var rect = Utils.CalcRect(
+ OriginPosition.X,
+ OriginPosition.Y,
+ ConnectDoor.OriginPosition.X,
+ ConnectDoor.OriginPosition.Y
+ );
+
+ switch (Direction)
+ {
+ case DoorDirection.E:
+ rect.Size = new Vector2I(rect.Size.X, GameConfig.CorridorWidth);
+ break;
+ case DoorDirection.W:
+ rect.Size = new Vector2I(rect.Size.X, GameConfig.CorridorWidth);
+ break;
+
+ case DoorDirection.S:
+ rect.Size = new Vector2I(GameConfig.CorridorWidth, rect.Size.Y);
+ break;
+ case DoorDirection.N:
+ rect.Size = new Vector2I(GameConfig.CorridorWidth, rect.Size.Y);
+ break;
+ }
+
+ return rect;
+ }
+
+ ///
+ /// 获取交叉门过道区域数据, 单位: 格, 如果当前门连接区域不带交叉点, 则报错
+ ///
+ public CrossAisleRectData GetCrossAisleRect()
+ {
+ if (!HasCross)
+ {
+ throw new Exception("当前门连接的过道不包含交叉点, 请改用 GetAisleRect() 函数!");
+ }
+
+ Rect2 rect;
+ Rect2 rect2;
+
+ //计算范围
+ switch (Direction)
+ {
+ case DoorDirection.E: //→
+ rect = new Rect2(
+ OriginPosition.X,
+ OriginPosition.Y,
+ Cross.X - OriginPosition.X,
+ GameConfig.CorridorWidth
+ );
+ break;
+ case DoorDirection.W: //←
+ rect = new Rect2(
+ Cross.X + GameConfig.CorridorWidth,
+ Cross.Y,
+ OriginPosition.X - (Cross.X + GameConfig.CorridorWidth),
+ GameConfig.CorridorWidth
+ );
+ break;
+ case DoorDirection.S: //↓
+ rect = new Rect2(
+ OriginPosition.X,
+ OriginPosition.Y,
+ GameConfig.CorridorWidth,
+ Cross.Y - OriginPosition.Y
+ );
+ break;
+ case DoorDirection.N: //↑
+ rect = new Rect2(
+ Cross.X,
+ Cross.Y + GameConfig.CorridorWidth,
+ GameConfig.CorridorWidth,
+ OriginPosition.Y - (Cross.Y + GameConfig.CorridorWidth)
+ );
+ break;
+ default:
+ rect = new Rect2();
+ break;
+ }
+
+ switch (ConnectDoor.Direction)
+ {
+ case DoorDirection.E: //→
+ rect2 = new Rect2(
+ ConnectDoor.OriginPosition.X,
+ ConnectDoor.OriginPosition.Y,
+ Cross.X - ConnectDoor.OriginPosition.X,
+ GameConfig.CorridorWidth
+ );
+ break;
+ case DoorDirection.W: //←
+ rect2 = new Rect2(
+ Cross.X + GameConfig.CorridorWidth,
+ Cross.Y,
+ ConnectDoor.OriginPosition.X -
+ (Cross.X + GameConfig.CorridorWidth),
+ GameConfig.CorridorWidth
+ );
+ break;
+ case DoorDirection.S: //↓
+ rect2 = new Rect2(
+ ConnectDoor.OriginPosition.X,
+ ConnectDoor.OriginPosition.Y,
+ GameConfig.CorridorWidth,
+ Cross.Y - ConnectDoor.OriginPosition.Y
+ );
+ break;
+ case DoorDirection.N: //↑
+ rect2 = new Rect2(
+ Cross.X,
+ Cross.Y + GameConfig.CorridorWidth,
+ GameConfig.CorridorWidth,
+ ConnectDoor.OriginPosition.Y -
+ (Cross.Y + GameConfig.CorridorWidth)
+ );
+ break;
+ default:
+ rect2 = new Rect2();
+ break;
+ }
+
+ return new CrossAisleRectData()
+ {
+ Rect1 = rect,
+ Rect2 = rect2,
+ Cross = new Rect2(Cross + Vector2.One, new Vector2(GameConfig.CorridorWidth - 2, GameConfig.CorridorWidth - 2))
+ };
+ }
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs b/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs
index e5753d0..618abc4 100644
--- a/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs
+++ b/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs
@@ -82,7 +82,7 @@
///
/// 房间迷雾
///
- public RoomFogMask RoomFogMask;
+ public FogMask FogMask;
///
/// 房间算上连接通道所占用的区域
@@ -286,9 +286,9 @@
StaticImageCanvas.Destroy();
}
- if (RoomFogMask != null)
+ if (FogMask != null)
{
- RoomFogMask.Destroy();
+ FogMask.Destroy();
}
if (AffiliationArea != null)
diff --git a/DungeonShooting_Godot/src/game/GameConfig.cs b/DungeonShooting_Godot/src/game/GameConfig.cs
index e6e1cd2..756b76b 100644
--- a/DungeonShooting_Godot/src/game/GameConfig.cs
+++ b/DungeonShooting_Godot/src/game/GameConfig.cs
@@ -22,7 +22,7 @@
///
public const int CorridorWidth = 4;
///
- /// 游戏地图网格大小
+ /// 游戏地图网格大小, 值为 16
///
public const int TileCellSize = 16;
///
diff --git a/DungeonShooting_Godot/src/game/room/DungeonManager.cs b/DungeonShooting_Godot/src/game/room/DungeonManager.cs
index f5c1d78..3138e80 100644
--- a/DungeonShooting_Godot/src/game/room/DungeonManager.cs
+++ b/DungeonShooting_Godot/src/game/room/DungeonManager.cs
@@ -428,12 +428,12 @@
//创建迷雾遮罩
private void CreateRoomFogMask(RoomInfo roomInfo)
{
- var roomFog = new RoomFogMask();
+ var roomFog = new FogMask();
//
- roomFog.BlendMode = Light2D.BlendModeEnum.Mix;
+ //roomFog.BlendMode = Light2D.BlendModeEnum.Mix;
roomFog.Name = "FogMask" + roomFog.IsDestroyed;
- roomInfo.RoomFogMask = roomFog;
- roomFog.Init(roomInfo, new Rect2I(
+ roomInfo.FogMask = roomFog;
+ roomFog.InitRoomFog(roomInfo, new Rect2I(
roomInfo.GetWorldPosition() - GameConfig.TileCellSizeVector2I,
(roomInfo.Size + new Vector2I(2, 2)) * GameConfig.TileCellSize)
);
@@ -441,29 +441,36 @@
//正向门
var roomDoorInfos = roomInfo.GetForwardDoors();
+ //生成通道迷雾
foreach (var roomDoorInfo in roomDoorInfos)
{
- var p1 = roomDoorInfo.GetWorldOriginPosition();
- var p2 = roomDoorInfo.ConnectDoor.GetWorldOriginPosition();
- var calcRect = Utils.CalcRect(p1.X, p1.Y, p2.X, p2.Y);
- if (calcRect.Size.X == 0)
+ // var p1 = roomDoorInfo.GetWorldOriginPosition();
+ // var p2 = roomDoorInfo.ConnectDoor.GetWorldOriginPosition();
+ // var calcRect = Utils.CalcRect(p1.X, p1.Y, p2.X, p2.Y);
+ // if (calcRect.Size.X == 0)
+ // {
+ // calcRect.Size += new Vector2I(4 * GameConfig.TileCellSize, 0);
+ // }
+ // else if (calcRect.Size.Y == 0)
+ // {
+ // calcRect.Size += new Vector2I(0, 4 * GameConfig.TileCellSize);
+ // }
+ if (!roomDoorInfo.HasCross)
{
- calcRect.Size += new Vector2(4 * GameConfig.TileCellSize, 0);
+ var calcRect = roomDoorInfo.GetAisleRect();
+ calcRect.Size *= GameConfig.TileCellSize;
+ calcRect.Position *= GameConfig.TileCellSize;
+
+ var calcRectSize = calcRect.Size;
+ var image = Image.Create(calcRectSize.X, calcRectSize.Y, false, Image.Format.Rgba8);
+ image.Fill(Colors.White);
+ var sprite2D = new FogMask();
+ //
+ //sprite2D.BlendMode = Light2D.BlendModeEnum.Mix;
+ sprite2D.Texture = ImageTexture.CreateFromImage(image);
+ sprite2D.Position = calcRect.Position + calcRect.Size / 2;
+ World.FogMaskRoot.AddChild(sprite2D);
}
- else if (calcRect.Size.Y == 0)
- {
- calcRect.Size += new Vector2(0, 4 * GameConfig.TileCellSize);
- }
-
- var calcRectSize = calcRect.Size.AsVector2I();
- var image = Image.Create(calcRectSize.X, calcRectSize.Y, false, Image.Format.Rgba8);
- image.Fill(Colors.White);
- var sprite2D = new PointLight2D();
- //
- sprite2D.BlendMode = Light2D.BlendModeEnum.Mix;
- sprite2D.Texture = ImageTexture.CreateFromImage(image);
- sprite2D.Position = calcRect.Position + calcRect.Size / 2;
- World.FogMaskRoot.AddChild(sprite2D);
}
}