diff --git a/DungeonShooting_Godot/prefab/ui/TileSetEditorCombination.tscn b/DungeonShooting_Godot/prefab/ui/TileSetEditorCombination.tscn index 383b76c..c4f6702 100644 --- a/DungeonShooting_Godot/prefab/ui/TileSetEditorCombination.tscn +++ b/DungeonShooting_Godot/prefab/ui/TileSetEditorCombination.tscn @@ -89,6 +89,8 @@ scale = Vector2(3, 3) mouse_filter = 2 +[node name="BrushRoot" type="Node2D" parent="HSplitContainer/VSplitContainer/LeftTop/MarginContainer/LeftTopBg/CombinationRoot"] + [node name="Grid" type="ColorRect" parent="HSplitContainer/VSplitContainer/LeftTop/MarginContainer/LeftTopBg"] material = SubResource("ShaderMaterial_df7va") layout_mode = 1 diff --git a/DungeonShooting_Godot/src/framework/common/Utils.cs b/DungeonShooting_Godot/src/framework/common/Utils.cs index b102450..563fe14 100644 --- a/DungeonShooting_Godot/src/framework/common/Utils.cs +++ b/DungeonShooting_Godot/src/framework/common/Utils.cs @@ -96,7 +96,7 @@ /// /// 原数值 /// 吸附步长 - public static float Adsorption(float value, float step) + public static float Adsorption(this float value, float step) { var f = Mathf.Round(value / step); return f * step; @@ -107,7 +107,7 @@ /// /// 原数值 /// 吸附步长 - public static int Adsorption(float value, int step) + public static int Adsorption(this float value, int step) { var f = Mathf.RoundToInt(value / step); return f * step; @@ -118,7 +118,7 @@ /// /// 原数值 /// 吸附步长 - public static Vector2 Adsorption(Vector2 value, Vector2 step) + public static Vector2 Adsorption(this Vector2 value, Vector2 step) { var x = Mathf.Round(value.X / step.X); var y = Mathf.Round(value.Y / step.Y); @@ -130,12 +130,58 @@ /// /// 原数值 /// 吸附步长 - public static Vector2I Adsorption(Vector2 value, Vector2I step) + public static Vector2I Adsorption(this Vector2 value, Vector2I step) { var x = Mathf.RoundToInt(value.X / step.X); var y = Mathf.RoundToInt(value.Y / step.Y); return new Vector2I(x * step.X, y * step.Y); } + + /// + /// 根据步长按照 Floor() 函数吸附值 + /// + /// 原数值 + /// 吸附步长 + public static float FloorAdsorption(this float value, float step) + { + var f = Mathf.Floor(value / step); + return f * step; + } + + /// + /// 根据步长按照 Floor() 函数吸附值 + /// + /// 原数值 + /// 吸附步长 + public static int FloorAdsorption(this float value, int step) + { + var f = Mathf.FloorToInt(value / step); + return f * step; + } + + /// + /// 根据步长按照 Floor() 函数吸附值 + /// + /// 原数值 + /// 吸附步长 + public static Vector2 FloorAdsorption(this Vector2 value, Vector2 step) + { + var x = Mathf.Floor(value.X / step.X); + var y = Mathf.Floor(value.Y / step.Y); + return new Vector2(x * step.X, y * step.Y); + } + + /// + /// 根据步长按照 Floor() 函数吸附值 + /// + /// 原数值 + /// 吸附步长 + public static Vector2I FloorAdsorption(this Vector2 value, Vector2I step) + { + var x = Mathf.FloorToInt(value.X / step.X); + var y = Mathf.FloorToInt(value.Y / step.Y); + return new Vector2I(x * step.X, y * step.Y); + } /// /// 字符串首字母小写 diff --git a/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/TileSetEditorCombination.cs b/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/TileSetEditorCombination.cs index 9056d5b..3e5b17b 100644 --- a/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/TileSetEditorCombination.cs +++ b/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/TileSetEditorCombination.cs @@ -32,10 +32,32 @@ } /// + /// 类型: , 路径: TileSetEditorCombination.HSplitContainer.VSplitContainer.LeftTop.MarginContainer.LeftTopBg.CombinationRoot.BrushRoot + /// + public class BrushRoot : UiNode + { + public BrushRoot(TileSetEditorCombinationPanel uiPanel, Godot.Node2D node) : base(uiPanel, node) { } + public override BrushRoot Clone() => new (UiPanel, (Godot.Node2D)Instance.Duplicate()); + } + + /// /// 类型: , 路径: TileSetEditorCombination.HSplitContainer.VSplitContainer.LeftTop.MarginContainer.LeftTopBg.CombinationRoot /// public class CombinationRoot : UiNode { + /// + /// 使用 Instance 属性获取当前节点实例对象, 节点类型: , 节点路径: TileSetEditorCombination.HSplitContainer.VSplitContainer.LeftTop.MarginContainer.LeftTopBg.BrushRoot + /// + public BrushRoot L_BrushRoot + { + get + { + if (_L_BrushRoot == null) _L_BrushRoot = new BrushRoot(UiPanel, Instance.GetNode("BrushRoot")); + return _L_BrushRoot; + } + } + private BrushRoot _L_BrushRoot; + public CombinationRoot(TileSetEditorCombinationPanel uiPanel, Godot.Control node) : base(uiPanel, node) { } public override CombinationRoot Clone() => new (UiPanel, (Godot.Control)Instance.Duplicate()); } @@ -548,6 +570,11 @@ /// + /// 场景中唯一名称的节点, 节点类型: , 节点路径: 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 /// public CombinationRoot S_CombinationRoot => L_HSplitContainer.L_VSplitContainer.L_LeftTop.L_MarginContainer.L_LeftTopBg.L_CombinationRoot; diff --git a/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/leftTop/CombinationCell.cs b/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/leftTop/CombinationCell.cs new file mode 100644 index 0000000..9bb9880 --- /dev/null +++ b/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/leftTop/CombinationCell.cs @@ -0,0 +1,21 @@ +using Godot; + +namespace UI.TileSetEditorCombination; + +public partial class CombinationCell : Sprite2D +{ + public override void _Ready() + { + Centered = false; + RegionEnabled = true; + } + + /// + /// 初始化数据, 设置纹理和显示的区域 + /// + public void InitData(Texture2D texture, Vector2I texturePos) + { + Texture = texture; + RegionRect = new Rect2(texturePos * GameConfig.TileCellSize, GameConfig.TileCellSizeVector2I); + } +} \ 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 7b7cc8e..053a89d 100644 --- a/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/leftTop/TileEditCombination.cs +++ b/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/leftTop/TileEditCombination.cs @@ -5,7 +5,13 @@ public partial class TileEditCombination : GridBg { - private Dictionary _brushData; + //kay: 代表原图中的坐标 + private Dictionary _brushData = new Dictionary(); + private Vector2I _brushOffset = Vector2I.Zero; + private int _xStart = 0; + private int _yStart = 0; + private int _xEnd = 0; + private int _yEnd = 0; public override void SetUiNode(IUiNode uiNode) { @@ -17,21 +23,44 @@ UiNode.UiPanel.AddEventListener(EventEnum.OnClearContainerCell, OnClearContainerCell); } + public override void _Process(double delta) + { + if (!UiNode.UiPanel.IsOpen) + { + return; + } + + UiNode.L_CombinationRoot.L_BrushRoot.Instance.Position = UiNode.L_CombinationRoot.Instance + .GetLocalMousePosition().FloorAdsorption(GameConfig.TileCellSizeVector2I); + } + private void OnSelectContainerCell(object obj) { - if (obj is Vector2I cell) + if (obj is Vector2I cell && !_brushData.ContainsKey(cell)) { - var src = UiNode.UiPanel.EditorPanel.TextureImage; - var image = Image.Create(GameConfig.TileCellSize, GameConfig.TileCellSize, false, Image.Format.Rgba8); - image.BlitRect(src, - new Rect2I(cell * GameConfig.TileCellSizeVector2I, GameConfig.TileCellSize, GameConfig.TileCellSize), - Vector2I.Zero); - //UiNode.L_CombinationRoot.L_TextureRect.Instance.Texture = ImageTexture.CreateFromImage(image);; + var cellData = new CombinationCell(); + var pos = cell * GameConfig.TileCellSize + _brushOffset; + cellData.Position = pos; + cellData.InitData(UiNode.UiPanel.EditorPanel.Texture, cell); + UiNode.L_CombinationRoot.L_BrushRoot.AddChild(cellData); + _brushData.Add(cell, cellData); + + //计算起始点和终点 + //if (pos.X < _xStart || pos.X > _xEnd || pos.) } } private void OnClearContainerCell(object obj) { - + foreach (var keyValuePair in _brushData) + { + keyValuePair.Value.QueueFree(); + } + _brushData.Clear(); + _brushOffset = Vector2I.Zero; + _xStart = 0; + _yStart = 0; + _xEnd = 0; + _yEnd = 0; } } \ No newline at end of file