diff --git a/DungeonShooting_Godot/prefab/ui/TileSetEditorCombination.tscn b/DungeonShooting_Godot/prefab/ui/TileSetEditorCombination.tscn index 4f906ac..2ab686e 100644 --- a/DungeonShooting_Godot/prefab/ui/TileSetEditorCombination.tscn +++ b/DungeonShooting_Godot/prefab/ui/TileSetEditorCombination.tscn @@ -1,13 +1,17 @@ -[gd_scene load_steps=11 format=3 uid="uid://daias2tkvj20c"] +[gd_scene load_steps=15 format=3 uid="uid://daias2tkvj20c"] [ext_resource type="Script" path="res://src/game/ui/tileSetEditorCombination/TileSetEditorCombinationPanel.cs" id="1_to1lc"] [ext_resource type="Script" path="res://src/game/ui/tileSetEditorCombination/leftBottom/TileEditArea.cs" id="2_h43yx"] [ext_resource type="Shader" path="res://resource/material/Grid.gdshader" id="2_t1p2n"] [ext_resource type="Texture2D" uid="uid://uhhfgdhpk7i4" path="res://icon.png" id="2_wr143"] +[ext_resource type="Script" path="res://src/game/ui/tileSetEditorCombination/leftTop/RectBrush.cs" id="3_avikb"] [ext_resource type="Script" path="res://src/game/ui/tileSetEditorCombination/leftBottom/MaskBrush.cs" id="4_ytys0"] +[ext_resource type="Texture2D" uid="uid://fkg21rtph51d" path="res://resource/sprite/ui/commonIcon/Delete2.png" id="5_6jqro"] +[ext_resource type="Texture2D" uid="uid://7l7aqhsaexoh" path="res://resource/sprite/ui/commonIcon/Play.png" id="6_75xjp"] [ext_resource type="Script" path="res://src/game/ui/tileSetEditorCombination/leftTop/TileEditCombination.cs" id="6_bb3jf"] [ext_resource type="Texture2D" uid="uid://bn47bmilcw4x0" path="res://resource/sprite/ui/commonIcon/Select2.png" id="6_g5ey6"] [ext_resource type="Script" path="res://src/game/ui/tileSetEditorCombination/right/TileSelected.cs" id="6_gql80"] +[ext_resource type="Texture2D" uid="uid://d2wslibovwv7w" path="res://resource/sprite/ui/commonIcon/CenterTool.png" id="7_mbnpy"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_df7va"] resource_local_to_scene = true @@ -89,8 +93,12 @@ scale = Vector2(3, 3) mouse_filter = 2 +[node name="CanvasRoot" type="Node2D" parent="HSplitContainer/VSplitContainer/LeftTop/MarginContainer/LeftTopBg/CombinationRoot"] + [node name="BrushRoot" type="Node2D" parent="HSplitContainer/VSplitContainer/LeftTop/MarginContainer/LeftTopBg/CombinationRoot"] -z_index = 1 + +[node name="RectBrush" type="Node2D" parent="HSplitContainer/VSplitContainer/LeftTop/MarginContainer/LeftTopBg/CombinationRoot"] +script = ExtResource("3_avikb") [node name="Grid" type="ColorRect" parent="HSplitContainer/VSplitContainer/LeftTop/MarginContainer/LeftTopBg"] material = SubResource("ShaderMaterial_df7va") @@ -102,6 +110,52 @@ grow_vertical = 2 mouse_filter = 2 +[node name="FocusBtn" type="TextureButton" parent="HSplitContainer/VSplitContainer/LeftTop/MarginContainer/LeftTopBg"] +layout_mode = 1 +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -79.0 +offset_top = 14.0 +offset_right = -15.0 +offset_bottom = 78.0 +grow_horizontal = 0 +tooltip_text = "聚焦" +texture_normal = ExtResource("7_mbnpy") +ignore_texture_size = true +stretch_mode = 5 + +[node name="DeleteBtn" type="TextureButton" parent="HSplitContainer/VSplitContainer/LeftTop/MarginContainer/LeftTopBg"] +layout_mode = 1 +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -151.0 +offset_top = 14.0 +offset_right = -87.0 +offset_bottom = 78.0 +grow_horizontal = 0 +tooltip_text = "删除所有图块" +texture_normal = ExtResource("5_6jqro") +ignore_texture_size = true +stretch_mode = 5 + +[node name="ImportBtn" type="Button" parent="HSplitContainer/VSplitContainer/LeftTop/MarginContainer/LeftTopBg"] +layout_mode = 1 +anchors_preset = 3 +anchor_left = 1.0 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -191.0 +offset_top = -84.0 +offset_right = -15.0 +offset_bottom = -20.0 +grow_horizontal = 0 +grow_vertical = 0 +text = "导入组合" +icon = ExtResource("6_75xjp") + [node name="LeftBottom" type="Panel" parent="HSplitContainer/VSplitContainer"] layout_mode = 2 size_flags_horizontal = 3 @@ -180,6 +234,21 @@ grow_vertical = 2 mouse_filter = 2 +[node name="FocusBtn" type="TextureButton" parent="HSplitContainer/VSplitContainer/LeftBottom/MarginContainer/LeftBottomBg"] +layout_mode = 1 +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -79.0 +offset_top = 14.0 +offset_right = -15.0 +offset_bottom = 78.0 +grow_horizontal = 0 +tooltip_text = "聚焦" +texture_normal = ExtResource("7_mbnpy") +ignore_texture_size = true +stretch_mode = 5 + [node name="Right" type="Panel" parent="HSplitContainer"] layout_mode = 2 size_flags_horizontal = 3 diff --git a/DungeonShooting_Godot/resource/sprite/ui/commonIcon/CenterTool.png b/DungeonShooting_Godot/resource/sprite/ui/commonIcon/CenterTool.png index d980ce2..0ecd99e 100644 --- a/DungeonShooting_Godot/resource/sprite/ui/commonIcon/CenterTool.png +++ b/DungeonShooting_Godot/resource/sprite/ui/commonIcon/CenterTool.png Binary files differ diff --git a/DungeonShooting_Godot/resource/sprite/ui/commonIcon/Delete2.png b/DungeonShooting_Godot/resource/sprite/ui/commonIcon/Delete2.png new file mode 100644 index 0000000..dc4c9f9 --- /dev/null +++ b/DungeonShooting_Godot/resource/sprite/ui/commonIcon/Delete2.png Binary files differ diff --git a/DungeonShooting_Godot/resource/sprite/ui/commonIcon/Delete2.png.import b/DungeonShooting_Godot/resource/sprite/ui/commonIcon/Delete2.png.import new file mode 100644 index 0000000..7130c78 --- /dev/null +++ b/DungeonShooting_Godot/resource/sprite/ui/commonIcon/Delete2.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://fkg21rtph51d" +path="res://.godot/imported/Delete2.png-171dd9a0d65da0bd6c6e0b2740c3d2b7.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://resource/sprite/ui/commonIcon/Delete2.png" +dest_files=["res://.godot/imported/Delete2.png-171dd9a0d65da0bd6c6e0b2740c3d2b7.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/DungeonShooting_Godot/src/game/event/EventEnum.cs b/DungeonShooting_Godot/src/game/event/EventEnum.cs index b133ecd..431226d 100644 --- a/DungeonShooting_Godot/src/game/event/EventEnum.cs +++ b/DungeonShooting_Godot/src/game/event/EventEnum.cs @@ -161,6 +161,10 @@ /// OnSelectCombinationCell, /// + /// 移除组合模式下的Cell图块, 参数为 + /// + OnRemoveCombinationCell, + /// /// 清除组合模式下的Cell图块 /// OnClearCombinationCell, diff --git a/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/GridBg.cs b/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/GridBg.cs index 4606c98..010b153 100644 --- a/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/GridBg.cs +++ b/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/GridBg.cs @@ -14,7 +14,7 @@ { UiNode = (T)uiNode; _dragBinder = DragUiManager.BindDrag(this, "mouse_middle", OnDrag); - Resized += OnLeftBgResize; + Resized += RefreshGridTrans; } public virtual void OnDestroy() @@ -27,36 +27,28 @@ /// public void OnShow() { - OnLeftBgResize(); + RefreshGridTrans(); } - public override void _UnhandledInput(InputEvent @event) + public override void _GuiInput(InputEvent @event) { - //Ui未打开 - var uiPanel = UiNode.GetUiPanel(); - if (!uiPanel.IsOpen) - { - return; - } if (@event is InputEventMouseButton mouseButton) { - if (uiPanel.IsOpen) + AcceptEvent(); + if (mouseButton.ButtonIndex == MouseButton.WheelDown) { - if (mouseButton.ButtonIndex == MouseButton.WheelDown) + if (GetGlobalRect().HasPoint(mouseButton.GlobalPosition)) { - if (GetGlobalRect().HasPoint(mouseButton.GlobalPosition)) - { - //缩小 - Shrink(); - } + //缩小 + Shrink(); } - else if (mouseButton.ButtonIndex == MouseButton.WheelUp) + } + else if (mouseButton.ButtonIndex == MouseButton.WheelUp) + { + if (GetGlobalRect().HasPoint(mouseButton.GlobalPosition)) { - if (GetGlobalRect().HasPoint(mouseButton.GlobalPosition)) - { - //放大 - Magnify(); - } + //放大 + Magnify(); } } } @@ -97,13 +89,15 @@ if (state == DragState.DragMove) { ContainerRoot.Position += pos; - OnLeftBgResize(); + RefreshGridTrans(); } } - //背景宽度变化 - private void OnLeftBgResize() + /// + /// 刷新背景网格位置和缩放 + /// + public void RefreshGridTrans() { Grid.Material.SetShaderMaterialParameter(ShaderParamNames.Size, Size); SetGridTransform(ContainerRoot.Position, ContainerRoot.Scale.X); diff --git a/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/TileSetEditorCombination.cs b/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/TileSetEditorCombination.cs index 3e5b17b..89feacd 100644 --- a/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/TileSetEditorCombination.cs +++ b/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/TileSetEditorCombination.cs @@ -32,6 +32,15 @@ } /// + /// 类型: , 路径: TileSetEditorCombination.HSplitContainer.VSplitContainer.LeftTop.MarginContainer.LeftTopBg.CombinationRoot.CanvasRoot + /// + public class CanvasRoot : UiNode + { + public CanvasRoot(TileSetEditorCombinationPanel uiPanel, Godot.Node2D node) : base(uiPanel, node) { } + public override CanvasRoot Clone() => new (UiPanel, (Godot.Node2D)Instance.Duplicate()); + } + + /// /// 类型: , 路径: TileSetEditorCombination.HSplitContainer.VSplitContainer.LeftTop.MarginContainer.LeftTopBg.CombinationRoot.BrushRoot /// public class BrushRoot : UiNode @@ -41,11 +50,33 @@ } /// + /// 类型: , 路径: TileSetEditorCombination.HSplitContainer.VSplitContainer.LeftTop.MarginContainer.LeftTopBg.CombinationRoot.RectBrush + /// + public class RectBrush : UiNode + { + public RectBrush(TileSetEditorCombinationPanel uiPanel, UI.TileSetEditorCombination.RectBrush node) : base(uiPanel, node) { } + public override RectBrush Clone() => new (UiPanel, (UI.TileSetEditorCombination.RectBrush)Instance.Duplicate()); + } + + /// /// 类型: , 路径: TileSetEditorCombination.HSplitContainer.VSplitContainer.LeftTop.MarginContainer.LeftTopBg.CombinationRoot /// public class CombinationRoot : UiNode { /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: TileSetEditorCombination.HSplitContainer.VSplitContainer.LeftTop.MarginContainer.LeftTopBg.CanvasRoot + /// + public CanvasRoot L_CanvasRoot + { + get + { + if (_L_CanvasRoot == null) _L_CanvasRoot = new CanvasRoot(UiPanel, Instance.GetNode("CanvasRoot")); + return _L_CanvasRoot; + } + } + private CanvasRoot _L_CanvasRoot; + + /// /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: TileSetEditorCombination.HSplitContainer.VSplitContainer.LeftTop.MarginContainer.LeftTopBg.BrushRoot /// public BrushRoot L_BrushRoot @@ -58,6 +89,19 @@ } private BrushRoot _L_BrushRoot; + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: TileSetEditorCombination.HSplitContainer.VSplitContainer.LeftTop.MarginContainer.LeftTopBg.RectBrush + /// + public RectBrush L_RectBrush + { + get + { + if (_L_RectBrush == null) _L_RectBrush = new RectBrush(UiPanel, Instance.GetNode("RectBrush")); + return _L_RectBrush; + } + } + private RectBrush _L_RectBrush; + public CombinationRoot(TileSetEditorCombinationPanel uiPanel, Godot.Control node) : base(uiPanel, node) { } public override CombinationRoot Clone() => new (UiPanel, (Godot.Control)Instance.Duplicate()); } @@ -72,6 +116,33 @@ } /// + /// 类型: , 路径: TileSetEditorCombination.HSplitContainer.VSplitContainer.LeftTop.MarginContainer.LeftTopBg.FocusBtn + /// + public class FocusBtn : UiNode + { + public FocusBtn(TileSetEditorCombinationPanel uiPanel, Godot.TextureButton node) : base(uiPanel, node) { } + public override FocusBtn Clone() => new (UiPanel, (Godot.TextureButton)Instance.Duplicate()); + } + + /// + /// 类型: , 路径: TileSetEditorCombination.HSplitContainer.VSplitContainer.LeftTop.MarginContainer.LeftTopBg.DeleteBtn + /// + public class DeleteBtn : UiNode + { + public DeleteBtn(TileSetEditorCombinationPanel uiPanel, Godot.TextureButton node) : base(uiPanel, node) { } + public override DeleteBtn Clone() => new (UiPanel, (Godot.TextureButton)Instance.Duplicate()); + } + + /// + /// 类型: , 路径: TileSetEditorCombination.HSplitContainer.VSplitContainer.LeftTop.MarginContainer.LeftTopBg.ImportBtn + /// + public class ImportBtn : UiNode + { + public ImportBtn(TileSetEditorCombinationPanel uiPanel, Godot.Button node) : base(uiPanel, node) { } + public override ImportBtn Clone() => new (UiPanel, (Godot.Button)Instance.Duplicate()); + } + + /// /// 类型: , 路径: TileSetEditorCombination.HSplitContainer.VSplitContainer.LeftTop.MarginContainer.LeftTopBg /// public class LeftTopBg : UiNode @@ -102,6 +173,45 @@ } private Grid _L_Grid; + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: TileSetEditorCombination.HSplitContainer.VSplitContainer.LeftTop.MarginContainer.FocusBtn + /// + public FocusBtn L_FocusBtn + { + get + { + if (_L_FocusBtn == null) _L_FocusBtn = new FocusBtn(UiPanel, Instance.GetNode("FocusBtn")); + return _L_FocusBtn; + } + } + private FocusBtn _L_FocusBtn; + + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: TileSetEditorCombination.HSplitContainer.VSplitContainer.LeftTop.MarginContainer.DeleteBtn + /// + public DeleteBtn L_DeleteBtn + { + get + { + if (_L_DeleteBtn == null) _L_DeleteBtn = new DeleteBtn(UiPanel, Instance.GetNode("DeleteBtn")); + return _L_DeleteBtn; + } + } + private DeleteBtn _L_DeleteBtn; + + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: TileSetEditorCombination.HSplitContainer.VSplitContainer.LeftTop.MarginContainer.ImportBtn + /// + public ImportBtn L_ImportBtn + { + get + { + if (_L_ImportBtn == null) _L_ImportBtn = new ImportBtn(UiPanel, Instance.GetNode("ImportBtn")); + return _L_ImportBtn; + } + } + private ImportBtn _L_ImportBtn; + public LeftTopBg(TileSetEditorCombinationPanel uiPanel, UI.TileSetEditorCombination.TileEditCombination node) : base(uiPanel, node) { } public override LeftTopBg Clone() => new (UiPanel, (UI.TileSetEditorCombination.TileEditCombination)Instance.Duplicate()); } @@ -235,6 +345,15 @@ } /// + /// 类型: , 路径: TileSetEditorCombination.HSplitContainer.VSplitContainer.LeftBottom.MarginContainer.LeftBottomBg.FocusBtn + /// + public class FocusBtn_1 : UiNode + { + public FocusBtn_1(TileSetEditorCombinationPanel uiPanel, Godot.TextureButton node) : base(uiPanel, node) { } + public override FocusBtn_1 Clone() => new (UiPanel, (Godot.TextureButton)Instance.Duplicate()); + } + + /// /// 类型: , 路径: TileSetEditorCombination.HSplitContainer.VSplitContainer.LeftBottom.MarginContainer.LeftBottomBg /// public class LeftBottomBg : UiNode @@ -265,6 +384,19 @@ } private Grid_1 _L_Grid; + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: TileSetEditorCombination.HSplitContainer.VSplitContainer.LeftBottom.MarginContainer.FocusBtn + /// + public FocusBtn_1 L_FocusBtn + { + get + { + if (_L_FocusBtn == null) _L_FocusBtn = new FocusBtn_1(UiPanel, Instance.GetNode("FocusBtn")); + return _L_FocusBtn; + } + } + private FocusBtn_1 _L_FocusBtn; + public LeftBottomBg(TileSetEditorCombinationPanel uiPanel, UI.TileSetEditorCombination.TileEditArea node) : base(uiPanel, node) { } public override LeftBottomBg Clone() => new (UiPanel, (UI.TileSetEditorCombination.TileEditArea)Instance.Duplicate()); } @@ -570,16 +702,36 @@ /// + /// 场景中唯一名称的节点, 节点类型: , 节点路径: TileSetEditorCombination.HSplitContainer.VSplitContainer.LeftTop.MarginContainer.LeftTopBg.CombinationRoot.CanvasRoot + /// + public CanvasRoot S_CanvasRoot => L_HSplitContainer.L_VSplitContainer.L_LeftTop.L_MarginContainer.L_LeftTopBg.L_CombinationRoot.L_CanvasRoot; + + /// /// 场景中唯一名称的节点, 节点类型: , 节点路径: TileSetEditorCombination.HSplitContainer.VSplitContainer.LeftTop.MarginContainer.LeftTopBg.CombinationRoot.BrushRoot /// public BrushRoot S_BrushRoot => L_HSplitContainer.L_VSplitContainer.L_LeftTop.L_MarginContainer.L_LeftTopBg.L_CombinationRoot.L_BrushRoot; /// + /// 场景中唯一名称的节点, 节点类型: , 节点路径: TileSetEditorCombination.HSplitContainer.VSplitContainer.LeftTop.MarginContainer.LeftTopBg.CombinationRoot.RectBrush + /// + public RectBrush S_RectBrush => L_HSplitContainer.L_VSplitContainer.L_LeftTop.L_MarginContainer.L_LeftTopBg.L_CombinationRoot.L_RectBrush; + + /// /// 场景中唯一名称的节点, 节点类型: , 节点路径: TileSetEditorCombination.HSplitContainer.VSplitContainer.LeftTop.MarginContainer.LeftTopBg.CombinationRoot /// public CombinationRoot S_CombinationRoot => L_HSplitContainer.L_VSplitContainer.L_LeftTop.L_MarginContainer.L_LeftTopBg.L_CombinationRoot; /// + /// 场景中唯一名称的节点, 节点类型: , 节点路径: TileSetEditorCombination.HSplitContainer.VSplitContainer.LeftTop.MarginContainer.LeftTopBg.DeleteBtn + /// + public DeleteBtn S_DeleteBtn => L_HSplitContainer.L_VSplitContainer.L_LeftTop.L_MarginContainer.L_LeftTopBg.L_DeleteBtn; + + /// + /// 场景中唯一名称的节点, 节点类型: , 节点路径: TileSetEditorCombination.HSplitContainer.VSplitContainer.LeftTop.MarginContainer.LeftTopBg.ImportBtn + /// + public ImportBtn S_ImportBtn => L_HSplitContainer.L_VSplitContainer.L_LeftTop.L_MarginContainer.L_LeftTopBg.L_ImportBtn; + + /// /// 场景中唯一名称的节点, 节点类型: , 节点路径: TileSetEditorCombination.HSplitContainer.VSplitContainer.LeftTop.MarginContainer.LeftTopBg /// public LeftTopBg S_LeftTopBg => L_HSplitContainer.L_VSplitContainer.L_LeftTop.L_MarginContainer.L_LeftTopBg; diff --git a/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/leftBottom/TileEditArea.cs b/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/leftBottom/TileEditArea.cs index ec72cdd..76f6f29 100644 --- a/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/leftBottom/TileEditArea.cs +++ b/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/leftBottom/TileEditArea.cs @@ -21,6 +21,9 @@ _maskGrid = new UiGrid(UiNode.L_TileTexture.L_MaskRoot.L_MaskRect, typeof(MaskRectCell)); _maskGrid.SetCellOffset(Vector2I.Zero); _maskGrid.GridContainer.MouseFilter = MouseFilterEnum.Ignore; + + //聚焦按钮点击 + UiNode.L_FocusBtn.Instance.Pressed += OnFocusClick; } public override void OnDestroy() @@ -29,31 +32,52 @@ _maskGrid.Destroy(); } - public override void _Process(double delta) + public override void _GuiInput(InputEvent @event) { - //Ui未打开 - if (!UiNode.UiPanel.IsOpen) + base._GuiInput(@event); + if (@event is InputEventMouse) { - return; - } - - if (Input.IsMouseButtonPressed(MouseButton.Left)) //左键选中 - { - if (this.IsMouseInRect()) + AcceptEvent(); + if (Input.IsMouseButtonPressed(MouseButton.Left)) //左键选中 { var cellPosition = GetMouseCellPosition(); if (UiNode.UiPanel.EditorPanel.IsCellPositionInTexture(cellPosition)) { if (Input.IsActionJustPressed("mouse_left")) //刚按下, 清除之前的选中 { - OnRemoveCell(); + OnClearCell(); } OnSelectCell(cellPosition); } } + else if (Input.IsMouseButtonPressed(MouseButton.Right)) //右键键擦除 + { + var cellPosition = GetMouseCellPosition(); + if (UiNode.UiPanel.EditorPanel.IsCellPositionInTexture(cellPosition)) + { + OnRemoveCell(cellPosition); + } + } } } + //聚焦按钮点击 + private void OnFocusClick() + { + var pos = Size / 2; + var texture = UiNode.L_TileTexture.Instance.Texture; + if (texture != null) + { + ContainerRoot.Position = pos - texture.GetSize() * 0.5f * ContainerRoot.Scale; + } + else + { + ContainerRoot.Position = pos; + } + + RefreshGridTrans(); + } + /// /// 选中Cell图块 /// @@ -74,9 +98,28 @@ } /// - /// 移除选中的Cell图块 + /// 移除指定的Cell图块 /// - private void OnRemoveCell() + private void OnRemoveCell(Vector2I cell) + { + if (_useMask.Contains(cell)) + { + var cellIndex = UiNode.UiPanel.EditorPanel.CellPositionToIndex(cell); + var uiCell = _maskGrid.GetCell(cellIndex); + if (uiCell != null && uiCell.Data) + { + _useMask.Remove(cell); + uiCell.SetData(false); + + EventManager.EmitEvent(EventEnum.OnRemoveCombinationCell, cell); + } + } + } + + /// + /// 移除所有选中的Cell图块 + /// + private void OnClearCell() { _useMask.Clear(); var count = _maskGrid.Count; @@ -110,6 +153,8 @@ _maskGrid.Add(false); } } + + OnFocusClick(); } /// diff --git a/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/leftTop/RectBrush.cs b/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/leftTop/RectBrush.cs new file mode 100644 index 0000000..7f9253a --- /dev/null +++ b/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/leftTop/RectBrush.cs @@ -0,0 +1,75 @@ +using Godot; + +namespace UI.TileSetEditorCombination; + +public partial class RectBrush : Node2D +{ + /// + /// 所在的根节点 + /// + public Control Root { get; set; } + + private bool _drawFlag = false; + private int _x; + private int _y; + private int _w; + private int _h; + + public override void _Process(double delta) + { + QueueRedraw(); + } + + /// + /// 停止绘制 + /// + public void ClearDrawRect() + { + _drawFlag = false; + } + + /// + /// 设置绘制的矩形区域 + /// + public void SetDrawRect(int x, int y, int w, int h) + { + _drawFlag = true; + _x = x; + _y = y; + _w = w; + _h = h; + } + + /// + /// 获取中心点坐标 + /// + public Vector2I GetCenterPosition() + { + if (!_drawFlag) + { + return Vector2I.Zero; + } + return new Vector2I(_x + _w / 2, _y + _h / 2); + } + + /// + /// 获取绘制的矩形大小 + /// + public Vector2I GetRectSize() + { + if (!_drawFlag) + { + return Vector2I.Zero; + } + + return new Vector2I(_w, _h); + } + + public override void _Draw() + { + if (Root != null && _drawFlag) + { + DrawRect(new Rect2(_x, _y, _w, _h), new Color(1, 1, 0, 0.5f), false, 2f / Root.Scale.X); + } + } +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/leftTop/TileEditCombination.cs b/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/leftTop/TileEditCombination.cs index 9fc4298..751e698 100644 --- a/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/leftTop/TileEditCombination.cs +++ b/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/leftTop/TileEditCombination.cs @@ -1,12 +1,15 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Godot; namespace UI.TileSetEditorCombination; public partial class TileEditCombination : GridBg { - //kay: 代表原图中的坐标, 单位: 格 + // ------------------------------- 笔刷相关 ------------------------------- + //笔刷数据, kay: 代表原图中的坐标, 单位: 格 private Dictionary _brushData = new Dictionary(); + //笔刷偏移, 单位: 像素 private Vector2I _brushOffset = Vector2I.Zero; //上一帧笔刷位置 @@ -17,17 +20,33 @@ private int _yStart = int.MaxValue; private int _xEnd = int.MinValue; private int _yEnd = int.MinValue; - - private Dictionary _canvas = new Dictionary(); + // ----------------------------------------------------------------------- + // ------------------------------- 画布相关 ------------------------------- + //画布数据, kay: 绘制坐标, 单位: 像素 + private Dictionary _canvas = new Dictionary(); + //画布数据是否需要更新 + private bool _canvasDirty = false; + // ----------------------------------------------------------------------- + + public override void SetUiNode(IUiNode uiNode) { base.SetUiNode(uiNode); + UiNode.L_CombinationRoot.L_RectBrush.Instance.Root = UiNode.L_CombinationRoot.Instance; Grid = UiNode.L_Grid.Instance; ContainerRoot = UiNode.L_CombinationRoot.Instance; - + UiNode.UiPanel.AddEventListener(EventEnum.OnSelectCombinationCell, OnSelectCombinationCell); + UiNode.UiPanel.AddEventListener(EventEnum.OnRemoveCombinationCell, OnRemoveCombinationCell); UiNode.UiPanel.AddEventListener(EventEnum.OnClearCombinationCell, OnClearCombinationCell); + + //删除按钮点击事件 + UiNode.L_DeleteBtn.Instance.Pressed += OnDeleteClick; + //聚焦按钮点击事件 + UiNode.L_FocusBtn.Instance.Pressed += OnFocusClick; + //导入组合按钮点击事件 + UiNode.L_ImportBtn.Instance.Pressed += OnImportClick; } public override void _Process(double delta) @@ -39,22 +58,122 @@ var brushRoot = UiNode.L_CombinationRoot.L_BrushRoot.Instance; var combinationRoot = UiNode.L_CombinationRoot.Instance; - Vector2 newPos = combinationRoot.GetLocalMousePosition().FloorAdsorption(GameConfig.TileCellSizeVector2I) + _brushOffset; - brushRoot.Position = newPos; + brushRoot.Position = combinationRoot.GetLocalMousePosition().FloorAdsorption(GameConfig.TileCellSizeVector2I) + _brushOffset; - //左键按下开始绘制 - if (_initBrush && Input.IsMouseButtonPressed(MouseButton.Left) && this.IsMouseInRect()) + if (_canvasDirty) //更新画布范围 { - if (_brushPrevPos != newPos || !_drawBrushFlag) + _canvasDirty = false; + if (_canvas.Count > 0) { - _drawBrushFlag = true; - _brushPrevPos = newPos; - DrawBrush(); + //单位: 像素 + var canvasXStart = int.MaxValue; + var canvasYStart = int.MaxValue; + var canvasXEnd = int.MinValue; + var canvasYEnd = int.MinValue; + + foreach (var keyValuePair in _canvas) + { + var pos = keyValuePair.Key; + canvasXStart = Mathf.Min(pos.X, canvasXStart); + canvasYStart = Mathf.Min(pos.Y, canvasYStart); + canvasXEnd = Mathf.Max(pos.X + GameConfig.TileCellSize, canvasXEnd); + canvasYEnd = Mathf.Max(pos.Y + GameConfig.TileCellSize, canvasYEnd); + } + + UiNode.L_CombinationRoot.L_RectBrush.Instance.SetDrawRect( + canvasXStart, + canvasYStart, + canvasXEnd - canvasXStart, + canvasYEnd - canvasYStart + ); + } + else + { + UiNode.L_CombinationRoot.L_RectBrush.Instance.ClearDrawRect(); } } - else + } + + public override void _GuiInput(InputEvent @event) + { + base._GuiInput(@event); + if (@event is InputEventMouse) { - _drawBrushFlag = false; + AcceptEvent(); + var brushRoot = UiNode.L_CombinationRoot.L_BrushRoot.Instance; + var newPos = brushRoot.Position; + + sbyte flag = 0; + //左键按下开始绘制 + if (_initBrush) + { + if (Input.IsMouseButtonPressed(MouseButton.Left)) //绘制 + { + flag = 1; + if (_brushPrevPos != newPos || !_drawBrushFlag) + { + _drawBrushFlag = true; + _brushPrevPos = newPos; + DrawBrush(); + } + } + else if (Input.IsMouseButtonPressed(MouseButton.Right)) //擦除 + { + flag = -1; + brushRoot.Modulate = new Color(1, 1, 1, 0.3f); + if (_brushPrevPos != newPos || !_drawBrushFlag) + { + _drawBrushFlag = true; + _brushPrevPos = newPos; + EraseBrush(); + } + } + } + + if (flag != 0) + { + _drawBrushFlag = false; + } + + if (flag != -1) + { + brushRoot.Modulate = Colors.White; + } + } + } + + //删除所有图块 + private void OnDeleteClick() + { + foreach (var keyValuePair in _canvas) + { + keyValuePair.Value.QueueFree(); + } + + _canvas.Clear(); + _canvasDirty = true; + } + + //点击聚焦按钮 + private void OnFocusClick() + { + var pos = Size / 2; + var center = UiNode.L_CombinationRoot.L_RectBrush.Instance.GetCenterPosition(); + ContainerRoot.Position = pos - center * ContainerRoot.Scale; + RefreshGridTrans(); + } + + //导入按钮点击 + private void OnImportClick() + { + var size = UiNode.L_CombinationRoot.L_RectBrush.Instance.GetRectSize(); + if (size == Vector2.Zero) + { + EditorWindowManager.ShowTips("警告", "请先绘制组合图块!"); + } + else if (size == GameConfig.TileCellSizeVector2I) + { + EditorWindowManager.ShowTips("警告", "导入一格大小的组合图块没有任何意义!"); } } @@ -74,8 +193,26 @@ { canvasCell = (CombinationCell)combinationCell.Duplicate(); canvasCell.Position = pos; - UiNode.L_CombinationRoot.AddChild(canvasCell); + UiNode.L_CombinationRoot.L_CanvasRoot.AddChild(canvasCell); _canvas.Add(pos, canvasCell); + _canvasDirty = true; + } + } + } + + //擦除笔刷 + private void EraseBrush() + { + var brushRoot = UiNode.L_CombinationRoot.L_BrushRoot.Instance; + foreach (var keyValuePair in _brushData) + { + var combinationCell = keyValuePair.Value; + var pos = (combinationCell.Position + brushRoot.Position).AsVector2I(); + if (_canvas.TryGetValue(pos, out var canvasCell)) + { + canvasCell.QueueFree(); + _canvas.Remove(pos); + _canvasDirty = true; } } } @@ -102,6 +239,19 @@ } //移除组合图块 + private void OnRemoveCombinationCell(object obj) + { + if (obj is Vector2I cell) + { + if (_brushData.TryGetValue(cell, out var cellData)) + { + cellData.QueueFree(); + _brushData.Remove(cell); + } + } + } + + //移除所有组合图块 private void OnClearCombinationCell(object obj) { foreach (var keyValuePair in _brushData)