Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / ui / mapEditorTools / MapEditorToolsPanel.cs
@小李xl 小李xl on 16 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.OnDeleteMark, OnDeleteMarkTool);
  87. _eventFactory.AddEventListener(EventEnum.OnSelectPreinstall, RefreshMark);
  88. }
  89.  
  90. public override void OnHideUi()
  91. {
  92. _eventFactory.RemoveAllEventListener();
  93. _eventFactory = null;
  94. }
  95.  
  96. public override void OnDestroyUi()
  97. {
  98. S_DoorToolTemplate.Instance.QueueFree();
  99. _toolGrid.Destroy();
  100. }
  101.  
  102. public override void Process(float delta)
  103. {
  104. S_HoverPreviewRoot.Instance.Visible = ActiveHoverArea != null && !DoorHoverArea.IsDrag;
  105. if (EditorMap.Instance.MouseType == EditorTileMap.MouseButtonType.Door)
  106. {
  107. S_ToolRoot.Instance.Modulate = new Color(1, 1, 1, 1);
  108. }
  109. else
  110. {
  111. S_ToolRoot.Instance.Modulate = new Color(1, 1, 1, 0.4f);
  112. }
  113. }
  114.  
  115. //刷新标记
  116. private void RefreshMark(object arg)
  117. {
  118. //删除之前的数据
  119. foreach (var keyValuePair in _currMarkToolsMap)
  120. {
  121. keyValuePair.Value.QueueFree();
  122. }
  123. _currMarkToolsMap.Clear();
  124. //添加新的数据
  125. var selectPreinstall = EditorMap.Instance.SelectPreinstall;
  126. if (selectPreinstall != null)
  127. {
  128. foreach (var markInfos in selectPreinstall.WaveList)
  129. {
  130. foreach (var markInfo in markInfos)
  131. {
  132. CreateMarkTool(markInfo);
  133. }
  134. }
  135. }
  136. }
  137.  
  138. //创建标记
  139. private void OnCreateMarkTool(object arg)
  140. {
  141. var markInfo = (MarkInfo)arg;
  142. CreateMarkTool(markInfo);
  143. }
  144.  
  145. //创建标记
  146. private void CreateMarkTool(MarkInfo markInfo)
  147. {
  148. var cloneAndPut = S_MarkTemplate.CloneAndPut();
  149. _currMarkToolsMap.Add(markInfo, cloneAndPut);
  150. cloneAndPut.Instance.Visible = true;
  151. cloneAndPut.Instance.InitData(markInfo);
  152. }
  153.  
  154. //选中标记
  155. private void OnSelectMarkTool(object arg)
  156. {
  157. if (arg is MarkInfo markInfo)
  158. {
  159. if (ActiveMark == null || markInfo != ActiveMark.MarkInfo)
  160. {
  161. if (_currMarkToolsMap.TryGetValue(markInfo, out var markTemplate))
  162. {
  163. SetActiveMark(markTemplate.Instance);
  164. }
  165. }
  166. }
  167. }
  168.  
  169. //删除标记
  170. private void OnDeleteMarkTool(object arg)
  171. {
  172. if (arg is MarkInfo markInfo)
  173. {
  174. if (_currMarkToolsMap.TryGetValue(markInfo, out var markTemplate))
  175. {
  176. if (ActiveMark == markTemplate.Instance)
  177. {
  178. SetActiveMark(null);
  179. }
  180. markTemplate.QueueFree();
  181. _currMarkToolsMap.Remove(markInfo);
  182. }
  183. }
  184. }
  185. /// <summary>
  186. /// 获取门区域对象
  187. /// </summary>
  188. public DoorHoverArea GetDoorHoverArea(DoorDirection direction)
  189. {
  190. switch (direction)
  191. {
  192. case DoorDirection.E: return S_E_HoverArea.Instance;
  193. case DoorDirection.N: return S_N_HoverArea.Instance;
  194. case DoorDirection.W: return S_W_HoverArea.Instance;
  195. case DoorDirection.S: return S_S_HoverArea.Instance;
  196. }
  197. return null;
  198. }
  199. /// <summary>
  200. /// 获取门区域根节点
  201. /// </summary>
  202. public Control GetDoorHoverAreaRoot(DoorDirection direction)
  203. {
  204. switch (direction)
  205. {
  206. case DoorDirection.E: return S_E_HoverRoot.Instance;
  207. case DoorDirection.N: return S_N_HoverRoot.Instance;
  208. case DoorDirection.W: return S_W_HoverRoot.Instance;
  209. case DoorDirection.S: return S_S_HoverRoot.Instance;
  210. }
  211. return null;
  212. }
  213.  
  214. /// <summary>
  215. /// 设置活动的鼠标悬停的区域
  216. /// </summary>
  217. public void SetActiveHoverArea(DoorHoverArea hoverArea)
  218. {
  219. ActiveHoverArea = hoverArea;
  220. if (hoverArea != null)
  221. {
  222. S_HoverPreviewRoot.Instance.Reparent(hoverArea.GetParent(), false);
  223. }
  224. else
  225. {
  226. S_HoverPreviewRoot.Instance.Reparent(S_ToolRoot.Instance, false);
  227. }
  228. }
  229.  
  230. /// <summary>
  231. /// 设置当前活动的标记
  232. /// </summary>
  233. public void SetActiveMark(MarkTool markTool)
  234. {
  235. if (ActiveMark == markTool)
  236. {
  237. return;
  238. }
  239.  
  240. if (ActiveMark != null)
  241. {
  242. ActiveMark.Modulate = Colors.White;
  243. }
  244. ActiveMark = markTool;
  245. if (markTool != null)
  246. {
  247. markTool.Modulate = Colors.Green;
  248. EventManager.EmitEvent(EventEnum.OnSelectMark, markTool.MarkInfo);
  249. }
  250. else
  251. {
  252. EventManager.EmitEvent(EventEnum.OnSelectMark);
  253. }
  254. }
  255.  
  256. /// <summary>
  257. /// 创建门区域设置工具
  258. /// </summary>
  259. /// <param name="doorAreaInfo">门区域数据</param>
  260. public DoorToolTemplate CreateDoorTool(DoorAreaInfo doorAreaInfo)
  261. {
  262. var doorHoverArea = GetDoorHoverArea(doorAreaInfo.Direction);
  263. var inst = CreateDoorToolInstance(doorHoverArea);
  264. inst.Instance.DoorAreaInfo = doorAreaInfo;
  265. inst.Instance.SetDoorAreaPosition(GetDoorHoverAreaRoot(doorAreaInfo.Direction).Position);
  266. inst.Instance.SetDoorAreaRange(doorAreaInfo.Start, doorAreaInfo.End);
  267. return inst;
  268. }
  269.  
  270. /// <summary>
  271. /// 创建拖拽状态下的门区域工具, 用于创建门区域
  272. /// </summary>
  273. /// <param name="doorHoverArea">悬停区域</param>
  274. /// <param name="start">起始位置, 单位: 像素</param>
  275. /// <param name="onSubmit">成功提交时回调, 参数1为方向, 参数2为起始点, 参数3为大小</param>
  276. /// <param name="onCancel">取消提交时调用</param>
  277. public DoorToolTemplate CreateDragDoorTool(DoorHoverArea doorHoverArea, int start,
  278. Action<DoorDirection, int, int> onSubmit, Action onCancel)
  279. {
  280. var inst = CreateDoorToolInstance(doorHoverArea);
  281. inst.Instance.SetDoorAreaPosition(GetDoorHoverAreaRoot(doorHoverArea.Direction).Position);
  282. inst.Instance.SetDoorAreaRange(start, start);
  283. inst.Instance.MakeDragMode(onSubmit, () =>
  284. {
  285. RemoveDoorTool(inst);
  286. onCancel();
  287. });
  288. return inst;
  289. }
  290.  
  291. /// <summary>
  292. /// 移除门区域设置工具
  293. /// </summary>
  294. public void RemoveDoorTool(DoorToolTemplate toolInstance)
  295. {
  296. _doorTools.Remove(toolInstance);
  297. if (toolInstance.Instance.DoorAreaInfo != null)
  298. {
  299. EditorMap.Instance.RemoveDoorArea(toolInstance.Instance.DoorAreaInfo);
  300. }
  301. toolInstance.Instance.QueueFree();
  302. }
  303.  
  304. /// <summary>
  305. /// 设置工具根节点的大小和缩放
  306. /// </summary>
  307. /// <param name="pos">坐标</param>
  308. /// <param name="scale">缩放</param>
  309. public void SetToolTransform(Vector2 pos, Vector2 scale)
  310. {
  311. S_ToolRoot.Instance.Position = pos;
  312. S_ToolRoot.Instance.Scale = scale;
  313. }
  314.  
  315. /// <summary>
  316. /// 设置鼠标悬停区域位置和大小
  317. /// </summary>
  318. /// <param name="position">房间起始点, 单位: 格</param>
  319. /// <param name="size">房间大小, 单位: 格</param>
  320. public void SetDoorHoverToolTransform(Vector2I position, Vector2I size)
  321. {
  322. position *= GameConfig.TileCellSize;
  323. size *= GameConfig.TileCellSize;
  324.  
  325. var nPos1 = S_N_HoverRoot.Instance.Position;
  326. var ePos1 = S_E_HoverRoot.Instance.Position;
  327. var sPos1 = S_S_HoverRoot.Instance.Position;
  328. var wPos1 = S_W_HoverRoot.Instance.Position;
  329. var nPos2 = position + GameConfig.TileCellSizeVector2I;
  330. var ePos2 = new Vector2(position.X + size.X - GameConfig.TileCellSize, position.Y + GameConfig.TileCellSize);
  331. var sPos2 = new Vector2(position.X + GameConfig.TileCellSize, position.Y + size.Y - GameConfig.TileCellSize);
  332. var wPos2 = position + GameConfig.TileCellSizeVector2I;
  333.  
  334. var nSize2 = new Vector2(size.X - GameConfig.TileCellSize * 2, S_N_HoverArea.Instance.Size.Y);
  335. var eSize2 = new Vector2(size.Y - GameConfig.TileCellSize * 2, S_E_HoverArea.Instance.Size.Y);
  336. var sSize2 = new Vector2(size.X - GameConfig.TileCellSize * 2, S_S_HoverArea.Instance.Size.Y);
  337. var wSize2 = new Vector2(size.Y - GameConfig.TileCellSize * 2, S_W_HoverArea.Instance.Size.Y);
  338. S_N_HoverRoot.Instance.Position = nPos2;
  339. S_E_HoverRoot.Instance.Position = ePos2;
  340. S_S_HoverRoot.Instance.Position = sPos2;
  341. S_W_HoverRoot.Instance.Position = wPos2;
  342. S_N_HoverArea.Instance.Size = nSize2;
  343. S_E_HoverArea.Instance.Size = eSize2;
  344. S_S_HoverArea.Instance.Size = sSize2;
  345. S_W_HoverArea.Instance.Size = wSize2;
  346. //调整门区域
  347. for (var i = 0; i < _doorTools.Count; i++)
  348. {
  349. var doorTool = _doorTools[i];
  350. var direction = doorTool.Instance.Direction;
  351. var areaRoot = GetDoorHoverAreaRoot(direction);
  352. var doorAreaRange = doorTool.Instance.GetDoorAreaRange();
  353. doorTool.Instance.SetDoorAreaPosition(areaRoot.Position);
  354.  
  355. if (direction == DoorDirection.N)
  356. {
  357. var hOffset = (int)(nPos2.X - nPos1.X);
  358. doorAreaRange.X -= hOffset;
  359. doorAreaRange.Y -= hOffset;
  360.  
  361. if (doorAreaRange.X >= 0 && doorAreaRange.Y <= nSize2.X) //允许提交
  362. {
  363. doorTool.Instance.SetDoorAreaRange(doorAreaRange.X, doorAreaRange.Y);
  364. if (doorTool.Instance.DoorAreaInfo != null)
  365. {
  366. doorTool.Instance.DoorAreaInfo.Start = doorAreaRange.X;
  367. doorTool.Instance.DoorAreaInfo.End = doorAreaRange.Y;
  368. }
  369. }
  370. else //如果超出区域, 则删除
  371. {
  372. RemoveDoorTool(doorTool);
  373. i--;
  374. }
  375. }
  376. else if (direction == DoorDirection.S)
  377. {
  378. var hOffset = (int)(sPos2.X - sPos1.X);
  379. doorAreaRange.X -= hOffset;
  380. doorAreaRange.Y -= hOffset;
  381.  
  382. if (doorAreaRange.X >= 0 && doorAreaRange.Y <= sSize2.X) //允许提交
  383. {
  384. doorTool.Instance.SetDoorAreaRange(doorAreaRange.X, doorAreaRange.Y);
  385. if (doorTool.Instance.DoorAreaInfo != null)
  386. {
  387. doorTool.Instance.DoorAreaInfo.Start = doorAreaRange.X;
  388. doorTool.Instance.DoorAreaInfo.End = doorAreaRange.Y;
  389. }
  390. }
  391. else //如果超出区域, 则删除
  392. {
  393. RemoveDoorTool(doorTool);
  394. i--;
  395. }
  396. }
  397. else if (direction == DoorDirection.E)
  398. {
  399. var vOffset = (int)(ePos2.Y - ePos1.Y);
  400. doorAreaRange.X -= vOffset;
  401. doorAreaRange.Y -= vOffset;
  402.  
  403. if (doorAreaRange.X >= 0 && doorAreaRange.Y <= eSize2.X) //允许提交
  404. {
  405. doorTool.Instance.SetDoorAreaRange(doorAreaRange.X, doorAreaRange.Y);
  406. if (doorTool.Instance.DoorAreaInfo != null)
  407. {
  408. doorTool.Instance.DoorAreaInfo.Start = doorAreaRange.X;
  409. doorTool.Instance.DoorAreaInfo.End = doorAreaRange.Y;
  410. }
  411. }
  412. else //如果超出区域, 则删除
  413. {
  414. RemoveDoorTool(doorTool);
  415. i--;
  416. }
  417. }
  418. else if (direction == DoorDirection.W)
  419. {
  420. var vOffset = (int)(wPos2.Y - wPos1.Y);
  421. doorAreaRange.X -= vOffset;
  422. doorAreaRange.Y -= vOffset;
  423.  
  424. if (doorAreaRange.X >= 0 && doorAreaRange.Y <= wSize2.X) //允许提交
  425. {
  426. doorTool.Instance.SetDoorAreaRange(doorAreaRange.X, doorAreaRange.Y);
  427. if (doorTool.Instance.DoorAreaInfo != null)
  428. {
  429. doorTool.Instance.DoorAreaInfo.Start = doorAreaRange.X;
  430. doorTool.Instance.DoorAreaInfo.End = doorAreaRange.Y;
  431. }
  432. }
  433. else //如果超出区域, 则删除
  434. {
  435. RemoveDoorTool(doorTool);
  436. i--;
  437. }
  438. }
  439. }
  440. }
  441. private DoorToolTemplate CreateDoorToolInstance(DoorHoverArea doorHoverArea)
  442. {
  443. var doorTool = S_DoorToolTemplate.Clone();
  444. S_ToolRoot.Instance.AddChild(doorTool.Instance);
  445. doorTool.Instance.SetDoorDragAreaNode(doorTool);
  446. doorTool.L_StartBtn.Instance.SetMapEditorToolsPanel(this);
  447. doorTool.L_EndBtn.Instance.SetMapEditorToolsPanel(this);
  448. doorTool.Instance.SetDoorHoverArea(doorHoverArea);
  449. _doorTools.Add(doorTool);
  450. return doorTool;
  451. }
  452. }