diff --git a/DungeonShooting_Godot/src/framework/map/fog/FogMask.cs b/DungeonShooting_Godot/src/framework/map/fog/FogMask.cs
index 61f2f87..40758cb 100644
--- a/DungeonShooting_Godot/src/framework/map/fog/FogMask.cs
+++ b/DungeonShooting_Godot/src/framework/map/fog/FogMask.cs
@@ -64,35 +64,50 @@
_inRightTopTransition = temp3.GetImage();
_inRightTopTransition.Rotate180();
}
-
+
///
- /// 初始化房间迷雾遮罩
+ /// 初始化迷雾遮罩
///
- /// 房间对象
- /// 迷雾所占区域
- public void InitRoomFog(RoomInfo roomInfo, Rect2I rect2)
+ /// 起始位置, 单位: 格
+ /// 大小, 单位: 格
+ /// 透明度
+ public void InitFog(Vector2I position, Vector2I size, float alpha = 0)
{
if (_init)
{
return;
}
InitSprite();
- GlobalPosition = rect2.Position + rect2.Size / 2;
+ GlobalPosition = new Vector2(
+ (position.X + size.X / 2f) * GameConfig.TileCellSize,
+ (position.Y + size.Y / 2f) * GameConfig.TileCellSize
+ );
//创建光纹理
- Width = rect2.Size.X;
- Height = rect2.Size.Y;
+ Width = (size.X + 2) * GameConfig.TileCellSize;
+ Height = (size.Y + 2) * GameConfig.TileCellSize;
var img = Image.Create(Width, Height, false, Image.Format.Rgba8);
img.Fill(Colors.White);
//处理边缘过渡
- HandlerTransition(roomInfo, img);
+ HandlerTransition(position, size, img);
Texture = ImageTexture.CreateFromImage(img);
+
+ var c = Color;
+ c.A = alpha;
+ Color = c;
}
- public void InitAisleFog()
+ ///
+ /// 使颜色的 alpha 通道过渡到指定的值
+ ///
+ /// 透明度值
+ /// 过渡时间
+ public void TransitionAlpha(float targetAlpha, float time)
{
-
+ var tween = CreateTween();
+ tween.TweenProperty(this, "color", new Color(1, 1, 1, targetAlpha), time);
+ tween.Play();
}
public void Destroy()
@@ -106,13 +121,13 @@
QueueFree();
}
- private void HandlerTransition(RoomInfo roomInfo, Image image)
+ private void HandlerTransition(Vector2I position, Vector2I size, 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;
+ var (x, y) = position;
+ var (width, height) = size;
x -= 1;
y -= 1;
width += 2;
diff --git a/DungeonShooting_Godot/src/framework/map/room/CrossAisleRectData.cs b/DungeonShooting_Godot/src/framework/map/room/CrossAisleRectData.cs
index f047fd8..385fc6e 100644
--- a/DungeonShooting_Godot/src/framework/map/room/CrossAisleRectData.cs
+++ b/DungeonShooting_Godot/src/framework/map/room/CrossAisleRectData.cs
@@ -9,13 +9,43 @@
///
/// 第一道门连接的过道区域
///
- public Rect2 Rect1;
+ public Rect2I Rect1;
///
/// 交叉点区域
///
- public Rect2 Cross;
+ public Rect2I Cross;
///
/// 第二道门连接的过道区域
///
- public Rect2 Rect2;
+ public Rect2I Rect2;
+
+ ///
+ /// 计算并返回过道所占矩形大小
+ ///
+ public Rect2I CalcAisleRect()
+ {
+ int x, y, w, h;
+ if (Rect1.Position.X < Rect2.Position.X)
+ {
+ x = Rect1.Position.X;
+ w = Rect2.Position.X - Rect1.Position.X + Rect2.Size.X;
+ }
+ else
+ {
+ x = Rect2.Position.X;
+ w = Rect1.Position.X - Rect2.Position.X + Rect1.Size.X;
+ }
+ if (Rect1.Position.Y < Rect2.Position.Y)
+ {
+ y = Rect1.Position.Y;
+ h = Rect2.Position.Y - Rect1.Position.Y + Rect2.Size.Y;
+ }
+ else
+ {
+ y = Rect2.Position.Y;
+ h = Rect1.Position.Y - Rect2.Position.Y + Rect1.Size.Y;
+ }
+
+ return new Rect2I(x, y, w, h);
+ }
}
\ 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 02601ba..58365e0 100644
--- a/DungeonShooting_Godot/src/framework/map/room/RoomDoorInfo.cs
+++ b/DungeonShooting_Godot/src/framework/map/room/RoomDoorInfo.cs
@@ -5,8 +5,10 @@
///
/// 房间的门
///
-public class RoomDoorInfo
+public class RoomDoorInfo : IDestroy
{
+ public bool IsDestroyed { get; private set; }
+
///
/// 所在墙面方向
///
@@ -53,6 +55,11 @@
public RoomDoor Door;
///
+ /// 过道的迷雾
+ ///
+ public FogMask FogMask;
+
+ ///
/// 世界坐标下的原点坐标, 单位: 像素
///
public Vector2I GetWorldOriginPosition()
@@ -110,14 +117,14 @@
throw new Exception("当前门连接的过道不包含交叉点, 请改用 GetAisleRect() 函数!");
}
- Rect2 rect;
- Rect2 rect2;
+ Rect2I rect;
+ Rect2I rect2;
//计算范围
switch (Direction)
{
case DoorDirection.E: //→
- rect = new Rect2(
+ rect = new Rect2I(
OriginPosition.X,
OriginPosition.Y,
Cross.X - OriginPosition.X,
@@ -125,7 +132,7 @@
);
break;
case DoorDirection.W: //←
- rect = new Rect2(
+ rect = new Rect2I(
Cross.X + GameConfig.CorridorWidth,
Cross.Y,
OriginPosition.X - (Cross.X + GameConfig.CorridorWidth),
@@ -133,7 +140,7 @@
);
break;
case DoorDirection.S: //↓
- rect = new Rect2(
+ rect = new Rect2I(
OriginPosition.X,
OriginPosition.Y,
GameConfig.CorridorWidth,
@@ -141,7 +148,7 @@
);
break;
case DoorDirection.N: //↑
- rect = new Rect2(
+ rect = new Rect2I(
Cross.X,
Cross.Y + GameConfig.CorridorWidth,
GameConfig.CorridorWidth,
@@ -149,14 +156,14 @@
);
break;
default:
- rect = new Rect2();
+ rect = new Rect2I();
break;
}
switch (ConnectDoor.Direction)
{
case DoorDirection.E: //→
- rect2 = new Rect2(
+ rect2 = new Rect2I(
ConnectDoor.OriginPosition.X,
ConnectDoor.OriginPosition.Y,
Cross.X - ConnectDoor.OriginPosition.X,
@@ -164,7 +171,7 @@
);
break;
case DoorDirection.W: //←
- rect2 = new Rect2(
+ rect2 = new Rect2I(
Cross.X + GameConfig.CorridorWidth,
Cross.Y,
ConnectDoor.OriginPosition.X -
@@ -173,7 +180,7 @@
);
break;
case DoorDirection.S: //↓
- rect2 = new Rect2(
+ rect2 = new Rect2I(
ConnectDoor.OriginPosition.X,
ConnectDoor.OriginPosition.Y,
GameConfig.CorridorWidth,
@@ -181,7 +188,7 @@
);
break;
case DoorDirection.N: //↑
- rect2 = new Rect2(
+ rect2 = new Rect2I(
Cross.X,
Cross.Y + GameConfig.CorridorWidth,
GameConfig.CorridorWidth,
@@ -190,7 +197,7 @@
);
break;
default:
- rect2 = new Rect2();
+ rect2 = new Rect2I();
break;
}
@@ -198,7 +205,21 @@
{
Rect1 = rect,
Rect2 = rect2,
- Cross = new Rect2(Cross + Vector2.One, new Vector2(GameConfig.CorridorWidth - 2, GameConfig.CorridorWidth - 2))
+ Cross = new Rect2I(Cross + Vector2I.One, new Vector2I(GameConfig.CorridorWidth - 2, GameConfig.CorridorWidth - 2))
};
}
+
+ public void Destroy()
+ {
+ if (IsDestroyed)
+ {
+ return;
+ }
+
+ IsDestroyed = true;
+ if (FogMask != null)
+ {
+ FogMask.Destroy();
+ }
+ }
}
\ 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 618abc4..5d0c04e 100644
--- a/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs
+++ b/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs
@@ -270,27 +270,39 @@
}
IsDestroyed = true;
+ //递归销毁下一个房间
foreach (var nextRoom in Next)
{
nextRoom.Destroy();
}
Next.Clear();
+
+ //销毁连接的门
+ foreach (var roomDoorInfo in Doors)
+ {
+ roomDoorInfo.Destroy();
+ }
+
+ //销毁预设
if (RoomPreinstall != null)
{
RoomPreinstall.Destroy();
RoomPreinstall = null;
}
+ //销毁画布
if (StaticImageCanvas != null)
{
StaticImageCanvas.Destroy();
}
+ //销毁迷雾
if (FogMask != null)
{
FogMask.Destroy();
}
+ //销毁所属区域对象
if (AffiliationArea != null)
{
AffiliationArea.Destroy();
@@ -317,6 +329,12 @@
return;
}
+ //清除迷雾
+ if (FogMask != null && FogMask.Color.A < 1)
+ {
+ FogMask.TransitionAlpha(1, 0.3f);
+ }
+
//房间内有敌人, 或者会刷新敌人才会关门
var hasEnemy = false;
if (AffiliationArea.ExistEnterItem(activityObject => activityObject.CollisionWithMask(PhysicsLayer.Enemy))) //先判断房间里面是否有敌人
@@ -381,6 +399,16 @@
{
doorInfo.Door.OpenDoor();
}
+
+ //清除过道的迷雾
+ foreach (var roomDoorInfo in GetForwardDoors())
+ {
+ if (roomDoorInfo.FogMask != null && roomDoorInfo.FogMask.Color.A < 1)
+ {
+ roomDoorInfo.FogMask.TransitionAlpha(1, 0.3f);
+ }
+ }
+
}
///
diff --git a/DungeonShooting_Godot/src/game/room/DungeonManager.cs b/DungeonShooting_Godot/src/game/room/DungeonManager.cs
index 3138e80..20d3ab6 100644
--- a/DungeonShooting_Godot/src/game/room/DungeonManager.cs
+++ b/DungeonShooting_Godot/src/game/room/DungeonManager.cs
@@ -197,7 +197,7 @@
World = GameApplication.Instance.CreateNewWorld();
yield return 0;
//生成地牢房间
- var random = new SeedRandom(2);
+ var random = new SeedRandom();
_dungeonGenerator = new DungeonGenerator(CurrConfig, random);
_dungeonGenerator.Generate();
yield return 0;
@@ -429,47 +429,94 @@
private void CreateRoomFogMask(RoomInfo roomInfo)
{
var roomFog = new FogMask();
- //
- //roomFog.BlendMode = Light2D.BlendModeEnum.Mix;
+ roomFog.BlendMode = Light2D.BlendModeEnum.Mix;
roomFog.Name = "FogMask" + roomFog.IsDestroyed;
- roomInfo.FogMask = roomFog;
- roomFog.InitRoomFog(roomInfo, new Rect2I(
- roomInfo.GetWorldPosition() - GameConfig.TileCellSizeVector2I,
- (roomInfo.Size + new Vector2I(2, 2)) * GameConfig.TileCellSize)
- );
+ float alpha;
+ if (roomInfo.RoomType == DungeonRoomType.Inlet) //起始房间没有迷雾
+ {
+ alpha = 1;
+ }
+ else
+ {
+ alpha = 0;
+ }
+ roomFog.InitFog(roomInfo.Position, roomInfo.Size, alpha);
+
World.FogMaskRoot.AddChild(roomFog);
+ roomInfo.FogMask = roomFog;
//正向门
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)
- // {
- // 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)
{
var calcRect = roomDoorInfo.GetAisleRect();
- calcRect.Size *= GameConfig.TileCellSize;
- calcRect.Position *= GameConfig.TileCellSize;
+ if (roomDoorInfo.Direction == DoorDirection.E || roomDoorInfo.Direction == DoorDirection.W)
+ {
+ calcRect.Position += new Vector2I(2, 0);
+ calcRect.Size -= new Vector2I(4, 0);
+ }
+ else
+ {
+ calcRect.Position += new Vector2I(0, 2);
+ calcRect.Size -= new Vector2I(0, 4);
+ }
+ var aisleFog = new FogMask();
+ aisleFog.BlendMode = Light2D.BlendModeEnum.Mix;
+ aisleFog.InitFog(calcRect.Position, calcRect.Size, alpha);
+ World.FogMaskRoot.AddChild(aisleFog);
+ roomDoorInfo.FogMask = aisleFog;
+ roomDoorInfo.ConnectDoor.FogMask = aisleFog;
+ }
+ else
+ {
+ var aisleRect = roomDoorInfo.GetCrossAisleRect();
+ var calcAisleRect = aisleRect.CalcAisleRect();
+
+ switch (roomDoorInfo.Direction)
+ {
+ case DoorDirection.E:
+ calcAisleRect.Position += new Vector2I(2, 0);
+ calcAisleRect.Size -= new Vector2I(2, 0);
+ break;
+ case DoorDirection.W:
+ calcAisleRect.Size -= new Vector2I(2, 0);
+ break;
+ case DoorDirection.S:
+ calcAisleRect.Position += new Vector2I(0, 2);
+ calcAisleRect.Size -= new Vector2I(0, 2);
+ break;
+ case DoorDirection.N:
+ calcAisleRect.Size -= new Vector2I(0, 2);
+ break;
+ }
- 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);
+ switch (roomDoorInfo.ConnectDoor.Direction)
+ {
+ case DoorDirection.E:
+ calcAisleRect.Position += new Vector2I(2, 0);
+ calcAisleRect.Size -= new Vector2I(2, 0);
+ break;
+ case DoorDirection.W:
+ calcAisleRect.Size -= new Vector2I(2, 0);
+ break;
+ case DoorDirection.S:
+ calcAisleRect.Position += new Vector2I(0, 2);
+ calcAisleRect.Size -= new Vector2I(0, 2);
+ break;
+ case DoorDirection.N:
+ calcAisleRect.Size -= new Vector2I(0, 2);
+ break;
+ }
+
+ var aisleFog = new FogMask();
+ aisleFog.BlendMode = Light2D.BlendModeEnum.Mix;
+ aisleFog.InitFog(calcAisleRect.Position, calcAisleRect.Size, alpha);
+ World.FogMaskRoot.AddChild(aisleFog);
+ roomDoorInfo.FogMask = aisleFog;
+ roomDoorInfo.ConnectDoor.FogMask = aisleFog;
}
}
}