Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / ui / tileSetEditorTerrain / TileSetEditorTerrainPanel.cs
@小李xl 小李xl on 14 Jan 2024 17 KB 修复TerrainCell遮挡页签的bug
  1. using Godot;
  2. using UI.TileSetEditor;
  3.  
  4. namespace UI.TileSetEditorTerrain;
  5.  
  6. public partial class TileSetEditorTerrainPanel : TileSetEditorTerrain
  7. {
  8. /// <summary>
  9. /// 父Ui
  10. /// </summary>
  11. public TileSetEditorPanel EditorPanel;
  12.  
  13. /// <summary>
  14. /// 当前选中的地形索引
  15. /// </summary>
  16. public int CurrTerrainIndex => TerrainTabGrid.SelectIndex;
  17.  
  18. /// <summary>
  19. /// 当前选中的地形
  20. /// </summary>
  21. public TileSetTerrainInfo CurrTerrain
  22. {
  23. get
  24. {
  25. var terrain = EditorPanel.TileSetSourceInfo.Terrain;
  26. if (CurrTerrainIndex < 0 || CurrTerrainIndex >= terrain.Count)
  27. {
  28. return null;
  29. }
  30. return terrain[CurrTerrainIndex];
  31. }
  32. }
  33. /// <summary>
  34. /// 正在拖拽的图块
  35. /// </summary>
  36. public MaskCell DraggingCell { get; set; }
  37.  
  38. public UiGrid<TerrainTab, TileSetTerrainInfo> TerrainTabGrid;
  39. public UiGrid<RightCell, byte> TerrainGrid3x3;
  40. public UiGrid<RightCell, byte> TerrainGrid2x2;
  41. public UiGrid<RightCell, byte> TerrainGridMiddle;
  42. public UiGrid<RightCell, byte> TerrainGridFloor;
  43. public UiGrid<BottomCell, Rect2I> MaskGrid;
  44.  
  45. private bool _refreshGridConnect = false;
  46.  
  47. public override void OnCreateUi()
  48. {
  49. EditorPanel = (TileSetEditorPanel)ParentUi;
  50. S_DragSprite.Instance.Visible = false;
  51. //改变选中的TileSet资源
  52. AddEventListener(EventEnum.OnSelectTileSetSource, OnSelectTileSetSource);
  53. //改变纹理事件
  54. AddEventListener(EventEnum.OnSetTileTexture, (data) =>
  55. {
  56. OnSetTileTexture(data);
  57. if (TerrainTabGrid.SelectIndex >= 0)
  58. {
  59. OnChangeTerrain(TerrainTabGrid.SelectIndex);
  60. }
  61. });
  62. //背景颜色改变
  63. AddEventListener(EventEnum.OnSetTileSetBgColor, OnChangeTileSetBgColor);
  64.  
  65. //地形页签
  66. TerrainTabGrid = CreateUiGrid<TerrainTab, TileSetTerrainInfo, TerrainTabCell>(S_TerrainTab);
  67. TerrainTabGrid.SetCellOffset(Vector2I.Zero);
  68. TerrainTabGrid.SetColumns(1);
  69. TerrainTabGrid.SetHorizontalExpand(true);
  70.  
  71. MaskGrid = CreateUiGrid<BottomCell, Rect2I, MaskCell>(S_BottomCell);
  72. MaskGrid.SetCellOffset(Vector2I.Zero);
  73. MaskGrid.GridContainer.MouseFilter = MouseFilterEnum.Ignore;
  74.  
  75. TerrainGrid3x3 = InitTopGrid(S_TerrainRoot.L_TerrainTexture1.Instance, GameConfig.TerrainBit3x3, TileSetTerrainInfo.TerrainLayerType);
  76. TerrainGrid2x2 = InitTopGrid(S_TerrainRoot.L_TerrainTexture4.Instance, GameConfig.TerrainBit2x2, TileSetTerrainInfo.TerrainLayerType);
  77. TerrainGridMiddle = InitTopGrid(S_TerrainRoot.L_TerrainTexture2.Instance, GameConfig.TerrainBitMiddle, TileSetTerrainInfo.MiddleLayerType);
  78. TerrainGridFloor = InitTopGrid(S_TerrainRoot.L_TerrainTexture3.Instance, GameConfig.TerrainBitFloor, TileSetTerrainInfo.FloorLayerType);
  79. //删除地形按钮
  80. S_DeleteButton.Instance.Pressed += OnDeleteTerrainClick;
  81. //添加地形按钮
  82. S_AddButton.Instance.Pressed += OnAddTerrainClick;
  83. //编辑地形
  84. S_EditButton.Instance.Pressed += OnEditTerrainClick;
  85. OnSetTileTexture(EditorPanel.Texture);
  86. OnChangeTileSetBgColor(EditorPanel.BgColor);
  87. OnChangeTerrainType(-1);
  88. //改变选中的地形
  89. TerrainTabGrid.SelectEvent += OnChangeTerrain;
  90. }
  91.  
  92. public override void OnDestroyUi()
  93. {
  94. }
  95.  
  96. public override void Process(float delta)
  97. {
  98. S_MaskBrush.Instance.Visible = DraggingCell == null;
  99.  
  100. if (_refreshGridConnect)
  101. {
  102. _refreshGridConnect = false;
  103.  
  104. var terrainList = EditorPanel.TileSetSourceInfo.Terrain;
  105. for (var i = 0; i < terrainList.Count; i++)
  106. {
  107. var terrain = terrainList[i];
  108. if (terrain.TerrainType == 0) //选中47格Terrain
  109. {
  110. TerrainGrid3x3.ForEach(cell => RefreshTerrainCellUseFlag(terrain, cell));
  111. if (EditorPanel.TileSetSourceIndex == 0 && CurrTerrainIndex == 0) //选中Main Source
  112. {
  113. TerrainGridMiddle.ForEach(cell => RefreshTerrainCellUseFlag(terrain, cell));
  114. TerrainGridFloor.ForEach(cell => RefreshTerrainCellUseFlag(terrain, cell));
  115. }
  116. }
  117. else //选中13格Terrain
  118. {
  119. TerrainGrid2x2.ForEach(cell => RefreshTerrainCellUseFlag(terrain, cell));
  120. }
  121. }
  122. }
  123. }
  124.  
  125. private UiGrid<RightCell, byte> InitTopGrid(Control texture, Vector2I size, byte type)
  126. {
  127. var cellRoot = S_TopBg.L_TerrainRoot.L_CellRoot;
  128. var sRightCell = cellRoot.L_RightCell;
  129. sRightCell.Instance.Position = texture.Position;
  130. var grid = CreateUiGrid<RightCell, byte, TerrainCell>(sRightCell, cellRoot.Instance);
  131. grid.GridContainer.MouseFilter = MouseFilterEnum.Ignore;
  132. grid.SetCellOffset(Vector2I.Zero);
  133. grid.SetColumns(size.X);
  134. for (var y = 0; y < size.Y; y++)
  135. {
  136. for (var x = 0; x < size.X; x++)
  137. {
  138. grid.Add(type);
  139. }
  140. }
  141. return grid;
  142. }
  143.  
  144. //改变选中的TileSet资源
  145. private void OnSelectTileSetSource(object obj)
  146. {
  147. TerrainTabGrid.RemoveAll();
  148. //加载Terrain
  149. if (obj != null)
  150. {
  151. var terrainList = ((TileSetSourceInfo)obj).Terrain;
  152. if (terrainList.Count > 0)
  153. {
  154. TerrainTabGrid.SetDataList(terrainList.ToArray());
  155. TerrainTabGrid.SelectIndex = 0;
  156. }
  157. }
  158. }
  159.  
  160. private void SetTerrainCellData(TileSetTerrainInfo terrain, UiCell<RightCell, byte> cell)
  161. {
  162. var data = terrain.GetTerrainCell(cell.Index, cell.Data);
  163. if (data != null)
  164. {
  165. var terrainCell = (TerrainCell)cell;
  166. var x = data[0];
  167. var y = data[1];
  168. terrainCell.SetCell(new Rect2I(x, y, GameConfig.TileCellSize, GameConfig.TileCellSize));
  169. }
  170. }
  171. private void RefreshConnectTerrainCell(TileSetTerrainInfo terrain, UiCell<RightCell, byte> cell)
  172. {
  173. var data = terrain.GetTerrainCell(cell.Index, cell.Data);
  174. if (data != null)
  175. {
  176. var terrainCell = (TerrainCell)cell;
  177. var x = data[0];
  178. var y = data[1];
  179. var index = x / GameConfig.TileCellSize + y / GameConfig.TileCellSize * MaskGrid.GetColumns();
  180. var maskCell = (MaskCell)MaskGrid.GetCell(index);
  181. if (maskCell != null)
  182. {
  183. //绑定TerrainCell
  184. maskCell.SetConnectTerrainCell(terrainCell);
  185. }
  186. }
  187. }
  188. private void RefreshTerrainCellUseFlag(TileSetTerrainInfo terrain, UiCell<RightCell, byte> cell)
  189. {
  190. var data = terrain.GetTerrainCell(cell.Index, cell.Data);
  191. if (data != null)
  192. {
  193. var x = data[0];
  194. var y = data[1];
  195. var index = x / GameConfig.TileCellSize + y / GameConfig.TileCellSize * MaskGrid.GetColumns();
  196. var maskCell = (MaskCell)MaskGrid.GetCell(index);
  197. if (maskCell != null)
  198. {
  199. maskCell.SetUseFlag(true);
  200. }
  201. }
  202. }
  203.  
  204. /// <summary>
  205. /// 放置地形Cell纹理
  206. /// </summary>
  207. public void OnDropCell(MaskCell maskCell)
  208. {
  209. var terrain = CurrTerrain;
  210. if (terrain == null)
  211. {
  212. return;
  213. }
  214. if (terrain.TerrainType == 0) //选中47个Terrain
  215. {
  216. var flag = true;
  217. TerrainGrid3x3.ForEach((cell) =>
  218. {
  219. flag = !((TerrainCell)cell).OnDropCell(maskCell);
  220. return flag;
  221. });
  222. if (EditorPanel.TileSetSourceIndex == 0 && CurrTerrainIndex == 0) //选中Main Source
  223. {
  224. if (flag)
  225. {
  226. TerrainGridMiddle.ForEach((cell) =>
  227. {
  228. flag = !((TerrainCell)cell).OnDropCell(maskCell);
  229. return flag;
  230. });
  231. }
  232. if (flag)
  233. {
  234. TerrainGridFloor.ForEach((cell) =>
  235. {
  236. return ((TerrainCell)cell).OnDropCell(maskCell);
  237. });
  238. }
  239. }
  240. }
  241. else //选中13格Terrain
  242. {
  243. TerrainGrid2x2.ForEach((cell) =>
  244. {
  245. return !((TerrainCell)cell).OnDropCell(maskCell);
  246. });
  247. }
  248. }
  249. //改变TileSet纹理
  250. private void OnSetTileTexture(object arg)
  251. {
  252. S_BottomBg.Instance.OnChangeTileSetTexture();
  253.  
  254. MaskGrid.RemoveAll();
  255. var cellHorizontal = EditorPanel.CellHorizontal;
  256. if (cellHorizontal <= 0)
  257. {
  258. return;
  259. }
  260. var cellVertical = EditorPanel.CellVertical;
  261. MaskGrid.SetColumns(cellHorizontal);
  262. for (var y = 0; y < cellVertical; y++)
  263. {
  264. for (var x = 0; x < cellHorizontal; x++)
  265. {
  266. MaskGrid.Add(new Rect2I(x * GameConfig.TileCellSize, y * GameConfig.TileCellSize, GameConfig.TileCellSize, GameConfig.TileCellSize));
  267. }
  268. }
  269.  
  270. _refreshGridConnect = true;
  271. }
  272. //更改背景颜色
  273. private void OnChangeTileSetBgColor(object obj)
  274. {
  275. S_BottomBg.Instance.Color = EditorPanel.BgColor;
  276. S_TopBg.Instance.Color = EditorPanel.BgColor;
  277. }
  278.  
  279. //切换选中的地形
  280. private void OnChangeTerrain(int index)
  281. {
  282. //清除所有绑定的Terrain
  283. if (index >= 0)
  284. {
  285. TerrainGrid3x3.ForEach(cell => ((TerrainCell)cell).ClearCellTexture());
  286. TerrainGridMiddle.ForEach(cell => ((TerrainCell)cell).ClearCellTexture());
  287. TerrainGridFloor.ForEach(cell => ((TerrainCell)cell).ClearCellTexture());
  288. TerrainGrid2x2.ForEach(cell => ((TerrainCell)cell).ClearCellTexture());
  289. }
  290. S_TopBg.Instance.SetHoverCell(null);
  291. S_BottomBg.Instance.SetHoverCell(null);
  292. MaskGrid.ForEach(cell =>
  293. {
  294. ((MaskCell)cell).SetConnectTerrainCell(null);
  295. });
  296. var terrain = CurrTerrain;
  297. if (terrain != null)
  298. {
  299. if (terrain.TerrainType == 0) //选中47个Terrain
  300. {
  301. TerrainGrid3x3.ForEach(cell =>
  302. {
  303. SetTerrainCellData(terrain, cell);
  304. RefreshConnectTerrainCell(terrain, cell);
  305. });
  306. if (EditorPanel.TileSetSourceIndex == 0 && CurrTerrainIndex == 0) //选中Main Source
  307. {
  308. TerrainGridMiddle.ForEach(cell =>
  309. {
  310. SetTerrainCellData(terrain, cell);
  311. RefreshConnectTerrainCell(terrain, cell);
  312. });
  313. TerrainGridFloor.ForEach(cell =>
  314. {
  315. SetTerrainCellData(terrain, cell);
  316. RefreshConnectTerrainCell(terrain, cell);
  317. });
  318. }
  319. }
  320. else //选中13格Terrain
  321. {
  322. TerrainGrid2x2.ForEach(cell =>
  323. {
  324. SetTerrainCellData(terrain, cell);
  325. RefreshConnectTerrainCell(terrain, cell);
  326. });
  327. }
  328. }
  329. if (index >= 0)
  330. {
  331. OnChangeTerrainType(TerrainTabGrid.GetCell(index).Data.TerrainType);
  332. }
  333. else
  334. {
  335. OnChangeTerrainType(-1);
  336. }
  337. }
  338. /// <summary>
  339. /// 切换Terrain类型
  340. /// </summary>
  341. private void OnChangeTerrainType(long index)
  342. {
  343. if (EditorPanel.TileSetSourceIndex == 0 && CurrTerrainIndex == 0) //选中 Main Source
  344. {
  345. S_TerrainTexture2.Instance.Visible = true;
  346. S_TerrainTexture3.Instance.Visible = true;
  347. TerrainGridMiddle.Visible = true;
  348. TerrainGridFloor.Visible = true;
  349. S_TerrainTexture1.L_Label.Instance.Text = "顶部墙壁";
  350. }
  351. else
  352. {
  353. S_TerrainTexture2.Instance.Visible = false;
  354. S_TerrainTexture3.Instance.Visible = false;
  355. TerrainGridMiddle.Visible = false;
  356. TerrainGridFloor.Visible = false;
  357. S_TerrainTexture1.L_Label.Instance.Text = "地形";
  358. }
  359. if (index == 0) //47 格子
  360. {
  361. S_TerrainRoot.L_TerrainTexture1.Instance.Visible = true;
  362. TerrainGrid3x3.Visible = true;
  363. S_TerrainRoot.L_TerrainTexture4.Instance.Visible = false;
  364. TerrainGrid2x2.Visible = false;
  365. }
  366. else if (index == 1) //13 格子
  367. {
  368. S_TerrainRoot.L_TerrainTexture1.Instance.Visible = false;
  369. TerrainGrid3x3.Visible = false;
  370. S_TerrainRoot.L_TerrainTexture4.Instance.Visible = true;
  371. TerrainGrid2x2.Visible = true;
  372. }
  373. else
  374. {
  375. S_TerrainRoot.L_TerrainTexture1.Instance.Visible = false;
  376. TerrainGrid3x3.Visible = false;
  377. S_TerrainRoot.L_TerrainTexture4.Instance.Visible = false;
  378. TerrainGrid2x2.Visible = false;
  379. }
  380. }
  381.  
  382. //删除地形
  383. private void OnDeleteTerrainClick()
  384. {
  385. if (EditorPanel.TileSetSourceIndex == 0 && CurrTerrainIndex == 0) //不能删除 Main Terrain
  386. {
  387. EditorWindowManager.ShowTips("警告", "不允许删除 Main Terrain!");
  388. return;
  389. }
  390.  
  391. var terrain = CurrTerrain;
  392. if (terrain != null)
  393. {
  394. EditorWindowManager.ShowConfirm("提示", $"是否删除地形'{terrain.Name}'?", (v) =>
  395. {
  396. if (v)
  397. {
  398. var index = TerrainTabGrid.SelectIndex;
  399. //执行删除操作
  400. //清除Mask
  401. if (terrain.TerrainType == 0) //47格
  402. {
  403. TerrainGrid3x3.ForEach(cell =>
  404. {
  405. var terrainCell = (TerrainCell)cell;
  406. terrainCell.ClearCellTexture();
  407. if (terrainCell.ConnectMaskCell != null)
  408. {
  409. terrainCell.ConnectMaskCell.SetUseFlag(false);
  410. terrainCell.ConnectMaskCell.SetConnectTerrainCell(null);
  411. }
  412. });
  413. }
  414. else //13格
  415. {
  416. TerrainGrid2x2.ForEach(cell =>
  417. {
  418. var terrainCell = (TerrainCell)cell;
  419. terrainCell.ClearCellTexture();
  420. if (terrainCell.ConnectMaskCell != null)
  421. {
  422. terrainCell.ConnectMaskCell.SetUseFlag(false);
  423. terrainCell.ConnectMaskCell.SetConnectTerrainCell(null);
  424. }
  425. });
  426. }
  427. EditorPanel.TileSetSourceInfo.Terrain.Remove(terrain);
  428. TerrainTabGrid.RemoveByIndex(index);
  429. if (index == TerrainTabGrid.Count)
  430. {
  431. TerrainTabGrid.SelectIndex = TerrainTabGrid.Count - 1;
  432. }
  433. else
  434. {
  435. TerrainTabGrid.SelectIndex = index;
  436. }
  437. EventManager.EmitEvent(EventEnum.OnTileMapDirty);
  438. }
  439. });
  440. }
  441. else
  442. {
  443. EditorWindowManager.ShowTips("提示", "清选择一个Terrain!");
  444. }
  445. }
  446.  
  447. //创建地形
  448. private void OnAddTerrainClick()
  449. {
  450. EditorWindowManager.ShowCreateTerrain(EditorPanel.TileSetSourceInfo, terrainInfo =>
  451. {
  452. //执行添加操作
  453. EditorPanel.TileSetSourceInfo.Terrain.Add(terrainInfo);
  454. TerrainTabGrid.Add(terrainInfo, true);
  455. EventManager.EmitEvent(EventEnum.OnTileMapDirty);
  456. });
  457. }
  458. //编辑地形(重命名)
  459. private void OnEditTerrainClick()
  460. {
  461. if (EditorPanel.TileSetSourceIndex == 0 && CurrTerrainIndex == 0) //不能删除 Main Terrain
  462. {
  463. EditorWindowManager.ShowTips("警告", "不允许重命名 Main Terrain!");
  464. return;
  465. }
  466. var terrain = CurrTerrain;
  467. if (terrain != null)
  468. {
  469. EditorWindowManager.ShowInput("提示", $"是否删除地形'{terrain.Name}'?", terrain.Name, (v, isClose) =>
  470. {
  471. if (string.IsNullOrEmpty(v))
  472. {
  473. EditorWindowManager.ShowTips("错误", $"名称不允许为空!");
  474. return false;
  475. }
  476. if (terrain.Name != v && EditorPanel.TileSetSourceInfo.Terrain.FindIndex(info => info.Name == v) >= 0)
  477. {
  478. EditorWindowManager.ShowTips("错误", $"已经有相同名称的Terrain了!");
  479. return false;
  480. }
  481.  
  482. terrain.Name = v;
  483. //刷新页签
  484. ((TerrainTabCell)TerrainTabGrid.GetCell(CurrTerrainIndex)).RefreshData();
  485. EventManager.EmitEvent(EventEnum.OnTileMapDirty);
  486. return true;
  487. });
  488. }
  489. else
  490. {
  491. EditorWindowManager.ShowTips("提示", "清选择一个Terrain!");
  492. }
  493. }
  494. }