diff --git a/DungeonShooting_Godot/prefab/ui/TileSetEditorSegment.tscn b/DungeonShooting_Godot/prefab/ui/TileSetEditorSegment.tscn index 985a78f..b829d83 100644 --- a/DungeonShooting_Godot/prefab/ui/TileSetEditorSegment.tscn +++ b/DungeonShooting_Godot/prefab/ui/TileSetEditorSegment.tscn @@ -1,6 +1,17 @@ -[gd_scene load_steps=2 format=3 uid="uid://daias2tkvj20c"] +[gd_scene load_steps=6 format=3 uid="uid://daias2tkvj20c"] [ext_resource type="Script" path="res://src/game/ui/tileSetEditorSegment/TileSetEditorSegmentPanel.cs" id="1_to1lc"] +[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/tileSetEditorSegment/TileSetEditorSegmentLeftBg.cs" id="3_dnmr6"] + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_u3xqn"] +shader = ExtResource("2_t1p2n") +shader_parameter/color = Color(0.529412, 0.529412, 0.529412, 0.0431373) +shader_parameter/size = Vector2(1334, 1076) +shader_parameter/line_width = 2 +shader_parameter/offset = Vector2(0, 0) +shader_parameter/grid_size = 16.0 [node name="TileSetEditorSegment" type="Control"] layout_mode = 3 @@ -37,21 +48,21 @@ [node name="LeftBg" type="ColorRect" parent="HSplitContainer/Left/MarginContainer"] layout_mode = 2 color = Color(0.203922, 0.203922, 0.203922, 1) +script = ExtResource("3_dnmr6") -[node name="TileTexture" type="TextureRect" parent="HSplitContainer/Left/MarginContainer/LeftBg"] +[node name="TileTexture" type="Sprite2D" parent="HSplitContainer/Left/MarginContainer/LeftBg"] +position = Vector2(547, 493) +texture = ExtResource("2_wr143") + +[node name="Grid" type="ColorRect" parent="HSplitContainer/Left/MarginContainer/LeftBg"] +material = SubResource("ShaderMaterial_u3xqn") layout_mode = 1 -anchors_preset = 8 -anchor_left = 0.5 -anchor_top = 0.5 -anchor_right = 0.5 -anchor_bottom = 0.5 -offset_left = -667.0 -offset_top = -538.0 -offset_right = 667.0 -offset_bottom = 538.0 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 -size_flags_horizontal = 4 +mouse_filter = 2 [node name="Right" type="Panel" parent="HSplitContainer"] layout_mode = 2 diff --git a/DungeonShooting_Godot/resource/material/Grid.gdshader b/DungeonShooting_Godot/resource/material/Grid.gdshader new file mode 100644 index 0000000..571251f --- /dev/null +++ b/DungeonShooting_Godot/resource/material/Grid.gdshader @@ -0,0 +1,17 @@ +shader_type canvas_item; +render_mode blend_mix; + +uniform vec4 color : source_color = vec4(1.0, 1.0, 1.0, 1.0); +uniform vec2 size = vec2(1280.0, 720.0); +uniform int line_width = 1; +uniform vec2 offset = vec2(0.0, 0.0); +uniform float grid_size = 16.0; + +void fragment() { + vec2 uv = ((offset - vec2(float(line_width)) * 0.5f) / size) + UV; + vec2 r = mod(size * uv, vec2(grid_size)); + vec2 lines = step(1.0 - float(line_width) / grid_size, r / vec2(grid_size)); + float alpha = dot(lines, vec2(1.0, 1.0)); + COLOR = color; + COLOR.a *= alpha; +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/ShaderParamNames.cs b/DungeonShooting_Godot/src/game/ShaderParamNames.cs index e09a4c7..9c00cc1 100644 --- a/DungeonShooting_Godot/src/game/ShaderParamNames.cs +++ b/DungeonShooting_Godot/src/game/ShaderParamNames.cs @@ -18,6 +18,22 @@ /// 是否显示轮廓 /// public static readonly StringName ShowOutline = "show_outline"; + /// + /// 纹理大小 + /// + public static readonly StringName Size = "size"; + /// + /// 线段宽度 + /// + public static readonly StringName LineWidth = "line_width"; + /// + /// 偏移 + /// + public static readonly StringName Offset = "offset"; + /// + /// 网格大小 + /// + public static readonly StringName GridSize = "grid_size"; /// /// 快速设置一个材质的 shader 材质参数 diff --git a/DungeonShooting_Godot/src/game/manager/DragUiManager.cs b/DungeonShooting_Godot/src/game/manager/DragUiManager.cs index cfb206a..e6f9a0f 100644 --- a/DungeonShooting_Godot/src/game/manager/DragUiManager.cs +++ b/DungeonShooting_Godot/src/game/manager/DragUiManager.cs @@ -8,6 +8,9 @@ private static readonly List _removeList = new List(); private static readonly List _addList = new List(); + /// + /// 绑定拖拽事件 + /// public static DragBinder BindDrag(Control control, Action callback) { var binder = new DragBinder(); @@ -19,6 +22,9 @@ return binder; } + /// + /// 解绑拖拽事件 + /// public static void UnBindDrag(DragBinder binder) { if (!_removeList.Contains(binder)) diff --git a/DungeonShooting_Godot/src/game/ui/tileSetEditor/TileSetEditorPanel.cs b/DungeonShooting_Godot/src/game/ui/tileSetEditor/TileSetEditorPanel.cs index ee046a1..a9b0ead 100644 --- a/DungeonShooting_Godot/src/game/ui/tileSetEditor/TileSetEditorPanel.cs +++ b/DungeonShooting_Godot/src/game/ui/tileSetEditor/TileSetEditorPanel.cs @@ -12,7 +12,7 @@ /// /// 纹理 /// - public Texture Texture; + public Texture2D Texture; /// /// 背景颜色 diff --git a/DungeonShooting_Godot/src/game/ui/tileSetEditorImport/TileSetEditorImportPanel.cs b/DungeonShooting_Godot/src/game/ui/tileSetEditorImport/TileSetEditorImportPanel.cs index c0a7961..3e93a36 100644 --- a/DungeonShooting_Godot/src/game/ui/tileSetEditorImport/TileSetEditorImportPanel.cs +++ b/DungeonShooting_Godot/src/game/ui/tileSetEditorImport/TileSetEditorImportPanel.cs @@ -43,17 +43,23 @@ { if (mouseButton.ButtonIndex == MouseButton.WheelDown) { - //缩小 - var scale = textureRect.Scale; - scale = new Vector2(Mathf.Max(0.1f, scale.X / 1.1f), Mathf.Max(0.1f, scale.Y / 1.1f)); - textureRect.Scale = scale; + if (GetGlobalRect().HasPoint(mouseButton.GlobalPosition)) + { + //缩小 + var scale = textureRect.Scale; + scale = new Vector2(Mathf.Max(0.1f, scale.X / 1.1f), Mathf.Max(0.1f, scale.Y / 1.1f)); + textureRect.Scale = scale; + } } else if (mouseButton.ButtonIndex == MouseButton.WheelUp) { - //放大 - var scale = textureRect.Scale; - scale = new Vector2(Mathf.Min(20f, scale.X * 1.1f), Mathf.Min(20f, scale.Y * 1.1f)); - textureRect.Scale = scale; + if (GetGlobalRect().HasPoint(mouseButton.GlobalPosition)) + { + //放大 + var scale = textureRect.Scale; + scale = new Vector2(Mathf.Min(20f, scale.X * 1.1f), Mathf.Min(20f, scale.Y * 1.1f)); + textureRect.Scale = scale; + } } } } diff --git a/DungeonShooting_Godot/src/game/ui/tileSetEditorSegment/TileSetEditorSegment.cs b/DungeonShooting_Godot/src/game/ui/tileSetEditorSegment/TileSetEditorSegment.cs index 5d51354..abec544 100644 --- a/DungeonShooting_Godot/src/game/ui/tileSetEditorSegment/TileSetEditorSegment.cs +++ b/DungeonShooting_Godot/src/game/ui/tileSetEditorSegment/TileSetEditorSegment.cs @@ -25,38 +25,61 @@ public sealed override void OnInitNestedUi() { + _ = L_HSplitContainer.L_Left.L_MarginContainer.L_LeftBg; } /// - /// 类型: , 路径: TileSetEditorSegment.HSplitContainer.Left.MarginContainer.LeftBg.TileTexture + /// 类型: , 路径: TileSetEditorSegment.HSplitContainer.Left.MarginContainer.LeftBg.TileTexture /// - public class TileTexture : UiNode + public class TileTexture : UiNode { - public TileTexture(TileSetEditorSegmentPanel uiPanel, Godot.TextureRect node) : base(uiPanel, node) { } - public override TileTexture Clone() => new (UiPanel, (Godot.TextureRect)Instance.Duplicate()); + public TileTexture(TileSetEditorSegmentPanel uiPanel, Godot.Sprite2D node) : base(uiPanel, node) { } + public override TileTexture Clone() => new (UiPanel, (Godot.Sprite2D)Instance.Duplicate()); } /// - /// 类型: , 路径: TileSetEditorSegment.HSplitContainer.Left.MarginContainer.LeftBg + /// 类型: , 路径: TileSetEditorSegment.HSplitContainer.Left.MarginContainer.LeftBg.Grid /// - public class LeftBg : UiNode + public class Grid : UiNode + { + public Grid(TileSetEditorSegmentPanel uiPanel, Godot.ColorRect node) : base(uiPanel, node) { } + public override Grid Clone() => new (UiPanel, (Godot.ColorRect)Instance.Duplicate()); + } + + /// + /// 类型: , 路径: TileSetEditorSegment.HSplitContainer.Left.MarginContainer.LeftBg + /// + public class LeftBg : UiNode { /// - /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: TileSetEditorSegment.HSplitContainer.Left.MarginContainer.TileTexture + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: TileSetEditorSegment.HSplitContainer.Left.MarginContainer.TileTexture /// public TileTexture L_TileTexture { get { - if (_L_TileTexture == null) _L_TileTexture = new TileTexture(UiPanel, Instance.GetNode("TileTexture")); + if (_L_TileTexture == null) _L_TileTexture = new TileTexture(UiPanel, Instance.GetNode("TileTexture")); return _L_TileTexture; } } private TileTexture _L_TileTexture; - public LeftBg(TileSetEditorSegmentPanel uiPanel, Godot.ColorRect node) : base(uiPanel, node) { } - public override LeftBg Clone() => new (UiPanel, (Godot.ColorRect)Instance.Duplicate()); + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: TileSetEditorSegment.HSplitContainer.Left.MarginContainer.Grid + /// + public Grid L_Grid + { + get + { + if (_L_Grid == null) _L_Grid = new Grid(UiPanel, Instance.GetNode("Grid")); + return _L_Grid; + } + } + private Grid _L_Grid; + + public LeftBg(TileSetEditorSegmentPanel uiPanel, UI.TileSetEditorSegment.TileSetEditorSegmentLeftBg node) : base(uiPanel, node) { } + public override LeftBg Clone() => new (UiPanel, (UI.TileSetEditorSegment.TileSetEditorSegmentLeftBg)Instance.Duplicate()); } /// @@ -65,13 +88,13 @@ public class MarginContainer : UiNode { /// - /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: TileSetEditorSegment.HSplitContainer.Left.LeftBg + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: TileSetEditorSegment.HSplitContainer.Left.LeftBg /// public LeftBg L_LeftBg { get { - if (_L_LeftBg == null) _L_LeftBg = new LeftBg(UiPanel, Instance.GetNode("LeftBg")); + if (_L_LeftBg == null) _L_LeftBg = new LeftBg(UiPanel, Instance.GetNode("LeftBg")); return _L_LeftBg; } } @@ -171,12 +194,17 @@ /// - /// 场景中唯一名称的节点, 节点类型: , 节点路径: TileSetEditorSegment.HSplitContainer.Left.MarginContainer.LeftBg.TileTexture + /// 场景中唯一名称的节点, 节点类型: , 节点路径: TileSetEditorSegment.HSplitContainer.Left.MarginContainer.LeftBg.TileTexture /// public TileTexture S_TileTexture => L_HSplitContainer.L_Left.L_MarginContainer.L_LeftBg.L_TileTexture; /// - /// 场景中唯一名称的节点, 节点类型: , 节点路径: TileSetEditorSegment.HSplitContainer.Left.MarginContainer.LeftBg + /// 场景中唯一名称的节点, 节点类型: , 节点路径: TileSetEditorSegment.HSplitContainer.Left.MarginContainer.LeftBg.Grid + /// + public Grid S_Grid => L_HSplitContainer.L_Left.L_MarginContainer.L_LeftBg.L_Grid; + + /// + /// 场景中唯一名称的节点, 节点类型: , 节点路径: TileSetEditorSegment.HSplitContainer.Left.MarginContainer.LeftBg /// public LeftBg S_LeftBg => L_HSplitContainer.L_Left.L_MarginContainer.L_LeftBg; diff --git a/DungeonShooting_Godot/src/game/ui/tileSetEditorSegment/TileSetEditorSegmentLeftBg.cs b/DungeonShooting_Godot/src/game/ui/tileSetEditorSegment/TileSetEditorSegmentLeftBg.cs new file mode 100644 index 0000000..91d8844 --- /dev/null +++ b/DungeonShooting_Godot/src/game/ui/tileSetEditorSegment/TileSetEditorSegmentLeftBg.cs @@ -0,0 +1,84 @@ +using Godot; + +namespace UI.TileSetEditorSegment; + +public partial class TileSetEditorSegmentLeftBg : ColorRect, IUiNodeScript +{ + private TileSetEditorSegment.LeftBg _leftBg; + private DragBinder _dragBinder; + + public void SetUiNode(IUiNode uiNode) + { + _leftBg = (TileSetEditorSegment.LeftBg)uiNode; + _dragBinder = DragUiManager.BindDrag(this, OnDrag); + Resized += OnLeftBgResize; + } + + public void OnDestroy() + { + _dragBinder.UnBind(); + } + + private void OnDrag(DragState state, Vector2 pos) + { + if (state == DragState.DragMove) + { + var p = _leftBg.L_TileTexture.Instance.Position + pos; + _leftBg.L_TileTexture.Instance.Position = p; + _leftBg.L_Grid.Instance.Material.SetShaderMaterialParameter(ShaderParamNames.Offset, -p); + } + } + + public override void _Input(InputEvent @event) + { + if (@event is InputEventMouseButton mouseButton) + { + if (_leftBg.UiPanel.IsOpen) + { + if (mouseButton.ButtonIndex == MouseButton.WheelDown) + { + if (GetGlobalRect().HasPoint(mouseButton.GlobalPosition)) + { + //缩小 + 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(); + } + } + else if (mouseButton.ButtonIndex == MouseButton.WheelUp) + { + if (GetGlobalRect().HasPoint(mouseButton.GlobalPosition)) + { + //放大 + 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(); + } + } + } + } + } + + /// + /// 当前Ui被显示出来时调用 + /// + public void OnShow() + { + //背景颜色 + Color = _leftBg.UiPanel.EditorPanel.BgColor; + OnLeftBgResize(); + } + + //背景宽度变化 + private void OnLeftBgResize() + { + var sprite = _leftBg.L_TileTexture.Instance; + sprite.Texture = _leftBg.UiPanel.EditorPanel.Texture; + var colorRect = _leftBg.L_Grid.Instance; + colorRect.Material.SetShaderMaterialParameter(ShaderParamNames.Size, Size); + colorRect.Material.SetShaderMaterialParameter(ShaderParamNames.GridSize, GameConfig.TileCellSize * sprite.Scale.X); + + } +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/ui/tileSetEditorSegment/TileSetEditorSegmentPanel.cs b/DungeonShooting_Godot/src/game/ui/tileSetEditorSegment/TileSetEditorSegmentPanel.cs index 2170239..03a6ff4 100644 --- a/DungeonShooting_Godot/src/game/ui/tileSetEditorSegment/TileSetEditorSegmentPanel.cs +++ b/DungeonShooting_Godot/src/game/ui/tileSetEditorSegment/TileSetEditorSegmentPanel.cs @@ -5,30 +5,31 @@ public partial class TileSetEditorSegmentPanel : TileSetEditorSegment { - - private TileSetEditorPanel _editorPanel; + /// + /// 父Ui + /// + public TileSetEditorPanel EditorPanel; public override void OnCreateUi() { - _editorPanel = (TileSetEditorPanel)ParentUi; + EditorPanel = (TileSetEditorPanel)ParentUi; } public override void OnShowUi() { - if (_editorPanel.Texture == null) + if (EditorPanel.Texture == null) { EditorWindowManager.ShowTips("警告", "请先导入纹理!", () => { - _editorPanel.TabGrid.SelectIndex = 0; + EditorPanel.TabGrid.SelectIndex = 0; }); } - S_LeftBg.Instance.Color = _editorPanel.BgColor; + S_LeftBg.Instance.OnShow(); } public override void OnDestroyUi() { } - }