Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / ui / tileSetEditorCombination / leftTop / TileEditCombination.cs
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Godot;
  5.  
  6. namespace UI.TileSetEditorCombination;
  7.  
  8. public partial class TileEditCombination : EditorGridBg<TileSetEditorCombination.LeftTopBg>
  9. {
  10. // ------------------------------- 笔刷相关 -------------------------------
  11. //笔刷数据, kay: 代表原图中的坐标, 单位: 格
  12. private Dictionary<Vector2I, CombinationCell> _brushData = new Dictionary<Vector2I, CombinationCell>();
  13.  
  14. //笔刷偏移, 单位: 像素
  15. private Vector2I _brushOffset = Vector2I.Zero;
  16. //上一帧笔刷位置
  17. private Vector2 _brushPrevPos = Vector2.Zero;
  18. private bool _initBrush = false;
  19. private bool _drawBrushFlag = false;
  20. private int _xStart = int.MaxValue;
  21. private int _yStart = int.MaxValue;
  22. private int _xEnd = int.MinValue;
  23. private int _yEnd = int.MinValue;
  24. // -----------------------------------------------------------------------
  25. // ------------------------------- 画布相关 -------------------------------
  26. //画布数据, kay: 绘制坐标, 单位: 像素
  27. private Dictionary<Vector2I, CombinationCell> _canvas = new Dictionary<Vector2I, CombinationCell>();
  28. //画布数据是否需要更新
  29. private bool _canvasDirty = false;
  30. // -----------------------------------------------------------------------
  31.  
  32. public override void SetUiNode(IUiNode uiNode)
  33. {
  34. base.SetUiNode(uiNode);
  35. UiNode.L_CombinationRoot.L_RectBrush.Instance.Root = UiNode.L_CombinationRoot.Instance;
  36. InitNode(UiNode.L_CombinationRoot.Instance, UiNode.L_Grid.Instance);
  37.  
  38. UiNode.UiPanel.AddEventListener(EventEnum.OnSelectCombinationCell, OnSelectCombinationCell);
  39. UiNode.UiPanel.AddEventListener(EventEnum.OnRemoveCombinationCell, OnRemoveCombinationCell);
  40. UiNode.UiPanel.AddEventListener(EventEnum.OnClearCombinationCell, OnClearCombinationCell);
  41.  
  42. //删除按钮点击事件
  43. UiNode.L_DeleteBtn.Instance.Pressed += ClearAllCell;
  44. //聚焦按钮点击事件
  45. UiNode.L_FocusBtn.Instance.Pressed += OnFocusClick;
  46. //导入组合按钮点击事件
  47. UiNode.L_ImportBtn.Instance.Pressed += OnImportClick;
  48. }
  49.  
  50. public override void _Process(double delta)
  51. {
  52. if (!UiNode.UiPanel.IsOpen)
  53. {
  54. return;
  55. }
  56.  
  57. var brushRoot = UiNode.L_CombinationRoot.L_BrushRoot.Instance;
  58. var combinationRoot = UiNode.L_CombinationRoot.Instance;
  59. brushRoot.Position = combinationRoot.GetLocalMousePosition().FloorAdsorption(GameConfig.TileCellSizeVector2I) + _brushOffset;
  60.  
  61. if (_canvasDirty) //更新画布范围
  62. {
  63. _canvasDirty = false;
  64. if (_canvas.Count > 0)
  65. {
  66. var rect = Utils.CalcTileRect(_canvas.Keys);
  67. UiNode.L_CombinationRoot.L_RectBrush.Instance.SetDrawRect(
  68. rect.Position.X,
  69. rect.Position.Y,
  70. rect.Size.X,
  71. rect.Size.Y
  72. );
  73. }
  74. else
  75. {
  76. UiNode.L_CombinationRoot.L_RectBrush.Instance.ClearDrawRect();
  77. }
  78. }
  79. }
  80.  
  81. public override void _GuiInput(InputEvent @event)
  82. {
  83. base._GuiInput(@event);
  84. if (@event is InputEventMouse)
  85. {
  86. AcceptEvent();
  87. var brushRoot = UiNode.L_CombinationRoot.L_BrushRoot.Instance;
  88. var newPos = brushRoot.Position;
  89. sbyte flag = 0;
  90. //左键按下开始绘制
  91. if (_initBrush)
  92. {
  93. if (Input.IsMouseButtonPressed(MouseButton.Left)) //绘制
  94. {
  95. flag = 1;
  96. if (_brushPrevPos != newPos || !_drawBrushFlag)
  97. {
  98. _drawBrushFlag = true;
  99. _brushPrevPos = newPos;
  100. DrawBrush();
  101. }
  102. }
  103. else if (Input.IsMouseButtonPressed(MouseButton.Right)) //擦除
  104. {
  105. flag = -1;
  106. brushRoot.Modulate = new Color(1, 1, 1, 0.3f);
  107. if (_brushPrevPos != newPos || !_drawBrushFlag)
  108. {
  109. _drawBrushFlag = true;
  110. _brushPrevPos = newPos;
  111. EraseBrush();
  112. }
  113. }
  114. }
  115.  
  116. if (flag != 0)
  117. {
  118. _drawBrushFlag = false;
  119. }
  120.  
  121. if (flag != -1)
  122. {
  123. brushRoot.Modulate = Colors.White;
  124. }
  125. }
  126. }
  127.  
  128. /// <summary>
  129. /// 删除已经绘制的图块
  130. /// </summary>
  131. public void ClearAllCell()
  132. {
  133. foreach (var keyValuePair in _canvas)
  134. {
  135. keyValuePair.Value.QueueFree();
  136. }
  137.  
  138. _canvas.Clear();
  139. _canvasDirty = true;
  140. }
  141. //点击聚焦按钮
  142. private void OnFocusClick()
  143. {
  144. Utils.DoFocusNode(ContainerRoot, Size, UiNode.L_CombinationRoot.L_RectBrush.Instance.GetCenterPosition() * 2);
  145. RefreshGridTrans();
  146. }
  147. //导入按钮点击
  148. private void OnImportClick()
  149. {
  150. var size = UiNode.L_CombinationRoot.L_RectBrush.Instance.GetRectSize();
  151. if (UiNode.UiPanel.EditorPanel.TextureImage == null)
  152. {
  153. EditorWindowManager.ShowTips("警告", "未选择纹理资源!");
  154. return;
  155. }
  156. else if (size == Vector2.Zero)
  157. {
  158. EditorWindowManager.ShowTips("警告", "请先绘制组合图块!");
  159. return;
  160. }
  161. else if (size == GameConfig.TileCellSizeVector2I)
  162. {
  163. EditorWindowManager.ShowTips("警告", "导入一格大小的组合图块没有任何意义!");
  164. return;
  165. }
  166. var originPos = UiNode.L_CombinationRoot.L_RectBrush.Instance.GetOriginPosition();
  167. var tempCell = new List<SerializeVector2>();
  168. var tempPos = new List<SerializeVector2>();
  169. foreach (var keyValuePair in _canvas)
  170. {
  171. var pos = keyValuePair.Key;
  172. var srcRect = keyValuePair.Value.RegionRect;
  173. tempCell.Add(new SerializeVector2(srcRect.Position.AsVector2I()));
  174. tempPos.Add(new SerializeVector2(pos - originPos));
  175. }
  176.  
  177. var cells = tempCell.ToArray();
  178. var positions = tempPos.ToArray();
  179.  
  180. var tileSetEditorPanel = UiNode.UiPanel.EditorPanel;
  181. var color = tileSetEditorPanel.BgColor;
  182. var src = tileSetEditorPanel.TextureImage;
  183. var image = ImportCombinationData.GetPreviewTexture(src, cells, positions);
  184. var texture = ImageTexture.CreateFromImage(image);
  185. EditorWindowManager.ShowImportCombination("组合", color, texture, (name) =>
  186. {
  187. var combinationInfo = new TileCombinationInfo();
  188. combinationInfo.Id = DateTime.UtcNow.Ticks.ToString();
  189. combinationInfo.Name = name;
  190. combinationInfo.Cells = cells;
  191. combinationInfo.Positions = positions;
  192. var data = new ImportCombinationData(texture, combinationInfo);
  193. //派发导入组合图块事件
  194. EventManager.EmitEvent(EventEnum.OnImportCombination, data);
  195. }, () => //取消添加组件
  196. {
  197. image.Dispose();
  198. texture.Dispose();
  199. });
  200. }
  201. //绘制笔刷
  202. private void DrawBrush()
  203. {
  204. var brushRoot = UiNode.L_CombinationRoot.L_BrushRoot.Instance;
  205. foreach (var keyValuePair in _brushData)
  206. {
  207. var combinationCell = keyValuePair.Value;
  208. var pos = (combinationCell.Position + brushRoot.Position).AsVector2I();
  209. if (_canvas.TryGetValue(pos, out var canvasCell))
  210. {
  211. canvasCell.CloneFrom(combinationCell);
  212. }
  213. else
  214. {
  215. canvasCell = (CombinationCell)combinationCell.Duplicate();
  216. canvasCell.Position = pos;
  217. UiNode.L_CombinationRoot.L_CanvasRoot.AddChild(canvasCell);
  218. _canvas.Add(pos, canvasCell);
  219. _canvasDirty = true;
  220. }
  221. }
  222. }
  223.  
  224. //擦除操作
  225. private void EraseBrush()
  226. {
  227. var brushRoot = UiNode.L_CombinationRoot.L_BrushRoot.Instance;
  228. foreach (var keyValuePair in _brushData)
  229. {
  230. var combinationCell = keyValuePair.Value;
  231. var pos = (combinationCell.Position + brushRoot.Position).AsVector2I();
  232. if (_canvas.TryGetValue(pos, out var canvasCell))
  233. {
  234. canvasCell.QueueFree();
  235. _canvas.Remove(pos);
  236. _canvasDirty = true;
  237. }
  238. }
  239. }
  240.  
  241. //选中组合的图块
  242. private void OnSelectCombinationCell(object obj)
  243. {
  244. if (obj is Vector2I cell && !_brushData.ContainsKey(cell))
  245. {
  246. _initBrush = true;
  247. var cellData = new CombinationCell();
  248. cellData.Position = cell * GameConfig.TileCellSize;
  249. cellData.InitData(UiNode.UiPanel.EditorPanel.Texture, cell);
  250. UiNode.L_CombinationRoot.L_BrushRoot.AddChild(cellData);
  251. _brushData.Add(cell, cellData);
  252. //计算起始点和终点
  253. _xStart = Mathf.Min(cell.X, _xStart);
  254. _yStart = Mathf.Min(cell.Y, _yStart);
  255. _xEnd = Mathf.Max(cell.X, _xEnd);
  256. _yEnd = Mathf.Max(cell.Y, _yEnd);
  257. _brushOffset = new Vector2I(-(_xStart + (_xEnd - _xStart) / 2), -(_yStart + (_yEnd - _yStart) / 2)) * GameConfig.TileCellSize;
  258. }
  259. }
  260. //移除组合图块
  261. private void OnRemoveCombinationCell(object obj)
  262. {
  263. if (obj is Vector2I cell)
  264. {
  265. if (_brushData.TryGetValue(cell, out var cellData))
  266. {
  267. cellData.QueueFree();
  268. _brushData.Remove(cell);
  269. }
  270. }
  271. }
  272.  
  273. //移除所有组合图块
  274. private void OnClearCombinationCell(object obj)
  275. {
  276. foreach (var keyValuePair in _brushData)
  277. {
  278. keyValuePair.Value.QueueFree();
  279. }
  280. _brushData.Clear();
  281. _initBrush = false;
  282. _brushOffset = Vector2I.Zero;
  283. _xStart = int.MaxValue;
  284. _yStart = int.MaxValue;
  285. _xEnd = int.MinValue;
  286. _yEnd = int.MinValue;
  287. }
  288. }