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