diff --git a/DungeonShooting_Godot/src/framework/common/Utils.cs b/DungeonShooting_Godot/src/framework/common/Utils.cs index 563fe14..7dd0903 100644 --- a/DungeonShooting_Godot/src/framework/common/Utils.cs +++ b/DungeonShooting_Godot/src/framework/common/Utils.cs @@ -1,4 +1,6 @@ +using System.Collections.Generic; using Godot; +using UI.TileSetEditorCombination; /// /// 常用函数工具类 @@ -352,4 +354,59 @@ { return ReflectByNormal(Vector2.FromAngle(rotation), normal).Angle(); } + + /// + /// 计算TileSet Cell所占用的区域 + /// + public static Rect2I CalcTileRect(IEnumerable cells) + { + //单位: 像素 + var canvasXStart = int.MaxValue; + var canvasYStart = int.MaxValue; + var canvasXEnd = int.MinValue; + var canvasYEnd = int.MinValue; + + foreach (var pos in cells) + { + 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); + } + + return new Rect2I( + canvasXStart, + canvasYStart, + canvasXEnd - canvasXStart, + canvasYEnd - canvasYStart + ); + } + + /// + /// 计算TileSet Cell所占用的区域 + /// + public static Rect2I CalcTileRect(IEnumerable cells) + { + //单位: 像素 + var canvasXStart = int.MaxValue; + var canvasYStart = int.MaxValue; + var canvasXEnd = int.MinValue; + var canvasYEnd = int.MinValue; + + foreach (var pos in cells) + { + canvasXStart = (int)Mathf.Min(pos.X, canvasXStart); + canvasYStart = (int)Mathf.Min(pos.Y, canvasYStart); + canvasXEnd = (int)Mathf.Max(pos.X + GameConfig.TileCellSize, canvasXEnd); + canvasYEnd = (int)Mathf.Max(pos.Y + GameConfig.TileCellSize, canvasYEnd); + } + + return new Rect2I( + canvasXStart, + canvasYStart, + canvasXEnd - canvasXStart, + canvasYEnd - canvasYStart + ); + } + } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/framework/map/tileSet/TileCombinationInfo.cs b/DungeonShooting_Godot/src/framework/map/tileSet/TileCombinationInfo.cs index 0f2f48a..ae1f83e 100644 --- a/DungeonShooting_Godot/src/framework/map/tileSet/TileCombinationInfo.cs +++ b/DungeonShooting_Godot/src/framework/map/tileSet/TileCombinationInfo.cs @@ -1,8 +1,29 @@ +using System.Text.Json.Serialization; + /// /// 组合图块数据 /// public class TileCombinationInfo { - + /// + /// 组合唯一Id + /// + [JsonInclude] + public string Id; + /// + /// 组合名称 + /// + [JsonInclude] + public string Name; + /// + /// 组合图块数据, 在纹理中的坐标, 单位: 像素 + /// + [JsonInclude] + public SerializeVector2[] Cells; + /// + /// 组合图块数据, 显示位置, 单位: 像素 + /// + [JsonInclude] + public SerializeVector2[] Positions; } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/framework/ui/grid/UiGrid.cs b/DungeonShooting_Godot/src/framework/ui/grid/UiGrid.cs index 047bae6..5ab54e2 100644 --- a/DungeonShooting_Godot/src/framework/ui/grid/UiGrid.cs +++ b/DungeonShooting_Godot/src/framework/ui/grid/UiGrid.cs @@ -256,6 +256,17 @@ return null; } + + /// + /// 遍历所有 Cell + /// + public void ForEach(Action> callback) + { + foreach (var uiCell in _cellList) + { + callback(uiCell); + } + } /// /// 设置当前网格组件中的所有 Cell 数据, 性能较低 diff --git a/DungeonShooting_Godot/src/game/data/ImportCombinationData.cs b/DungeonShooting_Godot/src/game/data/ImportCombinationData.cs index 4a631c5..ff8c6e7 100644 --- a/DungeonShooting_Godot/src/game/data/ImportCombinationData.cs +++ b/DungeonShooting_Godot/src/game/data/ImportCombinationData.cs @@ -1,4 +1,5 @@ +using System.Collections.Generic; using Godot; /// @@ -6,6 +7,41 @@ /// public class ImportCombinationData { - public string Name { get; set; } - public Texture2D PreviewTexture { get; set; } + /// + /// 预览图 + /// + public ImageTexture PreviewTexture { get; set; } + /// + /// 组合图块数据 + /// + public TileCombinationInfo CombinationInfo { get; set; } + + public ImportCombinationData(ImageTexture previewTexture, TileCombinationInfo combinationInfo) + { + PreviewTexture = previewTexture; + CombinationInfo = combinationInfo; + } + + public void UpdatePreviewTexture(Image src) + { + using (var image = GetPreviewTexture(src, CombinationInfo.Cells, CombinationInfo.Positions)) + { + PreviewTexture.SetImage(image); + } + } + + public static Image GetPreviewTexture(Image src, SerializeVector2[] cells, SerializeVector2[] positions) + { + var rect = Utils.CalcTileRect(positions); + var rectSize = rect.Size; + var image = Image.Create(rectSize.X + 4, rectSize.Y + 4, false, Image.Format.Rgba8); + image.Fill(Colors.Gray); + for (var i = 0; i < cells.Length; i++) + { + var cell = cells[i]; + var pos = positions[i]; + image.BlendRect(src, new Rect2I(cell.AsVector2I(), GameConfig.TileCellSizeVector2I), pos.AsVector2I() + new Vector2I(2, 2)); + } + return image; + } } \ 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 a15d60e..e9eac87 100644 --- a/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/leftTop/TileEditCombination.cs +++ b/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/leftTop/TileEditCombination.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using Godot; namespace UI.TileSetEditorCombination; @@ -64,26 +65,12 @@ _canvasDirty = false; if (_canvas.Count > 0) { - //单位: 像素 - 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); - } - + var rect = Utils.CalcTileRect(_canvas.Keys); UiNode.L_CombinationRoot.L_RectBrush.Instance.SetDrawRect( - canvasXStart, - canvasYStart, - canvasXEnd - canvasXStart, - canvasYEnd - canvasYStart + rect.Position.X, + rect.Position.Y, + rect.Size.X, + rect.Size.Y ); } else @@ -176,18 +163,37 @@ EditorWindowManager.ShowTips("警告", "导入一格大小的组合图块没有任何意义!"); return; } + + var originPos = UiNode.L_CombinationRoot.L_RectBrush.Instance.GetOriginPosition(); + var tempCell = new List(); + var tempPos = new List(); + foreach (var keyValuePair in _canvas) + { + var pos = keyValuePair.Key; + var srcRect = keyValuePair.Value.RegionRect; + tempCell.Add(new SerializeVector2(srcRect.Position.AsVector2I())); + tempPos.Add(new SerializeVector2(pos - originPos)); + } - var texture = GetCombinationPreviewTexture(); + var cells = tempCell.ToArray(); + var positions = tempPos.ToArray(); + + var src = UiNode.UiPanel.EditorPanel.TextureImage; + var image = ImportCombinationData.GetPreviewTexture(src, cells, positions); + var texture = ImageTexture.CreateFromImage(image); EditorWindowManager.ShowImportCombination("组合名称", texture, (name) => { + var combinationInfo = new TileCombinationInfo(); + combinationInfo.Id = "1"; + combinationInfo.Name = name; + combinationInfo.Cells = cells; + combinationInfo.Positions = positions; + var data = new ImportCombinationData(texture, combinationInfo); //派发导入组合图块事件 - EventManager.EmitEvent(EventEnum.OnImportCombination, new ImportCombinationData() - { - Name = name, - PreviewTexture = texture - }); + EventManager.EmitEvent(EventEnum.OnImportCombination, data); }, () => //取消添加组件 { + image.Dispose(); texture.Dispose(); }); } @@ -281,25 +287,4 @@ _xEnd = int.MinValue; _yEnd = int.MinValue; } - - /// - /// 获取组合的预览图 - /// - private Texture2D GetCombinationPreviewTexture() - { - var rectBrush = UiNode.L_CombinationRoot.L_RectBrush.Instance; - var src = UiNode.UiPanel.EditorPanel.TextureImage; - var rectSize = rectBrush.GetRectSize(); - var originPos = rectBrush.GetOriginPosition(); - var image = Image.Create(rectSize.X + 4, rectSize.Y + 4, false, Image.Format.Rgba8); - image.Fill(Colors.Gray); - foreach (var keyValuePair in _canvas) - { - var pos = keyValuePair.Key; - var srcRect = keyValuePair.Value.RegionRect; - image.BlendRect(src, new Rect2I(srcRect.Position.AsVector2I(), srcRect.Size.AsVector2I()), - pos - originPos + new Vector2I(2, 2)); - } - return ImageTexture.CreateFromImage(image); - } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/right/TileCell.cs b/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/right/TileCell.cs index dd1314c..98b9a87 100644 --- a/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/right/TileCell.cs +++ b/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/right/TileCell.cs @@ -11,7 +11,7 @@ public override void OnSetData(ImportCombinationData data) { - CellNode.L_CellName.Instance.Text = data.Name; + CellNode.L_CellName.Instance.Text = data.CombinationInfo.Name; CellNode.L_PreviewImage.Instance.Texture = data.PreviewTexture; } diff --git a/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/right/TileSelected.cs b/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/right/TileSelected.cs index e2d1270..a6683a7 100644 --- a/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/right/TileSelected.cs +++ b/DungeonShooting_Godot/src/game/ui/tileSetEditorCombination/right/TileSelected.cs @@ -58,6 +58,11 @@ /// public void OnChangeTileSetTexture() { - _grid.RemoveAll(); + //_grid.RemoveAll(); + //刷新预览图 + _grid.ForEach(cell => + { + cell.Data.UpdatePreviewTexture(_rightBg.UiPanel.EditorPanel.TextureImage); + }); } } \ No newline at end of file