Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / ui / mapEditorTools / DoorDragArea.cs
@小李xl 小李xl on 28 Jul 2023 10 KB 创建门区域, 开发中
  1. using System;
  2. using Godot;
  3.  
  4. namespace UI.MapEditorTools;
  5.  
  6. public partial class DoorDragArea : Control
  7. {
  8. /// <summary>
  9. /// 当前区域所占大小, 单位: 像素
  10. /// </summary>
  11. public Vector2 AreaSize => new Vector2(_areaSize, GameConfig.TileCellSize * 2);
  12.  
  13. //错误时的颜色
  14. private static Color _errorColor = new Color(1, 0, 0, 0.1882353F);
  15.  
  16. /// <summary>
  17. /// 朝向
  18. /// </summary>
  19. public DoorDirection Direction { get; private set; }
  20.  
  21. private DoorDragButton _startButton;
  22. private DoorDragButton _endButton;
  23. private MapEditorTools.DoorToolTemplate _node;
  24. private Vector2 _startTempPos;
  25. private Vector2 _endTempPos;
  26. //默认颜色
  27. private Color _defaultColor;
  28. //区域大小, 单位: 像素
  29. private int _areaSize = GameConfig.TileCellSize * 4;
  30. //拖拽松手后是否可以提交
  31. private bool _canComment = true;
  32. //开始拖拽时的区域
  33. private Vector2I _startDragRange;
  34. //是否是拖拽模式
  35. private bool _isDragMode = false;
  36. //拖拽模式提交回调
  37. private Action<int, int> _onSubmit;
  38. //拖拽模式取消时回调
  39. private Action _onCancel;
  40.  
  41. public void SetDoorDragAreaNode(MapEditorTools.DoorToolTemplate node)
  42. {
  43. _node = node;
  44. _defaultColor = _node.L_DoorArea.Instance.Color;
  45. _startButton = _node.L_StartBtn.Instance;
  46. _endButton = _node.L_EndBtn.Instance;
  47. _startButton.DragEvent += OnStartAreaDrag;
  48. _endButton.DragEvent += OnEndAreaDrag;
  49. SetDoorAreaSize(GameConfig.TileCellSize * 4);
  50. SetDoorAreaDirection(DoorDirection.N);
  51. }
  52.  
  53. public override void _Process(double delta)
  54. {
  55. if (_isDragMode)
  56. {
  57. if (!Input.IsMouseButtonPressed(MouseButton.Left)) //松开了右键
  58. {
  59. _isDragMode = false;
  60. if (_canComment) //可以提交
  61. {
  62. _isDragMode = false;
  63. _onCancel = null;
  64. _startButton.EmitSignal(BaseButton.SignalName.ButtonUp);
  65. _endButton.EmitSignal(BaseButton.SignalName.ButtonUp);
  66. if (_onSubmit != null)
  67. {
  68. var doorAreaRange = GetDoorAreaRange();
  69. _onSubmit(doorAreaRange.X, doorAreaRange.Y);
  70. _onSubmit = null;
  71. }
  72. }
  73. else //不能提交
  74. {
  75. if (_onCancel != null)
  76. {
  77. _onCancel();
  78. }
  79. }
  80. }
  81. }
  82. }
  83.  
  84. /// <summary>
  85. /// 设置门区域的位置, 单位: 像素
  86. /// </summary>
  87. public void SetDoorAreaPosition(Vector2 position)
  88. {
  89. Position = position;
  90. }
  91.  
  92. /// <summary>
  93. /// 设置门区域的方向
  94. /// </summary>
  95. public void SetDoorAreaDirection(DoorDirection direction)
  96. {
  97. Direction = direction;
  98. if (direction == DoorDirection.N)
  99. {
  100. Scale = new Vector2(1, 1);
  101. RotationDegrees = 0;
  102. }
  103. else if (direction == DoorDirection.E)
  104. {
  105. Scale = new Vector2(1, 1);
  106. RotationDegrees = 90;
  107. }
  108. else if (direction == DoorDirection.S)
  109. {
  110. Scale = new Vector2(-1, 1);
  111. RotationDegrees = 180;
  112. }
  113. else
  114. {
  115. Scale = new Vector2(-1, 1);
  116. RotationDegrees = 270;
  117. }
  118. }
  119.  
  120. /// <summary>
  121. /// 获取门区域所占范围, 单位: 像素, 返回的 Vector2I 的 x 代表起始坐标, y 代表结束坐标
  122. /// </summary>
  123. /// <returns></returns>
  124. public Vector2I GetDoorAreaRange()
  125. {
  126. return new Vector2I((int)(_startButton.Position.X + _startButton.Size.X), _areaSize);
  127. }
  128.  
  129. /// <summary>
  130. /// 设置门区域所占范围, 单位: 像素
  131. /// </summary>
  132. public void SetDoorAreaRange(int start, int size)
  133. {
  134. var startPosition = _startButton.Position;
  135. startPosition.X = start - _startButton.Size.X;
  136. _startButton.Position = startPosition;
  137. SetDoorAreaSize(size);
  138. }
  139.  
  140. /// <summary>
  141. /// 设置区域起始坐标
  142. /// </summary>
  143. public void SetDoorAreaStart(int start)
  144. {
  145. var startPosition = _startButton.Position;
  146. startPosition.X = start - _startButton.Size.X;
  147. _startButton.Position = startPosition;
  148. RefreshArea();
  149. }
  150.  
  151. /// <summary>
  152. /// 设置区域大小, 单位: 像素
  153. /// </summary>
  154. public void SetDoorAreaSize(int value)
  155. {
  156. _areaSize = value;
  157. RefreshArea();
  158. //GD.Print("size: " + GetDoorAreaRange());
  159. }
  160.  
  161. //刷新区域位置
  162. private void RefreshArea()
  163. {
  164. var colorRect = _node.L_DoorArea.Instance;
  165. var position = colorRect.Position;
  166. position.X = _startButton.Position.X + _startButton.Size.X;
  167. colorRect.Position = position;
  168. colorRect.Size = AreaSize;
  169.  
  170. var position2 = _endButton.Position;
  171. position2.X = position.X + AreaSize.X;
  172. _endButton.Position = position2;
  173. }
  174. //拖拽起始点
  175. private void OnStartAreaDrag(DragState dragState, Vector2 offset)
  176. {
  177. if (dragState == DragState.DragStart)
  178. {
  179. _canComment = true;
  180. _startTempPos = _startButton.Position;
  181. _startDragRange = GetDoorAreaRange();
  182. }
  183. else if (dragState == DragState.DragMove)
  184. {
  185. if (_isDragMode)
  186. {
  187. offset.X -= GameConfig.TileCellSize;
  188. }
  189. var position = _startTempPos;
  190. position.X = position.X += offset.X;
  191. var endPosition = _endButton.Position;
  192.  
  193. //拖拽模式
  194. if (_isDragMode)
  195. {
  196. if (position.X > endPosition.X) //该换方向了
  197. {
  198. _startButton.EmitSignal(BaseButton.SignalName.ButtonUp);
  199. _endButton.EmitSignal(BaseButton.SignalName.ButtonDown);
  200.  
  201. if (Mathf.Abs(position.X - endPosition.X) >= GameConfig.TileCellSize * 4 && !_canComment)
  202. {
  203. _canComment = true;
  204. _node.L_DoorArea.Instance.Color = _defaultColor;
  205. }
  206. return;
  207. }
  208. }
  209. //计算区域大小
  210. var areaSize = (int)(endPosition.X - position.X - _startButton.Size.X);
  211. _startButton.Position = position;
  212. //刷新区域位置
  213. SetDoorAreaSize(areaSize);
  214. //起始点坐标必须要小于终点坐标
  215. if (position.X < endPosition.X)
  216. {
  217. //区域必须大于等于 4 格宽度
  218. if (areaSize >= GameConfig.TileCellSize * 4)
  219. {
  220. if (!_canComment)
  221. {
  222. _canComment = true;
  223. _node.L_DoorArea.Instance.Color = _defaultColor;
  224. }
  225. return;
  226. }
  227. }
  228.  
  229. //错误的位置
  230. if (_canComment)
  231. {
  232. _canComment = false;
  233. _node.L_DoorArea.Instance.Color = _errorColor;
  234. }
  235. }
  236. else
  237. {
  238. //松手后如果不能提交, 则还原初始位置
  239. if (!_canComment)
  240. {
  241. _canComment = true;
  242. _node.L_DoorArea.Instance.Color = _defaultColor;
  243. SetDoorAreaRange(_startDragRange.X, _startDragRange.Y);
  244. }
  245. }
  246. }
  247. private void OnEndAreaDrag(DragState dragState, Vector2 offset)
  248. {
  249. if (dragState == DragState.DragStart)
  250. {
  251. _canComment = true;
  252. _endTempPos = _endButton.Position;
  253. _startDragRange = GetDoorAreaRange();
  254. }
  255. else if (dragState == DragState.DragMove)
  256. {
  257. var position = _endTempPos;
  258. position.X = position.X += offset.X;
  259. var startPosition = _startButton.Position;
  260. //拖拽模式
  261. if (_isDragMode)
  262. {
  263. if (position.X < startPosition.X) //该换方向了
  264. {
  265. _endButton.EmitSignal(BaseButton.SignalName.ButtonUp);
  266. _startButton.EmitSignal(BaseButton.SignalName.ButtonDown);
  267.  
  268. if (Mathf.Abs(position.X - startPosition.X) >= GameConfig.TileCellSize * 4 && !_canComment)
  269. {
  270. _canComment = true;
  271. _node.L_DoorArea.Instance.Color = _defaultColor;
  272. }
  273. return;
  274. }
  275. }
  276. //区域大小
  277. var areaSize = (int)(position.X - _startButton.Position.X - _startButton.Size.X);
  278. //刷新区域位置
  279. SetDoorAreaSize(areaSize);
  280. //终点坐标必须要大于起始点坐标
  281. if (position.X > startPosition.X)
  282. {
  283. //区域必须大于等于 4 格宽度
  284. if (areaSize >= GameConfig.TileCellSize * 4)
  285. {
  286. if (!_canComment)
  287. {
  288. _canComment = true;
  289. _node.L_DoorArea.Instance.Color = _defaultColor;
  290. }
  291. return;
  292. }
  293. }
  294.  
  295. //错误的位置
  296. if (_canComment)
  297. {
  298. _canComment = false;
  299. _node.L_DoorArea.Instance.Color = _errorColor;
  300. }
  301. }
  302. else
  303. {
  304. //松手后如果不能提交, 则还原初始位置
  305. if (!_canComment)
  306. {
  307. _canComment = true;
  308. _node.L_DoorArea.Instance.Color = _defaultColor;
  309. SetDoorAreaRange(_startDragRange.X, _startDragRange.Y);
  310. }
  311. }
  312. }
  313.  
  314. /// <summary>
  315. /// 将该区域变为拖拽模式, 用于创建门区域
  316. /// </summary>
  317. /// <param name="onSubmit">成功提交时回调, 参数1为起始点, 参数2为大小</param>
  318. /// <param name="onCancel">取消时调用</param>
  319. public void MakeDragMode(Action<int, int> onSubmit, Action onCancel)
  320. {
  321. _canComment = false;
  322. _isDragMode = true;
  323. _onSubmit = onSubmit;
  324. _onCancel = onCancel;
  325. _endButton.EmitSignal(BaseButton.SignalName.ButtonDown);
  326. }
  327. }