Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / ui / mapEditorTools / MapEditorToolsPanel.cs
@小李xl 小李xl on 15 Aug 2023 15 KB 创建房间标记, 开发中
  1. using System;
  2. using System.Collections.Generic;
  3. using Godot;
  4. using UI.MapEditor;
  5.  
  6. namespace UI.MapEditorTools;
  7.  
  8. public partial class MapEditorToolsPanel : MapEditorTools
  9. {
  10. public class ToolBtnData
  11. {
  12. public bool CanSelect = false;
  13. public string Icon;
  14. public Action OnClick;
  15.  
  16. public ToolBtnData(bool canSelect, string icon, Action onClick)
  17. {
  18. CanSelect = canSelect;
  19. Icon = icon;
  20. OnClick = onClick;
  21. }
  22. }
  23. /// <summary>
  24. /// 鼠标悬停区域
  25. /// </summary>
  26. public DoorHoverArea ActiveHoverArea { get; private set; }
  27. /// <summary>
  28. /// 鼠标选中的标记对象
  29. /// </summary>
  30. public MarkTool ActiveMark { get; private set; }
  31.  
  32. /// <summary>
  33. /// 所属编辑器Tile对象
  34. /// </summary>
  35. public MapEditor.MapEditor.TileMap EditorMap { get; set; }
  36. private List<DoorToolTemplate> _doorTools = new List<DoorToolTemplate>();
  37. private UiGrid<ToolButton, ToolBtnData> _toolGrid;
  38. //当前预设的所有标记
  39. private Dictionary<MarkInfo, MarkTemplate> _currMarkToolsMap = new Dictionary<MarkInfo, MarkTemplate>();
  40. private EventFactory _eventFactory;
  41.  
  42. public override void OnCreateUi()
  43. {
  44. S_N_HoverArea.Instance.Init(this, DoorDirection.N);
  45. S_S_HoverArea.Instance.Init(this, DoorDirection.S);
  46. S_W_HoverArea.Instance.Init(this, DoorDirection.W);
  47. S_E_HoverArea.Instance.Init(this, DoorDirection.E);
  48. S_ToolRoot.Instance.RemoveChild(S_DoorToolTemplate.Instance);
  49. S_MarkTemplate.Instance.Visible = false;
  50.  
  51. _toolGrid = new UiGrid<ToolButton, ToolBtnData>(S_ToolButton, typeof(ToolButtonCell));
  52. _toolGrid.SetColumns(10);
  53. //拖拽按钮
  54. _toolGrid.Add(new ToolBtnData(true, ResourcePath.resource_sprite_ui_commonIcon_DragTool_png, () =>
  55. {
  56. EventManager.EmitEvent(EventEnum.OnSelectDragTool);
  57. }));
  58. //画笔按钮
  59. _toolGrid.Add(new ToolBtnData(true, ResourcePath.resource_sprite_ui_commonIcon_PenTool_png, () =>
  60. {
  61. EventManager.EmitEvent(EventEnum.OnSelectPenTool);
  62. }));
  63. //绘制区域按钮
  64. _toolGrid.Add(new ToolBtnData(true, ResourcePath.resource_sprite_ui_commonIcon_AreaTool_png, () =>
  65. {
  66. EventManager.EmitEvent(EventEnum.OnSelectRectTool);
  67. }));
  68. //编辑门区域按钮
  69. _toolGrid.Add(new ToolBtnData(true, ResourcePath.resource_sprite_ui_commonIcon_DoorTool_png, () =>
  70. {
  71. EventManager.EmitEvent(EventEnum.OnSelectDoorTool);
  72. }));
  73. //聚焦按钮
  74. _toolGrid.Add(new ToolBtnData(false, ResourcePath.resource_sprite_ui_commonIcon_CenterTool_png, () =>
  75. {
  76. EventManager.EmitEvent(EventEnum.OnClickCenterTool);
  77. }));
  78. _toolGrid.SelectIndex = 1;
  79. }
  80.  
  81. public override void OnShowUi()
  82. {
  83. _eventFactory = EventManager.CreateEventFactory();
  84. _eventFactory.AddEventListener(EventEnum.OnCreateMark, OnCreateMarkTool);
  85. _eventFactory.AddEventListener(EventEnum.OnSelectMark, OnSelectMarkTool);
  86. _eventFactory.AddEventListener(EventEnum.OnSelectPreinstall, RefreshMark);
  87. }
  88.  
  89. public override void OnHideUi()
  90. {
  91. _eventFactory.RemoveAllEventListener();
  92. _eventFactory = null;
  93. }
  94.  
  95. public override void OnDestroyUi()
  96. {
  97. S_DoorToolTemplate.Instance.QueueFree();
  98. _toolGrid.Destroy();
  99. }
  100.  
  101. public override void Process(float delta)
  102. {
  103. S_HoverPreviewRoot.Instance.Visible = ActiveHoverArea != null && !DoorHoverArea.IsDrag;
  104. if (EditorMap.Instance.MouseType == EditorTileMap.MouseButtonType.Door)
  105. {
  106. S_ToolRoot.Instance.Modulate = new Color(1, 1, 1, 1);
  107. }
  108. else
  109. {
  110. S_ToolRoot.Instance.Modulate = new Color(1, 1, 1, 0.4f);
  111. }
  112. }
  113.  
  114. //刷新标记
  115. private void RefreshMark(object arg)
  116. {
  117. //删除之前的数据
  118. foreach (var keyValuePair in _currMarkToolsMap)
  119. {
  120. keyValuePair.Value.QueueFree();
  121. }
  122. _currMarkToolsMap.Clear();
  123. //添加新的数据
  124. var selectPreinstall = EditorMap.Instance.SelectPreinstall;
  125. if (selectPreinstall != null)
  126. {
  127. foreach (var markInfos in selectPreinstall.WaveList)
  128. {
  129. foreach (var markInfo in markInfos)
  130. {
  131. CreateMarkTool(markInfo);
  132. }
  133. }
  134. }
  135. }
  136.  
  137. //创建标记
  138. private void OnCreateMarkTool(object arg)
  139. {
  140. var markInfo = (MarkInfo)arg;
  141. CreateMarkTool(markInfo);
  142. }
  143.  
  144. //创建标记
  145. private void CreateMarkTool(MarkInfo markInfo)
  146. {
  147. var cloneAndPut = S_MarkTemplate.CloneAndPut();
  148. _currMarkToolsMap.Add(markInfo, cloneAndPut);
  149. cloneAndPut.Instance.Visible = true;
  150. cloneAndPut.Instance.InitData(markInfo);
  151. }
  152.  
  153. //选中标记
  154. private void OnSelectMarkTool(object arg)
  155. {
  156. if (arg is MarkInfo markInfo)
  157. {
  158. if (markInfo != ActiveMark.MarkInfo)
  159. {
  160. if (_currMarkToolsMap.TryGetValue(markInfo, out var markTemplate))
  161. {
  162. SetActiveMark(markTemplate.Instance);
  163. }
  164. }
  165. }
  166. }
  167. /// <summary>
  168. /// 获取门区域对象
  169. /// </summary>
  170. public DoorHoverArea GetDoorHoverArea(DoorDirection direction)
  171. {
  172. switch (direction)
  173. {
  174. case DoorDirection.E: return S_E_HoverArea.Instance;
  175. case DoorDirection.N: return S_N_HoverArea.Instance;
  176. case DoorDirection.W: return S_W_HoverArea.Instance;
  177. case DoorDirection.S: return S_S_HoverArea.Instance;
  178. }
  179. return null;
  180. }
  181. /// <summary>
  182. /// 获取门区域根节点
  183. /// </summary>
  184. public Control GetDoorHoverAreaRoot(DoorDirection direction)
  185. {
  186. switch (direction)
  187. {
  188. case DoorDirection.E: return S_E_HoverRoot.Instance;
  189. case DoorDirection.N: return S_N_HoverRoot.Instance;
  190. case DoorDirection.W: return S_W_HoverRoot.Instance;
  191. case DoorDirection.S: return S_S_HoverRoot.Instance;
  192. }
  193. return null;
  194. }
  195.  
  196. /// <summary>
  197. /// 设置活动的鼠标悬停的区域
  198. /// </summary>
  199. public void SetActiveHoverArea(DoorHoverArea hoverArea)
  200. {
  201. ActiveHoverArea = hoverArea;
  202. if (hoverArea != null)
  203. {
  204. S_HoverPreviewRoot.Instance.Reparent(hoverArea.GetParent(), false);
  205. }
  206. else
  207. {
  208. S_HoverPreviewRoot.Instance.Reparent(S_ToolRoot.Instance, false);
  209. }
  210. }
  211.  
  212. /// <summary>
  213. /// 设置当前活动的标记
  214. /// </summary>
  215. public void SetActiveMark(MarkTool markTool)
  216. {
  217. if (ActiveMark == markTool)
  218. {
  219. return;
  220. }
  221.  
  222. if (ActiveMark != null)
  223. {
  224. ActiveMark.Modulate = Colors.White;
  225. }
  226. ActiveMark = markTool;
  227. if (markTool != null)
  228. {
  229. markTool.Modulate = Colors.Green;
  230. EventManager.EmitEvent(EventEnum.OnSelectMark, markTool.MarkInfo);
  231. }
  232. else
  233. {
  234. EventManager.EmitEvent(EventEnum.OnSelectMark);
  235. }
  236. }
  237.  
  238. /// <summary>
  239. /// 创建门区域设置工具
  240. /// </summary>
  241. /// <param name="doorAreaInfo">门区域数据</param>
  242. public DoorToolTemplate CreateDoorTool(DoorAreaInfo doorAreaInfo)
  243. {
  244. var doorHoverArea = GetDoorHoverArea(doorAreaInfo.Direction);
  245. var inst = CreateDoorToolInstance(doorHoverArea);
  246. inst.Instance.DoorAreaInfo = doorAreaInfo;
  247. inst.Instance.SetDoorAreaPosition(GetDoorHoverAreaRoot(doorAreaInfo.Direction).Position);
  248. inst.Instance.SetDoorAreaRange(doorAreaInfo.Start, doorAreaInfo.End);
  249. return inst;
  250. }
  251.  
  252. /// <summary>
  253. /// 创建拖拽状态下的门区域工具, 用于创建门区域
  254. /// </summary>
  255. /// <param name="doorHoverArea">悬停区域</param>
  256. /// <param name="start">起始位置, 单位: 像素</param>
  257. /// <param name="onSubmit">成功提交时回调, 参数1为方向, 参数2为起始点, 参数3为大小</param>
  258. /// <param name="onCancel">取消提交时调用</param>
  259. public DoorToolTemplate CreateDragDoorTool(DoorHoverArea doorHoverArea, int start,
  260. Action<DoorDirection, int, int> onSubmit, Action onCancel)
  261. {
  262. var inst = CreateDoorToolInstance(doorHoverArea);
  263. inst.Instance.SetDoorAreaPosition(GetDoorHoverAreaRoot(doorHoverArea.Direction).Position);
  264. inst.Instance.SetDoorAreaRange(start, start);
  265. inst.Instance.MakeDragMode(onSubmit, () =>
  266. {
  267. RemoveDoorTool(inst);
  268. onCancel();
  269. });
  270. return inst;
  271. }
  272.  
  273. /// <summary>
  274. /// 移除门区域设置工具
  275. /// </summary>
  276. public void RemoveDoorTool(DoorToolTemplate toolInstance)
  277. {
  278. _doorTools.Remove(toolInstance);
  279. if (toolInstance.Instance.DoorAreaInfo != null)
  280. {
  281. EditorMap.Instance.RemoveDoorArea(toolInstance.Instance.DoorAreaInfo);
  282. }
  283. toolInstance.Instance.QueueFree();
  284. }
  285.  
  286. /// <summary>
  287. /// 设置工具根节点的大小和缩放
  288. /// </summary>
  289. /// <param name="pos">坐标</param>
  290. /// <param name="scale">缩放</param>
  291. public void SetToolTransform(Vector2 pos, Vector2 scale)
  292. {
  293. S_ToolRoot.Instance.Position = pos;
  294. S_ToolRoot.Instance.Scale = scale;
  295. }
  296.  
  297. /// <summary>
  298. /// 设置鼠标悬停区域位置和大小
  299. /// </summary>
  300. /// <param name="position">房间起始点, 单位: 格</param>
  301. /// <param name="size">房间大小, 单位: 格</param>
  302. public void SetDoorHoverToolTransform(Vector2I position, Vector2I size)
  303. {
  304. position *= GameConfig.TileCellSize;
  305. size *= GameConfig.TileCellSize;
  306.  
  307. var nPos1 = S_N_HoverRoot.Instance.Position;
  308. var ePos1 = S_E_HoverRoot.Instance.Position;
  309. var sPos1 = S_S_HoverRoot.Instance.Position;
  310. var wPos1 = S_W_HoverRoot.Instance.Position;
  311. var nPos2 = position + GameConfig.TileCellSizeVector2I;
  312. var ePos2 = new Vector2(position.X + size.X - GameConfig.TileCellSize, position.Y + GameConfig.TileCellSize);
  313. var sPos2 = new Vector2(position.X + GameConfig.TileCellSize, position.Y + size.Y - GameConfig.TileCellSize);
  314. var wPos2 = position + GameConfig.TileCellSizeVector2I;
  315.  
  316. var nSize2 = new Vector2(size.X - GameConfig.TileCellSize * 2, S_N_HoverArea.Instance.Size.Y);
  317. var eSize2 = new Vector2(size.Y - GameConfig.TileCellSize * 2, S_E_HoverArea.Instance.Size.Y);
  318. var sSize2 = new Vector2(size.X - GameConfig.TileCellSize * 2, S_S_HoverArea.Instance.Size.Y);
  319. var wSize2 = new Vector2(size.Y - GameConfig.TileCellSize * 2, S_W_HoverArea.Instance.Size.Y);
  320. S_N_HoverRoot.Instance.Position = nPos2;
  321. S_E_HoverRoot.Instance.Position = ePos2;
  322. S_S_HoverRoot.Instance.Position = sPos2;
  323. S_W_HoverRoot.Instance.Position = wPos2;
  324. S_N_HoverArea.Instance.Size = nSize2;
  325. S_E_HoverArea.Instance.Size = eSize2;
  326. S_S_HoverArea.Instance.Size = sSize2;
  327. S_W_HoverArea.Instance.Size = wSize2;
  328. //调整门区域
  329. for (var i = 0; i < _doorTools.Count; i++)
  330. {
  331. var doorTool = _doorTools[i];
  332. var direction = doorTool.Instance.Direction;
  333. var areaRoot = GetDoorHoverAreaRoot(direction);
  334. var doorAreaRange = doorTool.Instance.GetDoorAreaRange();
  335. doorTool.Instance.SetDoorAreaPosition(areaRoot.Position);
  336.  
  337. if (direction == DoorDirection.N)
  338. {
  339. var hOffset = (int)(nPos2.X - nPos1.X);
  340. doorAreaRange.X -= hOffset;
  341. doorAreaRange.Y -= hOffset;
  342.  
  343. if (doorAreaRange.X >= 0 && doorAreaRange.Y <= nSize2.X) //允许提交
  344. {
  345. doorTool.Instance.SetDoorAreaRange(doorAreaRange.X, doorAreaRange.Y);
  346. if (doorTool.Instance.DoorAreaInfo != null)
  347. {
  348. doorTool.Instance.DoorAreaInfo.Start = doorAreaRange.X;
  349. doorTool.Instance.DoorAreaInfo.End = doorAreaRange.Y;
  350. }
  351. }
  352. else //如果超出区域, 则删除
  353. {
  354. RemoveDoorTool(doorTool);
  355. i--;
  356. }
  357. }
  358. else if (direction == DoorDirection.S)
  359. {
  360. var hOffset = (int)(sPos2.X - sPos1.X);
  361. doorAreaRange.X -= hOffset;
  362. doorAreaRange.Y -= hOffset;
  363.  
  364. if (doorAreaRange.X >= 0 && doorAreaRange.Y <= sSize2.X) //允许提交
  365. {
  366. doorTool.Instance.SetDoorAreaRange(doorAreaRange.X, doorAreaRange.Y);
  367. if (doorTool.Instance.DoorAreaInfo != null)
  368. {
  369. doorTool.Instance.DoorAreaInfo.Start = doorAreaRange.X;
  370. doorTool.Instance.DoorAreaInfo.End = doorAreaRange.Y;
  371. }
  372. }
  373. else //如果超出区域, 则删除
  374. {
  375. RemoveDoorTool(doorTool);
  376. i--;
  377. }
  378. }
  379. else if (direction == DoorDirection.E)
  380. {
  381. var vOffset = (int)(ePos2.Y - ePos1.Y);
  382. doorAreaRange.X -= vOffset;
  383. doorAreaRange.Y -= vOffset;
  384.  
  385. if (doorAreaRange.X >= 0 && doorAreaRange.Y <= eSize2.X) //允许提交
  386. {
  387. doorTool.Instance.SetDoorAreaRange(doorAreaRange.X, doorAreaRange.Y);
  388. if (doorTool.Instance.DoorAreaInfo != null)
  389. {
  390. doorTool.Instance.DoorAreaInfo.Start = doorAreaRange.X;
  391. doorTool.Instance.DoorAreaInfo.End = doorAreaRange.Y;
  392. }
  393. }
  394. else //如果超出区域, 则删除
  395. {
  396. RemoveDoorTool(doorTool);
  397. i--;
  398. }
  399. }
  400. else if (direction == DoorDirection.W)
  401. {
  402. var vOffset = (int)(wPos2.Y - wPos1.Y);
  403. doorAreaRange.X -= vOffset;
  404. doorAreaRange.Y -= vOffset;
  405.  
  406. if (doorAreaRange.X >= 0 && doorAreaRange.Y <= wSize2.X) //允许提交
  407. {
  408. doorTool.Instance.SetDoorAreaRange(doorAreaRange.X, doorAreaRange.Y);
  409. if (doorTool.Instance.DoorAreaInfo != null)
  410. {
  411. doorTool.Instance.DoorAreaInfo.Start = doorAreaRange.X;
  412. doorTool.Instance.DoorAreaInfo.End = doorAreaRange.Y;
  413. }
  414. }
  415. else //如果超出区域, 则删除
  416. {
  417. RemoveDoorTool(doorTool);
  418. i--;
  419. }
  420. }
  421. }
  422. }
  423. private DoorToolTemplate CreateDoorToolInstance(DoorHoverArea doorHoverArea)
  424. {
  425. var doorTool = S_DoorToolTemplate.Clone();
  426. S_ToolRoot.Instance.AddChild(doorTool.Instance);
  427. doorTool.Instance.SetDoorDragAreaNode(doorTool);
  428. doorTool.L_StartBtn.Instance.SetMapEditorToolsPanel(this);
  429. doorTool.L_EndBtn.Instance.SetMapEditorToolsPanel(this);
  430. doorTool.Instance.SetDoorHoverArea(doorHoverArea);
  431. _doorTools.Add(doorTool);
  432. return doorTool;
  433. }
  434. }