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); } }