diff --git a/DungeonShooting_Godot/prefab/ui/RoomUI.tscn b/DungeonShooting_Godot/prefab/ui/RoomUI.tscn index 6718a80..a16d493 100644 --- a/DungeonShooting_Godot/prefab/ui/RoomUI.tscn +++ b/DungeonShooting_Godot/prefab/ui/RoomUI.tscn @@ -328,3 +328,14 @@ [node name="RoomMap" parent="." instance=ExtResource("16_rp3sg")] layout_mode = 1 metadata/_edit_lock_ = true + +[node name="Mask" type="ColorRect" parent="."] +visible = false +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +color = Color(0, 0, 0, 1) diff --git a/DungeonShooting_Godot/src/framework/map/DungeonTileMap.cs b/DungeonShooting_Godot/src/framework/map/DungeonTileMap.cs index f283ca9..643a556 100644 --- a/DungeonShooting_Godot/src/framework/map/DungeonTileMap.cs +++ b/DungeonShooting_Godot/src/framework/map/DungeonTileMap.cs @@ -143,6 +143,19 @@ _tileRoot.SetCell(GameConfig.TopMapLayer, pos, sourceId, new Vector2I(atlasCoordsX, atlasCoordsY)); } + //寻找可用传送点 + var maxCount = (roomInfo.Size.X - 2) * (roomInfo.Size.Y - 2); + var startPosition = roomInfo.Position + roomInfo.Size / 2; + for (int i = 0; i < maxCount; i++) + { + var pos = SpiralUtil.Screw(i) + startPosition; + if (IsWayTile(GameConfig.FloorMapLayer, pos.X, pos.Y)) + { + roomInfo.Waypoints = pos; + break; + } + } + //---------------------- 随机选择预设 ---------------------- RoomPreinstallInfo preinstallInfo; if (EditorPlayManager.IsPlay && roomInfo.RoomType == GameApplication.Instance.DungeonManager.CurrConfig.DesignatedType) //编辑器模式, 指定预设 diff --git a/DungeonShooting_Godot/src/framework/map/room/RoomDoorInfo.cs b/DungeonShooting_Godot/src/framework/map/room/RoomDoorInfo.cs index 36fa126..a420fe5 100644 --- a/DungeonShooting_Godot/src/framework/map/room/RoomDoorInfo.cs +++ b/DungeonShooting_Godot/src/framework/map/room/RoomDoorInfo.cs @@ -55,7 +55,7 @@ public DoorNavigationInfo Navigation; /// - /// 连接过道使用的导航网格 + /// 连接过道使用的导航网格 (暂未用到) /// public NavigationPolygonData AisleNavigation; diff --git a/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs b/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs index 3324738..f1269ca 100644 --- a/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs +++ b/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs @@ -129,6 +129,11 @@ /// 房间预览图, 用于小地图 /// public TextureRect PreviewSprite { get; set; } + + /// + /// 房间内的传送点, 单位: 格 + /// + public Vector2I Waypoints { get; set; } public bool IsDestroyed { get; private set; } diff --git a/DungeonShooting_Godot/src/game/GameConfig.cs b/DungeonShooting_Godot/src/game/GameConfig.cs index 932ab28..c116698 100644 --- a/DungeonShooting_Godot/src/game/GameConfig.cs +++ b/DungeonShooting_Godot/src/game/GameConfig.cs @@ -52,7 +52,7 @@ public const string UiCodeDir = "src/game/ui/"; /// - /// TileMap 底板的层级 + /// TileMap 地板的层级 /// public const int FloorMapLayer = 0; /// diff --git a/DungeonShooting_Godot/src/game/room/DungeonManager.cs b/DungeonShooting_Godot/src/game/room/DungeonManager.cs index 8565c8a..dc809fc 100644 --- a/DungeonShooting_Godot/src/game/room/DungeonManager.cs +++ b/DungeonShooting_Godot/src/game/room/DungeonManager.cs @@ -216,8 +216,8 @@ _dungeonTileMap.GenerateNavigationPolygon(GameConfig.AisleFloorMapLayer); yield return 0; //将导航网格绑定到 DoorInfo 上 - BindAisleNavigation(StartRoomInfo, _dungeonTileMap.GetPolygonData()); - yield return 0; + //BindAisleNavigation(StartRoomInfo, _dungeonTileMap.GetPolygonData()); + //yield return 0; //挂载过道导航区域 _dungeonTileMap.MountNavigationPolygon(World.TileRoot); yield return 0; @@ -331,7 +331,7 @@ } } - Debug.Log(roomInfo.Id + ", 是否找到连接过道: " + flag); + //Debug.Log(roomInfo.Id + ", 是否找到连接过道: " + flag); } } } @@ -790,16 +790,10 @@ //绘制ai寻路区域 Utils.DrawNavigationPolygon(this, _roomStaticNavigationList.ToArray()); } - StartRoomInfo?.EachRoom(info => - { - foreach (var roomDoorInfo in info.Doors) - { - if (roomDoorInfo.IsForward) - { - DrawLine(roomDoorInfo.GetWorldOriginPosition(), roomDoorInfo.AisleNavigation.GetPoints()[0], Colors.Red, 2f); - } - } - }); + // StartRoomInfo?.EachRoom(info => + // { + // DrawRect(new Rect2(info.Waypoints * GameConfig.TileCellSize, new Vector2(16, 16)), Colors.Red); + // }); //绘制房间区域 // if (_dungeonGenerator != null) // { diff --git a/DungeonShooting_Godot/src/game/ui/roomMap/RoomMapPanel.cs b/DungeonShooting_Godot/src/game/ui/roomMap/RoomMapPanel.cs index b5dfb9b..8ee5992 100644 --- a/DungeonShooting_Godot/src/game/ui/roomMap/RoomMapPanel.cs +++ b/DungeonShooting_Godot/src/game/ui/roomMap/RoomMapPanel.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -using System.Linq; using Godot; +using UI.RoomUI; namespace UI.RoomMap; @@ -25,6 +25,8 @@ //放大地图后鼠标悬停的房间 private RoomInfo _mouseHoverRoom; private Color _originOutlineColor; + private bool _pressMapFlag = false; + private Tween _transmissionTween; public override void OnCreateUi() { @@ -47,29 +49,41 @@ { _dragBinder.UnBind(); } + + if (_transmissionTween != null) + { + _transmissionTween.Dispose(); + } } public override void Process(float delta) { - //按下地图按键 - if (InputManager.Map && !_isMagnifyMap) + if (_transmissionTween == null) //不在传送过程中 { - if (UiManager.GetUiInstanceCount(UiManager.UiName.PauseMenu) == 0) + if (!InputManager.Map) { - World.Current.Pause = true; - _isMagnifyMap = true; - MagnifyMap(); + _pressMapFlag = false; } - } - else if (!InputManager.Map && _isMagnifyMap) - { - ResetMap(); - _isMagnifyMap = false; - World.Current.Pause = false; + //按下地图按键 + if (InputManager.Map && !_isMagnifyMap && !_pressMapFlag) + { + if (UiManager.GetUiInstanceCount(UiManager.UiName.PauseMenu) == 0) + { + World.Current.Pause = true; + _pressMapFlag = true; + _isMagnifyMap = true; + MagnifyMap(); + } + } + else if (!InputManager.Map && _isMagnifyMap) + { + ResetMap(); + _isMagnifyMap = false; + World.Current.Pause = false; + } } //更新敌人位置 - if (World.Current != null) { var enemyList = World.Current.Enemy_InstanceList; if (enemyList.Count == 0) //没有敌人 @@ -147,6 +161,18 @@ S_Root.Instance.Position = CalcRootPosition(Player.Current.Position) + _mapOffset; S_Mark.Instance.Position = S_DrawContainer.Instance.Size / 2 + _mapOffset; } + + //传送 + if (_pressMapFlag && _mouseHoverRoom != null && + !Player.Current.AffiliationArea.RoomInfo.IsSeclusion && + Input.IsMouseButtonPressed(MouseButton.Right)) + { + //执行传送操作 + DoTransmission(_mouseHoverRoom.Waypoints * GameConfig.TileCellSize); + ResetMap(); + _isMagnifyMap = false; + World.Current.Pause = false; + } } private void OnDrawContainerResized() @@ -216,7 +242,16 @@ _mouseHoverRoom = roomInfo; var shaderMaterial = (ShaderMaterial)roomInfo.PreviewSprite.Material; _originOutlineColor = shaderMaterial.GetShaderParameter("outline_color").AsColor(); - shaderMaterial.SetShaderParameter("outline_color", new Color(0, 1, 0, 0.9f)); + //玩家所在的房间门是否打开 + var isOpen = !Player.Current.AffiliationArea.RoomInfo.IsSeclusion; + if (isOpen) + { + shaderMaterial.SetShaderParameter("outline_color", new Color(0, 1, 0, 0.9f)); + } + else + { + shaderMaterial.SetShaderParameter("outline_color", new Color(1, 0, 0, 0.9f)); + } }; roomInfo.PreviewSprite.MouseExited += ResetOutlineColor; @@ -326,5 +361,24 @@ { return S_DrawContainer.Instance.Size / 2 - pos / 16 * S_Root.Instance.Scale; } - + + private void DoTransmission(Vector2 position) + { + var roomUI = (RoomUIPanel)ParentUi; + roomUI.S_Mask.Instance.Visible = true; + roomUI.S_Mask.Instance.Color = new Color(0, 0, 0, 0); + _transmissionTween = CreateTween(); + _transmissionTween.TweenProperty(roomUI.S_Mask.Instance, "color", new Color(0, 0, 0), 0.3f); + _transmissionTween.TweenCallback(Callable.From(() => + { + Player.Current.Position = position; + })); + _transmissionTween.TweenInterval(0.2f); + _transmissionTween.TweenProperty(roomUI.S_Mask.Instance, "color", new Color(0, 0, 0, 0), 0.3f); + _transmissionTween.TweenCallback(Callable.From(() => + { + _transmissionTween = null; + })); + _transmissionTween.Play(); + } } diff --git a/DungeonShooting_Godot/src/game/ui/roomUI/RoomUI.cs b/DungeonShooting_Godot/src/game/ui/roomUI/RoomUI.cs index 1f8e5af..64f9203 100644 --- a/DungeonShooting_Godot/src/game/ui/roomUI/RoomUI.cs +++ b/DungeonShooting_Godot/src/game/ui/roomUI/RoomUI.cs @@ -57,6 +57,19 @@ } private RoomMap _L_RoomMap; + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: RoomUI.Mask + /// + public Mask L_Mask + { + get + { + if (_L_Mask == null) _L_Mask = new Mask((RoomUIPanel)this, GetNode("Mask")); + return _L_Mask; + } + } + private Mask _L_Mask; + public RoomUI() : base(nameof(RoomUI)) { @@ -555,6 +568,15 @@ } } + /// + /// 类型: , 路径: RoomUI.Mask + /// + public class Mask : UiNode + { + public Mask(RoomUIPanel uiPanel, Godot.ColorRect node) : base(uiPanel, node) { } + public override Mask Clone() => new (UiPanel, (Godot.ColorRect)Instance.Duplicate()); + } + /// /// 场景中唯一名称的节点, 节点类型: , 节点路径: RoomUI.InteractiveTipBar.Icon @@ -676,4 +698,9 @@ /// public RoomMap S_RoomMap => L_RoomMap; + /// + /// 场景中唯一名称的节点, 节点类型: , 节点路径: RoomUI.Mask + /// + public Mask S_Mask => L_Mask; + }