diff --git a/DungeonShooting_Godot/prefab/ui/TileSetEditorSegment.tscn b/DungeonShooting_Godot/prefab/ui/TileSetEditorSegment.tscn index a0e53fe..9fcc463 100644 --- a/DungeonShooting_Godot/prefab/ui/TileSetEditorSegment.tscn +++ b/DungeonShooting_Godot/prefab/ui/TileSetEditorSegment.tscn @@ -67,8 +67,18 @@ offset_bottom = 32.0 grow_horizontal = 2 grow_vertical = 2 +scale = Vector2(2, 2) texture = ExtResource("2_wr143") +[node name="Brush" type="Control" parent="HSplitContainer/Left/MarginContainer/LeftBg/TileTexture"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 + [node name="Grid" type="ColorRect" parent="HSplitContainer/Left/MarginContainer/LeftBg"] material = SubResource("ShaderMaterial_u3xqn") layout_mode = 1 diff --git a/DungeonShooting_Godot/project.godot b/DungeonShooting_Godot/project.godot index 20cea87..a611d9f 100644 --- a/DungeonShooting_Godot/project.godot +++ b/DungeonShooting_Godot/project.godot @@ -210,6 +210,11 @@ "events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":1,"position":Vector2(136, 13),"global_position":Vector2(139, 45),"factor":1.0,"button_index":1,"canceled":false,"pressed":true,"double_click":false,"script":null) ] } +mouse_middle={ +"deadzone": 0.5, +"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":4,"position":Vector2(185, 17),"global_position":Vector2(189, 58),"factor":1.0,"button_index":3,"canceled":false,"pressed":true,"double_click":false,"script":null) +] +} [layer_names] diff --git a/DungeonShooting_Godot/src/game/data/DragBinder.cs b/DungeonShooting_Godot/src/game/data/DragBinder.cs index 4622dea..b816adb 100644 --- a/DungeonShooting_Godot/src/game/data/DragBinder.cs +++ b/DungeonShooting_Godot/src/game/data/DragBinder.cs @@ -12,6 +12,7 @@ public bool Dragging; public Vector2 PrevPosition; public Action Callback; + public StringName InputAction; public void OnMouseEntered() { diff --git a/DungeonShooting_Godot/src/game/manager/DragUiManager.cs b/DungeonShooting_Godot/src/game/manager/DragUiManager.cs index e6f9a0f..3a35326 100644 --- a/DungeonShooting_Godot/src/game/manager/DragUiManager.cs +++ b/DungeonShooting_Godot/src/game/manager/DragUiManager.cs @@ -11,16 +11,25 @@ /// /// 绑定拖拽事件 /// - public static DragBinder BindDrag(Control control, Action callback) + public static DragBinder BindDrag(Control control, StringName inputAction, Action callback) { var binder = new DragBinder(); binder.Control = control; control.MouseEntered += binder.OnMouseEntered; control.MouseExited += binder.OnMouseExited; binder.Callback = callback; + binder.InputAction = inputAction; _addList.Add(binder); return binder; } + + /// + /// 绑定拖拽事件 + /// + public static DragBinder BindDrag(Control control, Action callback) + { + return BindDrag(control, "mouse_left", callback); + } /// /// 解绑拖拽事件 @@ -40,14 +49,14 @@ { foreach (var dragBinder in _list) { - if (dragBinder.Dragging && !Input.IsActionPressed("mouse_left")) //松开鼠标, 结束拖拽 + if (dragBinder.Dragging && !Input.IsActionPressed(dragBinder.InputAction)) //松开鼠标, 结束拖拽 { dragBinder.Dragging = false; dragBinder.Callback(DragState.DragEnd, Vector2.Zero); } else if (!dragBinder.Dragging) //开始拖拽 { - if (dragBinder.MouseEntered && Input.IsActionJustPressed("mouse_left")) + if (dragBinder.MouseEntered && Input.IsActionJustPressed(dragBinder.InputAction)) { dragBinder.Dragging = true; dragBinder.PrevPosition = dragBinder.Control.GetGlobalMousePosition(); diff --git a/DungeonShooting_Godot/src/game/ui/tileSetEditorSegment/TileSetEditorSegment.cs b/DungeonShooting_Godot/src/game/ui/tileSetEditorSegment/TileSetEditorSegment.cs index a0b796c..245e694 100644 --- a/DungeonShooting_Godot/src/game/ui/tileSetEditorSegment/TileSetEditorSegment.cs +++ b/DungeonShooting_Godot/src/game/ui/tileSetEditorSegment/TileSetEditorSegment.cs @@ -30,10 +30,32 @@ } /// + /// 类型: , 路径: TileSetEditorSegment.HSplitContainer.Left.MarginContainer.LeftBg.TileTexture.Brush + /// + public class Brush : UiNode + { + public Brush(TileSetEditorSegmentPanel uiPanel, Godot.Control node) : base(uiPanel, node) { } + public override Brush Clone() => new (UiPanel, (Godot.Control)Instance.Duplicate()); + } + + /// /// 类型: , 路径: TileSetEditorSegment.HSplitContainer.Left.MarginContainer.LeftBg.TileTexture /// public class TileTexture : UiNode { + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: TileSetEditorSegment.HSplitContainer.Left.MarginContainer.LeftBg.Brush + /// + public Brush L_Brush + { + get + { + if (_L_Brush == null) _L_Brush = new Brush(UiPanel, Instance.GetNode("Brush")); + return _L_Brush; + } + } + private Brush _L_Brush; + public TileTexture(TileSetEditorSegmentPanel uiPanel, Godot.TextureRect node) : base(uiPanel, node) { } public override TileTexture Clone() => new (UiPanel, (Godot.TextureRect)Instance.Duplicate()); } @@ -194,6 +216,11 @@ /// + /// 场景中唯一名称的节点, 节点类型: , 节点路径: TileSetEditorSegment.HSplitContainer.Left.MarginContainer.LeftBg.TileTexture.Brush + /// + public Brush S_Brush => L_HSplitContainer.L_Left.L_MarginContainer.L_LeftBg.L_TileTexture.L_Brush; + + /// /// 场景中唯一名称的节点, 节点类型: , 节点路径: TileSetEditorSegment.HSplitContainer.Left.MarginContainer.LeftBg.TileTexture /// public TileTexture S_TileTexture => L_HSplitContainer.L_Left.L_MarginContainer.L_LeftBg.L_TileTexture; diff --git a/DungeonShooting_Godot/src/game/ui/tileSetEditorSegment/TileSetEditorSegmentLeftBg.cs b/DungeonShooting_Godot/src/game/ui/tileSetEditorSegment/TileSetEditorSegmentLeftBg.cs index 60a98fd..1c9ba1c 100644 --- a/DungeonShooting_Godot/src/game/ui/tileSetEditorSegment/TileSetEditorSegmentLeftBg.cs +++ b/DungeonShooting_Godot/src/game/ui/tileSetEditorSegment/TileSetEditorSegmentLeftBg.cs @@ -10,7 +10,8 @@ public void SetUiNode(IUiNode uiNode) { _leftBg = (TileSetEditorSegment.LeftBg)uiNode; - _dragBinder = DragUiManager.BindDrag(this, OnDrag); + _leftBg.L_TileTexture.L_Brush.Instance.Draw += OnBrushDraw; + _dragBinder = DragUiManager.BindDrag(this, "mouse_middle", OnDrag); Resized += OnLeftBgResize; } @@ -19,6 +20,11 @@ _dragBinder.UnBind(); } + public override void _Process(double delta) + { + _leftBg.L_TileTexture.L_Brush.Instance.QueueRedraw(); + } + private void OnDrag(DragState state, Vector2 pos) { if (state == DragState.DragMove) @@ -57,41 +63,32 @@ //缩小 private void Shrink() { - // var sprite = _leftBg.L_TileTexture.Instance; - // var pos = sprite.GetLocalMousePosition(); - // var scale = sprite.Scale / 1.1f; - // if (scale.LengthSquared() >= 0.5f) - // { - // sprite.Scale = scale; - // var tempPos = sprite.Position + pos * 0.1f * scale; - // SetGridTransform(tempPos, scale.X); - // } - // OnLeftBgResize(); - - var scale = _leftBg.L_TileTexture.Instance.Scale; - scale = new Vector2(Mathf.Max(0.1f, scale.X / 1.1f), Mathf.Max(0.1f, scale.Y / 1.1f)); - _leftBg.L_TileTexture.Instance.Scale = scale; - OnLeftBgResize(); + var textureRect = _leftBg.L_TileTexture.Instance; + var offset = textureRect.GetLocalMousePosition(); + var prevScale = textureRect.Scale; + var newScale = prevScale / 1.1f; + if (newScale.LengthSquared() >= 0.5f) + { + textureRect.Scale = newScale; + var position = textureRect.Position + offset * 0.1f * newScale; + textureRect.Position = position; + SetGridTransform(position, newScale.X); + } } //放大 private void Magnify() { - // var sprite = _leftBg.L_TileTexture.Instance; - // var pos = GetLocalMousePosition(); - // var prevScale = sprite.Scale; - // var scale = prevScale * 1.1f; - // if (scale.LengthSquared() <= 2000) - // { - // sprite.Scale = scale; - // var tempPos = sprite.Position - pos * 0.1f * prevScale; - // SetGridTransform(tempPos, scale.X); - // } - // OnLeftBgResize(); - - var scale = _leftBg.L_TileTexture.Instance.Scale; - scale = new Vector2(Mathf.Min(20f, scale.X * 1.1f), Mathf.Min(20f, scale.Y * 1.1f)); - _leftBg.L_TileTexture.Instance.Scale = scale; - OnLeftBgResize(); + var textureRect = _leftBg.L_TileTexture.Instance; + var offset = textureRect.GetLocalMousePosition(); + var prevScale = textureRect.Scale; + var newScale = prevScale * 1.1f; + if (newScale.LengthSquared() <= 2000) + { + textureRect.Scale = newScale; + var position = textureRect.Position - offset * 0.1f * prevScale; + textureRect.Position = position; + SetGridTransform(position, newScale.X); + } } /// @@ -109,15 +106,55 @@ { var sprite = _leftBg.L_TileTexture.Instance; sprite.Texture = _leftBg.UiPanel.EditorPanel.Texture; + var colorRect = _leftBg.L_Grid.Instance; colorRect.Material.SetShaderMaterialParameter(ShaderParamNames.Size, Size); SetGridTransform(sprite.Position, sprite.Scale.X); } + //设置网格位置和缩放 private void SetGridTransform(Vector2 pos, float scale) { var colorRect = _leftBg.L_Grid.Instance; colorRect.Material.SetShaderMaterialParameter(ShaderParamNames.GridSize, GameConfig.TileCellSize * scale); colorRect.Material.SetShaderMaterialParameter(ShaderParamNames.Offset, -pos); } + + private void OnBrushDraw() + { + //绘制texture区域 + var textureRect = _leftBg.L_TileTexture.Instance; + var brush = _leftBg.L_TileTexture.L_Brush; + if (textureRect.Texture != null) + { + brush.Instance.DrawRect(new Rect2(Vector2.Zero, textureRect.Size), + new Color(1, 1, 0, 0.5f), false, + 2f / textureRect.Scale.X); + } + + //绘制鼠标悬停区域 + if (IsMouseInTexture()) + { + var pos = textureRect.GetLocalMousePosition() / GameConfig.TileCellSize; + pos = new Vector2((int)pos.X * GameConfig.TileCellSize, (int)pos.Y * GameConfig.TileCellSize); + brush.Instance.DrawRect( + new Rect2(pos,GameConfig.TileCellSizeVector2I), + Colors.Green, false, 3f / textureRect.Scale.X + ); + } + } + + //返回鼠标是否在texture区域内 + private bool IsMouseInTexture() + { + var textureRect = _leftBg.L_TileTexture.Instance; + var pos = textureRect.GetLocalMousePosition(); + if (pos.X < 0 || pos.Y < 0) + { + return false; + } + + var size = textureRect.Size; + return pos.X <= size.X && pos.Y <= size.Y; + } } \ No newline at end of file