Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / ui / mapEditorTools / DoorDragArea.cs
@小李xl 小李xl on 6 Jan 2024 14 KB 保存TileSet数据,开发中
  1. using System;
  2. using Godot;
  3. using UI.MapEditor;
  4.  
  5. namespace UI.MapEditorTools;
  6.  
  7. public partial class DoorDragArea : Control
  8. {
  9. /// <summary>
  10. /// 当前区域所占大小, 单位: 像素
  11. /// </summary>
  12. public Vector2 AreaSize => new Vector2(_areaSize, GameConfig.TileCellSize * 2);
  13.  
  14. //错误时的颜色
  15. private static Color _errorColor = new Color(1, 0, 0, 0.1882353F);
  16.  
  17. /// <summary>
  18. /// 朝向
  19. /// </summary>
  20. public DoorDirection Direction { get; private set; }
  21. /// <summary>
  22. /// 绑定的数据
  23. /// </summary>
  24. public DoorAreaInfo DoorAreaInfo { get; set; }
  25. /// <summary>
  26. /// 所属悬停区域
  27. /// </summary>
  28. public DoorHoverArea DoorHoverArea { get; private set; }
  29. /// <summary>
  30. /// 所属 Ui 对象
  31. /// </summary>
  32. public MapEditorToolsPanel MapEditorToolsPanel { get; private set; }
  33.  
  34. private DoorDragButton _startButton;
  35. private DoorDragButton _endButton;
  36.  
  37. private bool _mouseHover = false;
  38. private MapEditorTools.DoorToolTemplate _node;
  39. private Vector2 _startTempPos;
  40. private Vector2 _endTempPos;
  41. //默认颜色
  42. private Color _defaultColor;
  43. //区域大小, 单位: 像素
  44. private int _areaSize = GameConfig.TileCellSize * 4;
  45. //拖拽松手后是否可以提交
  46. private bool _canComment = true;
  47. //开始拖拽时的区域
  48. private Vector2I _startDragRange;
  49. //是否是拖拽模式
  50. private bool _isDragMode = false;
  51. //拖拽模式提交回调
  52. private Action<DoorDirection, int, int> _onSubmit;
  53. //拖拽模式取消时回调
  54. private Action _onCancel;
  55.  
  56. public void SetDoorDragAreaNode(MapEditorTools.DoorToolTemplate node)
  57. {
  58. _node = node;
  59. MapEditorToolsPanel = (MapEditorToolsPanel)node.UiPanel;
  60. _defaultColor = _node.L_DoorArea.Instance.Color;
  61. _startButton = _node.L_StartBtn.Instance;
  62. _endButton = _node.L_EndBtn.Instance;
  63. _startButton.DragEvent += OnStartAreaDrag;
  64. _endButton.DragEvent += OnEndAreaDrag;
  65. node.L_DoorArea.Instance.MouseEntered += OnMouseEntered;
  66. node.L_DoorArea.Instance.MouseExited += OnMouseExited;
  67. SetDoorAreaSize(GameConfig.TileCellSize * 4);
  68. }
  69.  
  70. public override void _Process(double delta)
  71. {
  72. if (_mouseHover && !DoorHoverArea.IsDrag && Input.IsMouseButtonPressed(MouseButton.Right)) //右键删除区域
  73. {
  74. MapEditorToolsPanel.RemoveDoorTool(_node);
  75. }
  76. else if (_isDragMode)
  77. {
  78. if (!Input.IsMouseButtonPressed(MouseButton.Left)) //松开了右键
  79. {
  80. _isDragMode = false;
  81. if (_canComment) //可以提交
  82. {
  83. _isDragMode = false;
  84. _onCancel = null;
  85. _startButton.EmitSignal(BaseButton.SignalName.ButtonUp);
  86. _endButton.EmitSignal(BaseButton.SignalName.ButtonUp);
  87. if (_onSubmit != null)
  88. {
  89. var doorAreaRange = GetDoorAreaRange();
  90. _onSubmit(Direction, doorAreaRange.X, doorAreaRange.Y);
  91. _onSubmit = null;
  92. }
  93. }
  94. else //不能提交
  95. {
  96. if (_onCancel != null)
  97. {
  98. _onCancel();
  99. }
  100. }
  101. }
  102. }
  103. }
  104.  
  105. /// <summary>
  106. /// 设置门区域的位置, 单位: 像素
  107. /// </summary>
  108. public void SetDoorAreaPosition(Vector2 position)
  109. {
  110. Position = position;
  111. }
  112.  
  113. /// <summary>
  114. /// 设置所属悬停区域
  115. /// </summary>
  116. public void SetDoorHoverArea(DoorHoverArea hoverArea)
  117. {
  118. DoorHoverArea = hoverArea;
  119. Direction = hoverArea.Direction;
  120. if (Direction == DoorDirection.N)
  121. {
  122. Scale = new Vector2(1, 1);
  123. RotationDegrees = 0;
  124. }
  125. else if (Direction == DoorDirection.E)
  126. {
  127. Scale = new Vector2(1, 1);
  128. RotationDegrees = 90;
  129. }
  130. else if (Direction == DoorDirection.S)
  131. {
  132. Scale = new Vector2(-1, 1);
  133. RotationDegrees = 180;
  134. }
  135. else
  136. {
  137. Scale = new Vector2(-1, 1);
  138. RotationDegrees = 270;
  139. }
  140. }
  141.  
  142. /// <summary>
  143. /// 获取门区域所占范围, 单位: 像素, 返回的 Vector2I 的 x 代表起始坐标, y 代表结束坐标
  144. /// </summary>
  145. /// <returns></returns>
  146. public Vector2I GetDoorAreaRange()
  147. {
  148. var start = (int)(_startButton.Position.X + _startButton.Size.X);
  149. return new Vector2I(start, start + _areaSize);
  150. }
  151.  
  152. /// <summary>
  153. /// 设置门区域所占范围, 单位: 像素
  154. /// </summary>
  155. public void SetDoorAreaRange(int start, int end)
  156. {
  157. var startPosition = _startButton.Position;
  158. startPosition.X = start - _startButton.Size.X;
  159. _startButton.Position = startPosition;
  160. SetDoorAreaSize(end - start);
  161. }
  162.  
  163. /// <summary>
  164. /// 设置区域起始坐标
  165. /// </summary>
  166. public void SetDoorAreaStart(int start)
  167. {
  168. var startPosition = _startButton.Position;
  169. startPosition.X = start - _startButton.Size.X;
  170. _startButton.Position = startPosition;
  171. RefreshArea();
  172. }
  173.  
  174. /// <summary>
  175. /// 设置区域大小, 单位: 像素
  176. /// </summary>
  177. public void SetDoorAreaSize(int value)
  178. {
  179. _areaSize = value;
  180. RefreshArea();
  181. //Debug.Log("size: " + GetDoorAreaRange());
  182. }
  183.  
  184. //刷新区域位置
  185. private void RefreshArea()
  186. {
  187. var colorRect = _node.L_DoorArea.Instance;
  188. var position = colorRect.Position;
  189. position.X = _startButton.Position.X + _startButton.Size.X;
  190. colorRect.Position = position;
  191. colorRect.Size = AreaSize;
  192.  
  193. var position2 = _endButton.Position;
  194. position2.X = position.X + AreaSize.X;
  195. _endButton.Position = position2;
  196. }
  197. //拖拽起始点
  198. private void OnStartAreaDrag(DragState dragState, Vector2 offset)
  199. {
  200. if (dragState == DragState.DragStart)
  201. {
  202. DoorHoverArea.IsDrag = true;
  203. _canComment = true;
  204. _startTempPos = _startButton.Position;
  205. _startDragRange = GetDoorAreaRange();
  206. }
  207. else if (dragState == DragState.DragMove)
  208. {
  209. if (_isDragMode)
  210. {
  211. offset.X -= GameConfig.TileCellSize;
  212. }
  213. var position = _startTempPos;
  214. position.X += offset.X + _startButton.Size.X;
  215. var endPosition = _endButton.Position;
  216.  
  217. //拖拽模式
  218. if (_isDragMode)
  219. {
  220. if (position.X > endPosition.X) //该换方向了
  221. {
  222. _startButton.EmitSignal(BaseButton.SignalName.ButtonUp);
  223. _endButton.EmitSignal(BaseButton.SignalName.ButtonDown);
  224.  
  225. if (Mathf.Abs(position.X - endPosition.X) >= GameConfig.TileCellSize * 4 && !_canComment)
  226. {
  227. _canComment = true;
  228. _node.L_DoorArea.Instance.Color = _defaultColor;
  229. }
  230. return;
  231. }
  232. }
  233. //计算区域大小
  234. var areaSize = (int)(endPosition.X - position.X);
  235. _startButton.Position = position - new Vector2(_startButton.Size.X, 0);
  236. //刷新区域位置
  237. SetDoorAreaSize(areaSize);
  238. //起始点坐标必须要小于终点坐标, 且起点坐标大于0
  239. if (position.X < endPosition.X && (DoorHoverArea == null || position.X >= 0))
  240. {
  241. //区域必须大于等于 4 格宽度
  242. if (areaSize >= GameConfig.TileCellSize * 4)
  243. {
  244. var doorAreaRange = GetDoorAreaRange();
  245. //检测是否撞到其他区域
  246. bool checkResult;
  247. if (DoorAreaInfo == null)
  248. {
  249. checkResult = MapEditorToolsPanel.EditorMap.Instance.CheckDoorArea(Direction, doorAreaRange.X, doorAreaRange.Y);
  250. }
  251. else
  252. {
  253. checkResult = MapEditorToolsPanel.EditorMap.Instance.CheckDoorArea(DoorAreaInfo, doorAreaRange.X, doorAreaRange.Y);
  254. }
  255. if (checkResult)
  256. {
  257. //可以提交
  258. _canComment = true;
  259. _node.L_DoorArea.Instance.Color = _defaultColor;
  260. return;
  261. }
  262. }
  263. }
  264.  
  265. //错误的位置
  266. if (_canComment)
  267. {
  268. _canComment = false;
  269. _node.L_DoorArea.Instance.Color = _errorColor;
  270. }
  271. }
  272. else
  273. {
  274. DoorHoverArea.IsDrag = false;
  275. //松手后如果不能提交, 则还原初始位置
  276. if (!_canComment)
  277. {
  278. _canComment = true;
  279. _node.L_DoorArea.Instance.Color = _defaultColor;
  280. SetDoorAreaRange(_startDragRange.X, _startDragRange.Y);
  281. }
  282. else
  283. {
  284. //提交数据
  285. SubmitData();
  286. }
  287. if (DoorHoverArea != null)
  288. {
  289. DoorHoverArea.EmitSignal(Control.SignalName.MouseExited);
  290. }
  291. }
  292. }
  293. private void OnEndAreaDrag(DragState dragState, Vector2 offset)
  294. {
  295. if (dragState == DragState.DragStart)
  296. {
  297. DoorHoverArea.IsDrag = true;
  298. _canComment = true;
  299. _endTempPos = _endButton.Position;
  300. _startDragRange = GetDoorAreaRange();
  301. }
  302. else if (dragState == DragState.DragMove)
  303. {
  304. var position = _endTempPos;
  305. position.X = position.X += offset.X;
  306. var startPosition = _startButton.Position + new Vector2(_startButton.Size.X, 0);
  307. //拖拽模式
  308. if (_isDragMode)
  309. {
  310. if (position.X < startPosition.X) //该换方向了
  311. {
  312. _endButton.EmitSignal(BaseButton.SignalName.ButtonUp);
  313. _startButton.EmitSignal(BaseButton.SignalName.ButtonDown);
  314.  
  315. if (Mathf.Abs(position.X - startPosition.X) >= GameConfig.TileCellSize * 4 && !_canComment)
  316. {
  317. _canComment = true;
  318. _node.L_DoorArea.Instance.Color = _defaultColor;
  319. }
  320. return;
  321. }
  322. }
  323. //区域大小
  324. var areaSize = (int)(position.X - startPosition.X);
  325. //刷新区域位置
  326. SetDoorAreaSize(areaSize);
  327. //终点坐标必须要大于起始点坐标, 且终点坐标必须小于宽度
  328. if (position.X > startPosition.X && (DoorHoverArea == null || position.X <= DoorHoverArea.Size.X))
  329. {
  330. //区域必须大于等于 4 格宽度
  331. if (areaSize >= GameConfig.TileCellSize * 4)
  332. {
  333. var doorAreaRange = GetDoorAreaRange();
  334. //检测是否撞到其他区域
  335. bool checkResult;
  336. if (DoorAreaInfo == null)
  337. {
  338. checkResult = MapEditorToolsPanel.EditorMap.Instance.CheckDoorArea(Direction, doorAreaRange.X, doorAreaRange.Y);
  339. }
  340. else
  341. {
  342. checkResult = MapEditorToolsPanel.EditorMap.Instance.CheckDoorArea(DoorAreaInfo, doorAreaRange.X, doorAreaRange.Y);
  343. }
  344. if (checkResult)
  345. {
  346. //可以提交
  347. _canComment = true;
  348. _node.L_DoorArea.Instance.Color = _defaultColor;
  349. return;
  350. }
  351. }
  352. }
  353.  
  354. //错误的位置
  355. if (_canComment)
  356. {
  357. _canComment = false;
  358. _node.L_DoorArea.Instance.Color = _errorColor;
  359. }
  360. }
  361. else
  362. {
  363. DoorHoverArea.IsDrag = false;
  364. //松手后如果不能提交, 则还原初始位置
  365. if (!_canComment)
  366. {
  367. _canComment = true;
  368. _node.L_DoorArea.Instance.Color = _defaultColor;
  369. SetDoorAreaRange(_startDragRange.X, _startDragRange.Y);
  370. }
  371. else
  372. {
  373. //提交数据
  374. SubmitData();
  375. }
  376. if (DoorHoverArea != null)
  377. {
  378. DoorHoverArea.EmitSignal(Control.SignalName.MouseExited);
  379. }
  380. }
  381. }
  382.  
  383. /// <summary>
  384. /// 将该区域变为拖拽模式, 用于创建门区域
  385. /// </summary>
  386. /// <param name="onSubmit">成功提交时回调, 参数1为方向, 参数2为起始点, 参数3为大小</param>
  387. /// <param name="onCancel">取消时调用</param>
  388. public void MakeDragMode(Action<DoorDirection, int, int> onSubmit, Action onCancel)
  389. {
  390. _canComment = false;
  391. _isDragMode = true;
  392. _onSubmit = onSubmit;
  393. _onCancel = onCancel;
  394. _endButton.EmitSignal(BaseButton.SignalName.ButtonDown);
  395. }
  396.  
  397. //提交数据
  398. private void SubmitData()
  399. {
  400. //保存数据
  401. if (DoorAreaInfo != null)
  402. {
  403. var doorAreaRange = GetDoorAreaRange();
  404. DoorAreaInfo.Start = doorAreaRange.X;
  405. DoorAreaInfo.End = doorAreaRange.Y;
  406. Debug.Log("提交修改: " + doorAreaRange);
  407. //派发修改数据修改事件
  408. EventManager.EmitEvent(EventEnum.OnTileMapDirty);
  409. }
  410. }
  411.  
  412. private void OnMouseEntered()
  413. {
  414. if (MapEditorToolsPanel.EditorMap.Instance.MouseType != EditorTileMap.MouseButtonType.Edit)
  415. {
  416. return;
  417. }
  418. _mouseHover = true;
  419. }
  420. private void OnMouseExited()
  421. {
  422. if (MapEditorToolsPanel.EditorMap.Instance.MouseType != EditorTileMap.MouseButtonType.Edit)
  423. {
  424. return;
  425. }
  426. _mouseHover = false;
  427. }
  428. }