Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / ui / mapEditor / tileView / EditorTileMap.cs
@小李xl 小李xl on 18 Jan 2024 53 KB TileMap编辑器绘制组合
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Godot;
  5. using Godot.Collections;
  6. using UI.MapEditorTools;
  7.  
  8. namespace UI.MapEditor;
  9.  
  10. public partial class EditorTileMap : TileMap, IUiNodeScript
  11. {
  12. public enum MouseButtonType
  13. {
  14. /// <summary>
  15. /// 无状态
  16. /// </summary>
  17. None,
  18. /// <summary>
  19. /// 拖拽模式
  20. /// </summary>
  21. Drag,
  22. /// <summary>
  23. /// 笔
  24. /// </summary>
  25. Pen,
  26. /// <summary>
  27. /// 绘制区域模式
  28. /// </summary>
  29. Area,
  30. /// <summary>
  31. /// 编辑工具模式
  32. /// </summary>
  33. Edit,
  34. }
  35. public enum TileMapDrawMode
  36. {
  37. /// <summary>
  38. /// 无状态
  39. /// </summary>
  40. None,
  41. /// <summary>
  42. /// 自由绘制
  43. /// </summary>
  44. Free,
  45. /// <summary>
  46. /// 地形绘制
  47. /// </summary>
  48. Terrain,
  49. /// <summary>
  50. /// 组合绘制
  51. /// </summary>
  52. Combination
  53. }
  54.  
  55. /// <summary>
  56. /// 所属地图编辑器UI
  57. /// </summary>
  58. public MapEditorPanel MapEditorPanel { get; private set; }
  59. /// <summary>
  60. /// 编辑器工具UI
  61. /// </summary>
  62. public MapEditorToolsPanel MapEditorToolsPanel { get; set; }
  63. /// <summary>
  64. /// 左键功能
  65. /// </summary>
  66. public MouseButtonType MouseType { get; private set; } = MouseButtonType.Pen;
  67. //鼠标坐标
  68. private Vector2 _mousePosition;
  69. //鼠标所在的cell坐标
  70. private Vector2I _mouseCellPosition;
  71. //上一帧鼠标所在的cell坐标
  72. private Vector2I _prevMouseCellPosition = new Vector2I(-99999, -99999);
  73. //单次绘制是否改变过tile数据
  74. private bool _changeFlag = false;
  75. //左键开始按下时鼠标所在的坐标
  76. private Vector2I _mouseStartCellPosition;
  77. //鼠标中建是否按下
  78. private bool _isMiddlePressed = false;
  79. private Vector2 _moveOffset;
  80. //左键是否按下
  81. private bool _isLeftPressed = false;
  82. //右键是否按下
  83. private bool _isRightPressed = false;
  84. //绘制填充区域
  85. private bool _drawFullRect = false;
  86. //负责存储自动图块数据
  87. private InfiniteGrid<bool> _autoCellLayerGrid = new InfiniteGrid<bool>();
  88. //停止绘制多久后开始执行生成操作
  89. private float _generateInterval = 3f;
  90. //生成自动图块和导航网格的计时器
  91. private float _generateTimer = -1;
  92. //检测地形结果
  93. private bool _checkTerrainFlag = true;
  94. //错误地形位置
  95. private Vector2I _checkTerrainErrorPosition = Vector2I.Zero;
  96. //是否执行生成地形成功
  97. private bool _isGenerateTerrain = true;
  98. //导航网格数据
  99. private Vector2[][] _polygonData;
  100. private bool _initLayer = false;
  101.  
  102. //--------- 配置数据 -------------
  103. private int _mainSource = 0;
  104. private int _mainTerrainSet = 0;
  105. private int _mainTerrain = 0;
  106. private AutoTileConfig _autoTileConfig;
  107.  
  108. /// <summary>
  109. /// 正在编辑的房间数据
  110. /// </summary>
  111. public DungeonRoomSplit CurrRoomSplit;
  112. /// <summary>
  113. /// 数据是否脏了, 也就是是否有修改
  114. /// </summary>
  115. public bool IsDirty { get; private set; }
  116.  
  117. /// <summary>
  118. /// 地图是否有绘制错误
  119. /// </summary>
  120. public bool HasTerrainError => !_isGenerateTerrain;
  121. /// <summary>
  122. /// 当前选择的图层
  123. /// </summary>
  124. public TileMapLayerData CurrLayer { get; private set; }
  125. /// <summary>
  126. /// 当前正在使用的 TileSetSplit 数据
  127. /// </summary>
  128. public TileSetSplit CurrentTileSet { get; private set; }
  129. /// <summary>
  130. /// 当前正在使用的 Source
  131. /// </summary>
  132. public TileSetSourceInfo CurrSource => CurrentTileSet.TileSetInfo.Sources[CurrSourceIndex];
  133.  
  134. /// <summary>
  135. /// 当前正在使用的 Source 索引
  136. /// </summary>
  137. public int CurrSourceIndex { get; private set; }
  138. /// <summary>
  139. /// 当前笔刷类型
  140. /// </summary>
  141. public TileMapDrawMode CurrBrushType { get; private set; }
  142.  
  143. /// <summary>
  144. /// 当前笔刷使用的 AtlasCoords,, key: position, value: atlasCoords, 单位: 格
  145. /// </summary>
  146. public System.Collections.Generic.Dictionary<Vector2I, Vector2I> CurrBrush { get; } = new System.Collections.Generic.Dictionary<Vector2I, Vector2I>();
  147. /// <summary>
  148. /// 当前笔刷使用的纹理
  149. /// </summary>
  150. public Texture2D CurrBrushTexture { get; private set; }
  151.  
  152. //笔刷偏移, 单位: 格
  153. private Vector2I _brushOffset = Vector2I.Zero;
  154. //淡化其它层级
  155. private bool _desaltOtherLayer = false;
  156. //--------------------------------------- 变动过的数据 ---------------------------------------
  157. /// <summary>
  158. /// 地图位置, 单位: 格
  159. /// </summary>
  160. public Vector2I CurrRoomPosition { get; private set; }
  161. /// <summary>
  162. /// 当前地图大小, 单位: 格
  163. /// </summary>
  164. public Vector2I CurrRoomSize { get; private set; }
  165. /// <summary>
  166. /// 当前编辑的门数据
  167. /// </summary>
  168. public List<DoorAreaInfo> CurrDoorConfigs { get; } = new List<DoorAreaInfo>();
  169.  
  170. /// <summary>
  171. /// 是否绘制房间中的辅助标记
  172. /// </summary>
  173. public bool IsDrawMark { get; set; } = true;
  174.  
  175. //-------------------------------
  176. private MapEditor.TileMap _editorTileMap;
  177. private EventFactory _eventFactory;
  178. private Vector2I _cacheToolSizeData;
  179. public void SetUiNode(IUiNode uiNode)
  180. {
  181. _editorTileMap = (MapEditor.TileMap)uiNode;
  182. MapEditorPanel = _editorTileMap.UiPanel;
  183. MapEditorToolsPanel = _editorTileMap.UiPanel.S_MapEditorTools.Instance;
  184.  
  185. _editorTileMap.L_Brush.Instance.Draw += DrawGuides;
  186. _eventFactory = EventManager.CreateEventFactory();
  187. _eventFactory.AddEventListener(EventEnum.OnSelectDragTool, OnSelectHandTool);
  188. _eventFactory.AddEventListener(EventEnum.OnSelectPenTool, OnSelectPenTool);
  189. _eventFactory.AddEventListener(EventEnum.OnSelectRectTool, OnSelectRectTool);
  190. _eventFactory.AddEventListener(EventEnum.OnSelectEditTool, OnSelectEditTool);
  191. _eventFactory.AddEventListener(EventEnum.OnClickCenterTool, OnClickCenterTool);
  192. _eventFactory.AddEventListener(EventEnum.OnTileMapDirty, OnEditorDirty);
  193.  
  194. RenderingServer.FramePostDraw += OnFramePostDraw;
  195. var navigationRegion = _editorTileMap.L_NavigationRegion.Instance;
  196. navigationRegion.Visible = false;
  197. navigationRegion.NavigationPolygon.AgentRadius = GameConfig.NavigationAgentRadius;
  198. navigationRegion.BakeFinished += OnBakeFinished;
  199. }
  200.  
  201. public void OnDestroy()
  202. {
  203. _eventFactory.RemoveAllEventListener();
  204. RenderingServer.FramePostDraw -= OnFramePostDraw;
  205. }
  206.  
  207. public override void _Process(double delta)
  208. {
  209. if (!_initLayer)
  210. {
  211. return;
  212. }
  213. //触发绘制辅助线
  214. _editorTileMap.L_Brush.Instance.QueueRedraw();
  215. var newDelta = (float)delta;
  216. _drawFullRect = false;
  217. var position = GetLocalMousePosition();
  218. _mouseCellPosition = LocalToMap(position);
  219. _mousePosition = new Vector2(
  220. _mouseCellPosition.X * GameConfig.TileCellSize,
  221. _mouseCellPosition.Y * GameConfig.TileCellSize
  222. );
  223. if (!MapEditorToolsPanel.S_HBoxContainer.Instance.IsMouseInRect()) //不在Ui节点上
  224. {
  225. //左键绘制
  226. if (_isLeftPressed)
  227. {
  228. if (MouseType == MouseButtonType.Pen) //绘制单格
  229. {
  230. if (_prevMouseCellPosition != _mouseCellPosition || !_changeFlag) //鼠标位置变过
  231. {
  232. _changeFlag = true;
  233. _prevMouseCellPosition = _mouseCellPosition;
  234. //绘制图块
  235. SetSingleCell(_mouseCellPosition);
  236. }
  237. }
  238. else if (MouseType == MouseButtonType.Area) //绘制区域
  239. {
  240. _drawFullRect = true;
  241. }
  242. else if (MouseType == MouseButtonType.Drag) //拖拽
  243. {
  244. SetMapPosition(GetGlobalMousePosition() + _moveOffset);
  245. }
  246. }
  247. else if (_isRightPressed) //右键擦除
  248. {
  249. if (MouseType == MouseButtonType.Pen) //绘制单格
  250. {
  251. if (_prevMouseCellPosition != _mouseCellPosition || !_changeFlag) //鼠标位置变过
  252. {
  253. _changeFlag = true;
  254. _prevMouseCellPosition = _mouseCellPosition;
  255. EraseSingleCell(_mouseCellPosition);
  256. }
  257. }
  258. else if (MouseType == MouseButtonType.Area) //绘制区域
  259. {
  260. _drawFullRect = true;
  261. }
  262. else if (MouseType == MouseButtonType.Drag) //拖拽
  263. {
  264. SetMapPosition(GetGlobalMousePosition() + _moveOffset);
  265. }
  266. }
  267. else if (_isMiddlePressed) //中键移动
  268. {
  269. SetMapPosition(GetGlobalMousePosition() + _moveOffset);
  270. }
  271. }
  272.  
  273. //绘制停止指定时间后, 生成导航网格
  274. if (_generateTimer > 0)
  275. {
  276. _generateTimer -= newDelta;
  277. if (_generateTimer <= 0)
  278. {
  279. //检测地形
  280. RunCheckHandler();
  281. }
  282. }
  283. }
  284.  
  285. /// <summary>
  286. /// 绘制辅助线
  287. /// </summary>
  288. public void DrawGuides()
  289. {
  290. if (_hasPreviewImage)
  291. {
  292. return;
  293. }
  294. CanvasItem canvasItem = _editorTileMap.L_Brush.Instance;
  295. //轴线
  296. canvasItem.DrawLine(new Vector2(0, 2000), new Vector2(0, -2000), Colors.Green);
  297. canvasItem.DrawLine(new Vector2(2000, 0), new Vector2( -2000, 0), Colors.Red);
  298.  
  299. if (IsDrawMark)
  300. {
  301. //绘制房间区域
  302. if (CurrRoomSize.X != 0 && CurrRoomSize.Y != 0)
  303. {
  304. canvasItem.DrawRect(
  305. new Rect2(
  306. (CurrRoomPosition + new Vector2I(1, 2)) * GameConfig.TileCellSize,
  307. (CurrRoomSize - new Vector2I(2, 3)) * GameConfig.TileCellSize
  308. ),
  309. Colors.Aqua, false, 5f / Scale.X
  310. );
  311. }
  312.  
  313. //绘制导航网格
  314. if (_checkTerrainFlag && _isGenerateTerrain && _polygonData != null)
  315. {
  316. foreach (var vector2s in _polygonData)
  317. {
  318. canvasItem.DrawPolygon(vector2s, new Color(0,1,1, 0.3f).MakeArray(vector2s.Length));
  319. }
  320. }
  321. }
  322.  
  323. //绘制笔刷
  324. if (MouseType == MouseButtonType.Pen || MouseType == MouseButtonType.Area)
  325. {
  326. if (_drawFullRect) //绘制填充矩形
  327. {
  328. var size = TileSet.TileSize;
  329. var cellPos = _mouseStartCellPosition;
  330. var temp = size;
  331. if (_mouseStartCellPosition.X > _mouseCellPosition.X)
  332. {
  333. cellPos.X += 1;
  334. temp.X -= size.X;
  335. }
  336. if (_mouseStartCellPosition.Y > _mouseCellPosition.Y)
  337. {
  338. cellPos.Y += 1;
  339. temp.Y -= size.Y;
  340. }
  341.  
  342. var pos = cellPos * size;
  343. canvasItem.DrawRect(new Rect2(pos, _mousePosition - pos + temp), Colors.White, false, 2f / Scale.X);
  344. }
  345. else //绘制单格
  346. {
  347. if (CurrLayer.Layer == MapLayer.AutoFloorLayer) //选择自动地板层
  348. {
  349. DrawCellOutline(canvasItem);
  350. }
  351. else //自定义层
  352. {
  353. if (CurrBrushType == TileMapDrawMode.Free || CurrBrushType == TileMapDrawMode.Combination) //自由绘制 或者 绘制组合
  354. {
  355. if (_isRightPressed) //按下了左键擦除
  356. {
  357. DrawCellOutline(canvasItem);
  358. }
  359. else //正常绘制
  360. {
  361. foreach (var item in CurrBrush)
  362. {
  363. var rect = new Rect2(_mousePosition + (item.Key + _brushOffset) * GameConfig.TileCellSize, GameConfig.TileCellSize, GameConfig.TileCellSize);
  364. var srcRect = new Rect2(item.Value * GameConfig.TileCellSize, GameConfig.TileCellSize, GameConfig.TileCellSize);
  365. canvasItem.DrawTextureRectRegion(CurrBrushTexture, rect, srcRect, new Color(1, 1, 1, 0.3f));
  366. }
  367. }
  368. }
  369. }
  370. }
  371. }
  372. }
  373.  
  374. private void DrawCellOutline(CanvasItem canvasItem)
  375. {
  376. canvasItem.DrawRect(new Rect2(_mousePosition, TileSet.TileSize), Colors.White, false, 2f / Scale.X);
  377. }
  378.  
  379. public override void _Input(InputEvent @event)
  380. {
  381. if (@event is InputEventMouseButton mouseButton)
  382. {
  383. if (mouseButton.ButtonIndex == MouseButton.Left) //左键
  384. {
  385. if (mouseButton.Pressed) //按下
  386. {
  387. _moveOffset = Position - GetGlobalMousePosition();
  388. _mouseStartCellPosition = LocalToMap(GetLocalMousePosition());
  389. }
  390. else
  391. {
  392. _changeFlag = false;
  393. if (_drawFullRect) //松开, 提交绘制的矩形区域
  394. {
  395. SetRectCell(_mouseStartCellPosition, _mouseCellPosition);
  396. _drawFullRect = false;
  397. }
  398. }
  399.  
  400. _isLeftPressed = mouseButton.Pressed;
  401. }
  402. else if (mouseButton.ButtonIndex == MouseButton.Right) //右键
  403. {
  404. if (mouseButton.Pressed) //按下
  405. {
  406. _moveOffset = Position - GetGlobalMousePosition();
  407. _mouseStartCellPosition = LocalToMap(GetLocalMousePosition());
  408. }
  409. else
  410. {
  411. _changeFlag = false;
  412. if (_drawFullRect) //松开, 提交擦除的矩形区域
  413. {
  414. EraseRectCell(_mouseStartCellPosition, _mouseCellPosition);
  415. _drawFullRect = false;
  416. }
  417. }
  418. _isRightPressed = mouseButton.Pressed;
  419. }
  420. else if (mouseButton.ButtonIndex == MouseButton.WheelDown)
  421. {
  422. //缩小
  423. Shrink();
  424. }
  425. else if (mouseButton.ButtonIndex == MouseButton.WheelUp)
  426. {
  427. //放大
  428. Magnify();
  429. }
  430. else if (mouseButton.ButtonIndex == MouseButton.Middle)
  431. {
  432. _isMiddlePressed = mouseButton.Pressed;
  433. if (_isMiddlePressed)
  434. {
  435. _moveOffset = Position - GetGlobalMousePosition();
  436. }
  437. }
  438. }
  439. }
  440.  
  441. /// <summary>
  442. /// 设置选择的layer
  443. /// </summary>
  444. public void SetCurrentLayer(TileMapLayerData layerData)
  445. {
  446. CurrLayer = layerData;
  447. MapEditorToolsPanel.S_CurrLayer.Instance.Text = "当前图层:" + layerData.Title;
  448. SetLayerModulate(MapLayer.AutoFloorLayer, _GetEditorLayerModulate(MapLayer.AutoFloorLayer));
  449. SetLayerModulate(MapLayer.AutoMiddleLayer, _GetEditorLayerModulate(MapLayer.AutoMiddleLayer));
  450. SetLayerModulate(MapLayer.AutoTopLayer, _GetEditorLayerModulate(MapLayer.AutoTopLayer));
  451. SetLayerModulate(MapLayer.CustomFloorLayer1, _GetEditorLayerModulate(MapLayer.CustomFloorLayer1));
  452. SetLayerModulate(MapLayer.CustomFloorLayer2, _GetEditorLayerModulate(MapLayer.CustomFloorLayer2));
  453. SetLayerModulate(MapLayer.CustomFloorLayer3, _GetEditorLayerModulate(MapLayer.CustomFloorLayer3));
  454. SetLayerModulate(MapLayer.CustomMiddleLayer1, _GetEditorLayerModulate(MapLayer.CustomMiddleLayer1));
  455. SetLayerModulate(MapLayer.CustomMiddleLayer2, _GetEditorLayerModulate(MapLayer.CustomMiddleLayer2));
  456. SetLayerModulate(MapLayer.CustomTopLayer, _GetEditorLayerModulate(MapLayer.CustomTopLayer));
  457. }
  458.  
  459. /// <summary>
  460. /// 设置选中的 Source 索引
  461. /// </summary>
  462. public void SetCurrSourceIndex(int index)
  463. {
  464. CurrSourceIndex = index;
  465. }
  466.  
  467. /// <summary>
  468. /// 设置当前笔刷类型
  469. /// </summary>
  470. public void SetCurrBrushType(TileMapDrawMode mode)
  471. {
  472. CurrBrushType = mode;
  473. }
  474.  
  475. /// <summary>
  476. /// 添加笔刷绘制的资源坐标, 单位: 格
  477. /// </summary>
  478. public void AddCurrBrushAtlasCoords(Vector2I pos, Vector2I atlasCoords)
  479. {
  480. if (!CurrBrush.ContainsKey(pos))
  481. {
  482. CurrBrush.Add(pos, atlasCoords);
  483. var xStart = int.MaxValue;
  484. var xEnd = int.MinValue;
  485. var yStart = int.MaxValue;
  486. var yEnd = int.MinValue;
  487.  
  488. //计算起始点和终点
  489. foreach (var kv in CurrBrush)
  490. {
  491. var cell = kv.Key;
  492. xStart = Mathf.Min(cell.X, xStart);
  493. yStart = Mathf.Min(cell.Y, yStart);
  494. xEnd = Mathf.Max(cell.X, xEnd);
  495. yEnd = Mathf.Max(cell.Y, yEnd);
  496. }
  497. _brushOffset = new Vector2I(-(xStart + (xEnd - xStart) / 2), -(yStart + (yEnd - yStart) / 2));
  498. }
  499. }
  500. /// <summary>
  501. /// 清除笔刷
  502. /// </summary>
  503. public void ClearCurrBrushAtlasCoords()
  504. {
  505. CurrBrush.Clear();
  506. }
  507.  
  508. /// <summary>
  509. /// 设置笔刷使用的纹理
  510. /// </summary>
  511. public void SetCurrBrushTexture(Texture2D texture)
  512. {
  513. CurrBrushTexture = texture;
  514. }
  515.  
  516. /// <summary>
  517. /// 设置选中某个图层时是否淡化其他图层
  518. /// </summary>
  519. public void SetDesaltOtherLayer(bool flag)
  520. {
  521. _desaltOtherLayer = flag;
  522. SetCurrentLayer(CurrLayer);
  523. }
  524.  
  525. /// <summary>
  526. /// 尝试运行检查, 如果已经运行过了, 则没有效果
  527. /// </summary>
  528. public void TryRunCheckHandler()
  529. {
  530. if (_generateTimer > 0)
  531. {
  532. _generateTimer = -1;
  533. RunCheckHandler();
  534. }
  535. }
  536. //执行检测地形操作
  537. private void RunCheckHandler()
  538. {
  539. _isGenerateTerrain = false;
  540. //计算区域
  541. CalcTileRect(false);
  542. Debug.Log("开始检测是否可以生成地形...");
  543. if (CheckTerrain())
  544. {
  545. Debug.Log("开始绘制自动贴图...");
  546. GenerateTerrain();
  547. _isGenerateTerrain = true;
  548. }
  549. else
  550. {
  551. SetErrorCell(_checkTerrainErrorPosition);
  552. }
  553. }
  554.  
  555. //将指定自动地形层数据存入list中
  556. private void PushAutoLayerDataToList(int layer, List<int> list)
  557. {
  558. const int sourceId = 0; //这里指定0是因为 Main Source 的 id 为 0
  559. var layerArray = GetUsedCellsById(layer, sourceId);
  560. foreach (var pos in layerArray)
  561. {
  562. var atlasCoords = GetCellAtlasCoords(layer, pos);
  563. var tileCellData = _autoTileConfig.GetCellData(atlasCoords);
  564. if (tileCellData != null)
  565. {
  566. list.Add(pos.X);
  567. list.Add(pos.Y);
  568. list.Add((int)tileCellData.TerrainPeering);
  569. list.Add(tileCellData.TerrainType);
  570. }
  571. }
  572. }
  573. //将指定层数据存入list中
  574. private void PushLayerDataToList(int layer, List<int> list)
  575. {
  576. var layerArray = GetUsedCellsById(layer);
  577. foreach (var pos in layerArray)
  578. {
  579. var atlasCoords = GetCellAtlasCoords(layer, pos);
  580. list.Add(pos.X);
  581. list.Add(pos.Y);
  582. list.Add(GetCellSourceId(layer, pos));
  583. list.Add(atlasCoords.X);
  584. list.Add(atlasCoords.Y);
  585. }
  586. }
  587.  
  588. //设置自动地形层的数据
  589. private void SetAutoLayerDataFromList(int layer, List<int> list)
  590. {
  591. var terrainInfo = _autoTileConfig.TerrainInfo;
  592. var sourceId = _autoTileConfig.SourceId;
  593. for (var i = 0; i < list.Count; i += 4)
  594. {
  595. var pos = new Vector2I(list[i], list[i + 1]);
  596. var bit = (uint)list[i + 2];
  597. var type = (byte)list[i + 3];
  598. var index = terrainInfo.TerrainBitToIndex(bit, type);
  599. var terrainCell = terrainInfo.GetTerrainCell(index, type);
  600. var atlasCoords = terrainInfo.GetPosition(terrainCell);
  601. SetCell(layer, pos, sourceId, atlasCoords);
  602. if (layer == MapLayer.AutoFloorLayer)
  603. {
  604. _autoCellLayerGrid.Set(pos, true);
  605. }
  606. }
  607. }
  608. //设置自定义层的数据
  609. private void SetCustomLayerDataFromList(int layer, List<int> list)
  610. {
  611. //五个一组
  612. for (var i = 0; i < list.Count; i += 5)
  613. {
  614. var pos = new Vector2I(list[i], list[i + 1]);
  615. var sourceId = list[i + 2];
  616. var atlasCoords = new Vector2I(list[i + 3], list[i + 4]);
  617. SetCell(layer, pos, sourceId, atlasCoords);
  618. }
  619. }
  620.  
  621. /// <summary>
  622. /// 触发保存地图数据
  623. /// </summary>
  624. public void TriggerSave(RoomErrorType errorType, Action finish)
  625. {
  626. Debug.Log("保存地牢房间数据...");
  627. //执行创建预览图流程
  628. RunSavePreviewImage(() =>
  629. {
  630. //执行保存数据流程
  631. CurrRoomSplit.ErrorType = errorType;
  632. SaveRoomInfoConfig();
  633. SaveTileInfoConfig();
  634. SavePreinstallConfig();
  635. IsDirty = false;
  636. MapEditorPanel.SetTitleDirty(false);
  637. //派发保存事件
  638. EventManager.EmitEvent(EventEnum.OnTileMapSave);
  639. if (finish != null)
  640. {
  641. finish();
  642. }
  643. });
  644. }
  645.  
  646. /// <summary>
  647. /// 加载地牢, 返回是否加载成功
  648. /// </summary>
  649. public bool Load(DungeonRoomSplit roomSplit, TileSetSplit tileSetSplit)
  650. {
  651. InitTileSet(tileSetSplit);
  652. //重新加载数据
  653. roomSplit.ReloadRoomInfo();
  654. roomSplit.ReloadTileInfo();
  655. roomSplit.ReloadPreinstall();
  656. CurrRoomSplit = roomSplit;
  657. var roomInfo = roomSplit.RoomInfo;
  658. var tileInfo = roomSplit.TileInfo;
  659.  
  660. CurrRoomPosition = roomInfo.Position.AsVector2I();
  661. SetMapSize(roomInfo.Size.AsVector2I(), true);
  662. CurrDoorConfigs.Clear();
  663. foreach (var doorAreaInfo in roomInfo.DoorAreaInfos)
  664. {
  665. CurrDoorConfigs.Add(doorAreaInfo.Clone());
  666. }
  667. //读取地块数据
  668. SetAutoLayerDataFromList(MapLayer.AutoFloorLayer, tileInfo.Floor);
  669. SetAutoLayerDataFromList(MapLayer.AutoMiddleLayer, tileInfo.Middle);
  670. SetAutoLayerDataFromList(MapLayer.AutoTopLayer, tileInfo.Top);
  671. SetCustomLayerDataFromList(MapLayer.CustomFloorLayer1, tileInfo.CustomFloor1);
  672. SetCustomLayerDataFromList(MapLayer.CustomFloorLayer2, tileInfo.CustomFloor2);
  673. SetCustomLayerDataFromList(MapLayer.CustomFloorLayer3, tileInfo.CustomFloor3);
  674. SetCustomLayerDataFromList(MapLayer.CustomMiddleLayer1, tileInfo.CustomMiddle1);
  675. SetCustomLayerDataFromList(MapLayer.CustomMiddleLayer2, tileInfo.CustomMiddle2);
  676. SetCustomLayerDataFromList(MapLayer.CustomTopLayer, tileInfo.CustomTop);
  677.  
  678. //如果有图块错误, 则找出错误的点位
  679. if (roomSplit.ErrorType == RoomErrorType.TileError)
  680. {
  681. RunCheckHandler();
  682. }
  683. else
  684. {
  685. //导航网格
  686. if (tileInfo.NavigationPolygon != null && tileInfo.NavigationVertices != null)
  687. {
  688. var polygon = _editorTileMap.L_NavigationRegion.Instance.NavigationPolygon;
  689. polygon.Vertices = tileInfo.NavigationVertices.Select(v => v.AsVector2()).ToArray();
  690. foreach (var p in tileInfo.NavigationPolygon)
  691. {
  692. polygon.AddPolygon(p);
  693. }
  694.  
  695. OnBakeFinished();
  696. }
  697. }
  698. //聚焦
  699. //MapEditorPanel.CallDelay(0.1f, OnClickCenterTool);
  700. //CallDeferred(nameof(OnClickCenterTool), null);
  701. //加载门编辑区域
  702. foreach (var doorAreaInfo in CurrDoorConfigs)
  703. {
  704. MapEditorToolsPanel.CreateDoorTool(doorAreaInfo);
  705. }
  706. //聚焦 (需要延时一帧调用)
  707. this.CallDelayInNode(0, () => OnClickCenterTool(null));
  708. return true;
  709. }
  710. /// <summary>
  711. /// 初始化图块集。
  712. /// </summary>
  713. /// <param name="tileSetSplit">要初始化的图块集</param>
  714. private void InitTileSet(TileSetSplit tileSetSplit)
  715. {
  716. CurrentTileSet = tileSetSplit;
  717. TileSet = tileSetSplit.GetTileSet();
  718.  
  719. // 创建AutoTileConfig对象
  720. // 使用第一个图块集源作为参数
  721. _autoTileConfig = new AutoTileConfig(0, tileSetSplit.TileSetInfo.Sources[0].Terrain[0]);
  722. }
  723.  
  724. /// <summary>
  725. /// 初始化层数据
  726. /// </summary>
  727. public void InitLayer()
  728. {
  729. if (_initLayer)
  730. {
  731. return;
  732. }
  733.  
  734. _initLayer = true;
  735. //初始化层级数据
  736. AddLayer(MapLayer.AutoFloorLayer);
  737. SetLayerZIndex(MapLayer.AutoFloorLayer, MapLayer.AutoFloorLayer);
  738. AddLayer(MapLayer.CustomFloorLayer1);
  739. SetLayerZIndex(MapLayer.CustomFloorLayer1, MapLayer.CustomFloorLayer1);
  740. AddLayer(MapLayer.CustomFloorLayer2);
  741. SetLayerZIndex(MapLayer.CustomFloorLayer2, MapLayer.CustomFloorLayer2);
  742. AddLayer(MapLayer.CustomFloorLayer3);
  743. SetLayerZIndex(MapLayer.CustomFloorLayer3, MapLayer.CustomFloorLayer3);
  744. AddLayer(MapLayer.AutoMiddleLayer);
  745. SetLayerZIndex(MapLayer.AutoMiddleLayer, MapLayer.AutoMiddleLayer);
  746. AddLayer(MapLayer.CustomMiddleLayer1);
  747. SetLayerZIndex(MapLayer.CustomMiddleLayer1, MapLayer.CustomMiddleLayer1);
  748. AddLayer(MapLayer.CustomMiddleLayer2);
  749. SetLayerZIndex(MapLayer.CustomMiddleLayer2, MapLayer.CustomMiddleLayer2);
  750. AddLayer(MapLayer.AutoTopLayer);
  751. SetLayerZIndex(MapLayer.AutoTopLayer, MapLayer.AutoTopLayer);
  752. AddLayer(MapLayer.CustomTopLayer);
  753. SetLayerZIndex(MapLayer.CustomTopLayer, MapLayer.CustomTopLayer);
  754. }
  755.  
  756. //缩小
  757. private void Shrink()
  758. {
  759. var pos = GetLocalMousePosition();
  760. var scale = Scale / 1.1f;
  761. if (scale.LengthSquared() >= 0.5f)
  762. {
  763. Scale = scale;
  764. SetMapPosition(Position + pos * 0.1f * scale);
  765. }
  766. }
  767. //放大
  768. private void Magnify()
  769. {
  770. var pos = GetLocalMousePosition();
  771. var prevScale = Scale;
  772. var scale = prevScale * 1.1f;
  773. if (scale.LengthSquared() <= 2000)
  774. {
  775. Scale = scale;
  776. SetMapPosition(Position - pos * 0.1f * prevScale);
  777. }
  778. }
  779.  
  780. //绘制单个贴图
  781. private void SetSingleCell(Vector2I position)
  782. {
  783. if (CurrLayer.Layer == MapLayer.AutoFloorLayer) //选择自动地板层, 那么不管笔刷类型, 通通使用 Main Source 中的 Main Terrain
  784. {
  785. var tileCellData = _autoTileConfig.Floor;
  786. SetCell(MapLayer.AutoFloorLayer, position, tileCellData.SourceId, tileCellData.AutoTileCoords);
  787. if (!_autoCellLayerGrid.Contains(position.X, position.Y))
  788. {
  789. ResetGenerateTimer();
  790. _autoCellLayerGrid.Set(position.X, position.Y, true);
  791. }
  792. }
  793. else //自定义层
  794. {
  795. if (CurrBrushType == TileMapDrawMode.Free || CurrBrushType == TileMapDrawMode.Combination) //自由绘制 或者 组合
  796. {
  797. foreach (var item in CurrBrush)
  798. {
  799. SetCell(CurrLayer.Layer, position + item.Key + _brushOffset, CurrSourceIndex, item.Value);
  800. //标记有修改数据
  801. EventManager.EmitEvent(EventEnum.OnTileMapDirty);
  802. }
  803. }
  804. }
  805. }
  806. //绘制区域贴图
  807. private void SetRectCell(Vector2I start, Vector2I end)
  808. {
  809. ResetGenerateTimer();
  810. if (start.X > end.X)
  811. {
  812. var temp = end.X;
  813. end.X = start.X;
  814. start.X = temp;
  815. }
  816. if (start.Y > end.Y)
  817. {
  818. var temp = end.Y;
  819. end.Y = start.Y;
  820. start.Y = temp;
  821. }
  822.  
  823. var width = end.X - start.X + 1;
  824. var height = end.Y - start.Y + 1;
  825. for (var i = 0; i < width; i++)
  826. {
  827. for (var j = 0; j < height; j++)
  828. {
  829. var tileCellData = _autoTileConfig.Floor;
  830. SetCell(MapLayer.AutoFloorLayer, new Vector2I(start.X + i, start.Y + j), tileCellData.SourceId, tileCellData.AutoTileCoords);
  831. }
  832. }
  833.  
  834. _autoCellLayerGrid.SetRect(start, new Vector2I(width, height), true);
  835. }
  836.  
  837. //擦除单个图块
  838. private void EraseSingleCell(Vector2I position)
  839. {
  840. if (CurrLayer.Layer == MapLayer.AutoFloorLayer) //选择自动地板层, 那么不管笔刷类型, 通通使用 Main Source 中的 Main Terrain
  841. {
  842. EraseCell(MapLayer.AutoFloorLayer, position);
  843. if (_autoCellLayerGrid.Remove(position.X, position.Y))
  844. {
  845. ResetGenerateTimer();
  846. }
  847. }
  848. else //自定义层
  849. {
  850. EraseCell(CurrLayer.Layer, position);
  851. //标记有修改数据
  852. EventManager.EmitEvent(EventEnum.OnTileMapDirty);
  853. }
  854. }
  855. //擦除一个区域内的贴图
  856. private void EraseRectCell(Vector2I start, Vector2I end)
  857. {
  858. ResetGenerateTimer();
  859. if (start.X > end.X)
  860. {
  861. var temp = end.X;
  862. end.X = start.X;
  863. start.X = temp;
  864. }
  865. if (start.Y > end.Y)
  866. {
  867. var temp = end.Y;
  868. end.Y = start.Y;
  869. start.Y = temp;
  870. }
  871.  
  872. var width = end.X - start.X + 1;
  873. var height = end.Y - start.Y + 1;
  874. for (var i = 0; i < width; i++)
  875. {
  876. for (var j = 0; j < height; j++)
  877. {
  878. EraseCell(MapLayer.AutoFloorLayer, new Vector2I(start.X + i, start.Y + j));
  879. }
  880. }
  881. _autoCellLayerGrid.RemoveRect(start, new Vector2I(width, height));
  882. }
  883.  
  884. //重置计时器
  885. private void ResetGenerateTimer()
  886. {
  887. _generateTimer = _generateInterval;
  888. _isGenerateTerrain = false;
  889. ClearLayer(MapLayer.AutoTopLayer);
  890. ClearLayer(MapLayer.AutoMiddleLayer);
  891. CloseErrorCell();
  892. //标记有修改数据
  893. EventManager.EmitEvent(EventEnum.OnTileMapDirty);
  894. }
  895.  
  896. //重新计算房间区域
  897. private void CalcTileRect(bool refreshDoorTrans)
  898. {
  899. var rect = _autoCellLayerGrid.GetRect();
  900. CurrRoomPosition = rect.Position - new Vector2I(2, 3);
  901. SetMapSize(rect.Size + new Vector2I(4, 5), refreshDoorTrans);
  902. }
  903. //检测是否有不合规的图块, 返回true表示图块正常
  904. private bool CheckTerrain()
  905. {
  906. _checkTerrainFlag = true;
  907. _autoCellLayerGrid.ForEach((x, y, flag) =>
  908. {
  909. if (flag)
  910. {
  911. if (!_autoCellLayerGrid.Contains(x, y + 1) && _autoCellLayerGrid.Contains(x, y + 2))
  912. {
  913. _checkTerrainFlag = false;
  914. _checkTerrainErrorPosition = new Vector2I(x, y + 1);
  915. return false;
  916. }
  917. }
  918.  
  919. return true;
  920. });
  921. return _checkTerrainFlag;
  922. }
  923. //生成自动图块 (地形)
  924. private void GenerateTerrain()
  925. {
  926. //ClearLayer(MapLayer.AutoFloorLayer);
  927. var list = new List<Vector2I>();
  928. var xStart = int.MaxValue;
  929. var yStart = int.MaxValue;
  930. var xEnd = int.MinValue;
  931. var yEnd = int.MinValue;
  932. _autoCellLayerGrid.ForEach((x, y, flag) =>
  933. {
  934. if (flag)
  935. {
  936. //计算范围
  937. if (x < xStart)
  938. xStart = x;
  939. else if (x > xEnd)
  940. xEnd = x;
  941.  
  942. if (y < yStart)
  943. yStart = y;
  944. else if (y > yEnd)
  945. yEnd = y;
  946. //填充墙壁
  947. if (!_autoCellLayerGrid.Contains(x, y - 1))
  948. {
  949. var left = _autoCellLayerGrid.Contains(x - 1, y - 1);
  950. var right = _autoCellLayerGrid.Contains(x + 1, y - 1);
  951. TileCellData tileCellData;
  952. if (left && right)
  953. {
  954. tileCellData = _autoTileConfig.Wall_Vertical_Single;
  955. }
  956. else if (left)
  957. {
  958. tileCellData = _autoTileConfig.Wall_Vertical_Left;
  959. }
  960. else if (right)
  961. {
  962. tileCellData = _autoTileConfig.Wall_Vertical_Right;
  963. }
  964. else
  965. {
  966. tileCellData = _autoTileConfig.Wall_Vertical_Center;
  967. }
  968. SetCell(MapLayer.AutoFloorLayer, new Vector2I(x, y - 1), tileCellData.SourceId, tileCellData.AutoTileCoords);
  969. }
  970. }
  971.  
  972. return true;
  973. });
  974. //绘制临时边界
  975. var temp1 = new List<Vector2I>();
  976. for (var x = xStart - 3; x <= xEnd + 3; x++)
  977. {
  978. var p1 = new Vector2I(x, yStart - 4);
  979. var p2 = new Vector2I(x, yEnd + 3);
  980. temp1.Add(p1);
  981. temp1.Add(p2);
  982. //上横
  983. SetCell(MapLayer.AutoFloorLayer, p1, _autoTileConfig.TopMask.SourceId, _autoTileConfig.TopMask.AutoTileCoords);
  984. //下横
  985. SetCell(MapLayer.AutoFloorLayer, p2, _autoTileConfig.TopMask.SourceId, _autoTileConfig.TopMask.AutoTileCoords);
  986. }
  987. for (var y = yStart - 4; y <= yEnd + 3; y++)
  988. {
  989. var p1 = new Vector2I(xStart - 3, y);
  990. var p2 = new Vector2I(xEnd + 3, y);
  991. temp1.Add(p1);
  992. temp1.Add(p2);
  993. //左竖
  994. SetCell(MapLayer.AutoFloorLayer, p1, _autoTileConfig.TopMask.SourceId, _autoTileConfig.TopMask.AutoTileCoords);
  995. //右竖
  996. SetCell(MapLayer.AutoFloorLayer, p2, _autoTileConfig.TopMask.SourceId, _autoTileConfig.TopMask.AutoTileCoords);
  997. }
  998. //计算需要绘制的图块
  999. var temp2 = new List<Vector2I>();
  1000. for (var x = xStart - 2; x <= xEnd + 2; x++)
  1001. {
  1002. for (var y = yStart - 3; y <= yEnd + 2; y++)
  1003. {
  1004. if (!_autoCellLayerGrid.Contains(x, y) && !_autoCellLayerGrid.Contains(x, y + 1))
  1005. {
  1006. list.Add(new Vector2I(x, y));
  1007. if (!IsMaskCollisionGround(_autoCellLayerGrid, x, y))
  1008. {
  1009. temp2.Add(new Vector2I(x, y));
  1010. }
  1011. }
  1012. }
  1013. }
  1014. var arr = new Array<Vector2I>(list);
  1015. //绘制自动图块
  1016. SetCellsTerrainConnect(MapLayer.AutoFloorLayer, arr, _mainTerrainSet, _mainTerrain, false);
  1017. //擦除临时边界
  1018. for (var i = 0; i < temp1.Count; i++)
  1019. {
  1020. EraseCell(MapLayer.AutoFloorLayer, temp1[i]);
  1021. }
  1022.  
  1023. //计算区域
  1024. CalcTileRect(true);
  1025. //开始绘制导航网格
  1026. GenerateNavigation();
  1027.  
  1028. //擦除临时边界2
  1029. for (var i = 0; i < temp2.Count; i++)
  1030. {
  1031. EraseCell(MapLayer.AutoFloorLayer, temp2[i]);
  1032. }
  1033. //将墙壁移动到指定层
  1034. MoveTerrainCell();
  1035. }
  1036.  
  1037. private bool IsMaskCollisionGround(InfiniteGrid<bool> autoCellLayerGrid, int x, int y)
  1038. {
  1039. for (var i = -2; i <= 2; i++)
  1040. {
  1041. for (var j = -2; j <= 3; j++)
  1042. {
  1043. if (autoCellLayerGrid.Contains(x + i, y + j))
  1044. {
  1045. return true;
  1046. }
  1047. }
  1048. }
  1049.  
  1050. return false;
  1051. }
  1052. //将自动生成的图块从 MapLayer.AutoFloorLayer 移动到指定图层中
  1053. private void MoveTerrainCell()
  1054. {
  1055. ClearLayer(MapLayer.AutoTopLayer);
  1056. ClearLayer(MapLayer.AutoMiddleLayer);
  1057. var x = CurrRoomPosition.X;
  1058. var y = CurrRoomPosition.Y;
  1059. var w = CurrRoomSize.X;
  1060. var h = CurrRoomSize.Y;
  1061.  
  1062. for (var i = 0; i < w; i++)
  1063. {
  1064. for (var j = 0; j < h; j++)
  1065. {
  1066. var pos = new Vector2I(x + i, y + j);
  1067. if (!_autoCellLayerGrid.Contains(pos) && GetCellSourceId(MapLayer.AutoFloorLayer, pos) != -1)
  1068. {
  1069. var atlasCoords = GetCellAtlasCoords(MapLayer.AutoFloorLayer, pos);
  1070. var layer = _autoTileConfig.GetLayer(atlasCoords);
  1071. if (layer == MapLayer.AutoMiddleLayer)
  1072. {
  1073. layer = MapLayer.AutoMiddleLayer;
  1074. }
  1075. else if (layer == MapLayer.AutoTopLayer)
  1076. {
  1077. layer = MapLayer.AutoTopLayer;
  1078. }
  1079. else
  1080. {
  1081. Debug.LogError($"异常图块: {pos}, 这个图块的图集坐标'{atlasCoords}'不属于'MiddleMapLayer'和'TopMapLayer'!");
  1082. continue;
  1083. }
  1084. EraseCell(MapLayer.AutoFloorLayer, pos);
  1085. SetCell(layer, pos, _mainSource, atlasCoords);
  1086. }
  1087. }
  1088. }
  1089. }
  1090.  
  1091. //生成导航网格
  1092. private void GenerateNavigation()
  1093. {
  1094. var navigationRegion = _editorTileMap.L_NavigationRegion.Instance;
  1095. var navigationPolygon = navigationRegion.NavigationPolygon;
  1096. navigationPolygon.Clear();
  1097. navigationPolygon.ClearPolygons();
  1098. navigationPolygon.ClearOutlines();
  1099. var endPos = CurrRoomPosition + CurrRoomSize;
  1100. navigationPolygon.AddOutline(new []
  1101. {
  1102. CurrRoomPosition * GameConfig.TileCellSize,
  1103. new Vector2(endPos.X, CurrRoomPosition.Y) * GameConfig.TileCellSize,
  1104. endPos * GameConfig.TileCellSize,
  1105. new Vector2(CurrRoomPosition.X, endPos.Y) * GameConfig.TileCellSize
  1106. });
  1107. navigationRegion.BakeNavigationPolygon(false);
  1108. }
  1109.  
  1110. //设置显示的错误cell, 会标记上红色的闪烁动画
  1111. private void SetErrorCell(Vector2I pos)
  1112. {
  1113. MapEditorPanel.S_ErrorCell.Instance.Position = pos * GameConfig.TileCellSize;
  1114. MapEditorPanel.S_ErrorCellAnimationPlayer.Instance.Play(AnimatorNames.Show);
  1115. }
  1116.  
  1117. //关闭显示的错误cell
  1118. private void CloseErrorCell()
  1119. {
  1120. MapEditorPanel.S_ErrorCellAnimationPlayer.Instance.Stop();
  1121. }
  1122. /// <summary>
  1123. /// 选中拖拽功能
  1124. /// </summary>
  1125. private void OnSelectHandTool(object arg)
  1126. {
  1127. MouseType = MouseButtonType.Drag;
  1128. }
  1129. /// <summary>
  1130. /// 选中画笔攻击
  1131. /// </summary>
  1132. private void OnSelectPenTool(object arg)
  1133. {
  1134. MouseType = MouseButtonType.Pen;
  1135. }
  1136.  
  1137. /// <summary>
  1138. /// 选中绘制区域功能
  1139. /// </summary>
  1140. private void OnSelectRectTool(object arg)
  1141. {
  1142. MouseType = MouseButtonType.Area;
  1143. }
  1144.  
  1145. /// <summary>
  1146. /// 选择编辑门区域
  1147. /// </summary>
  1148. private void OnSelectEditTool(object arg)
  1149. {
  1150. MouseType = MouseButtonType.Edit;
  1151. }
  1152.  
  1153. /// <summary>
  1154. /// 聚焦
  1155. /// </summary>
  1156. private void OnClickCenterTool(object arg)
  1157. {
  1158. var pos = MapEditorPanel.S_SubViewport.Instance.Size / 2;
  1159. if (CurrRoomSize.X == 0 && CurrRoomSize.Y == 0) //聚焦原点
  1160. {
  1161. SetMapPosition(pos);
  1162. }
  1163. else //聚焦地图中心点
  1164. {
  1165. var roomPos = new Vector2(CurrRoomPosition.X, CurrRoomPosition.Y);
  1166. var roomSize = new Vector2(CurrRoomSize.X, CurrRoomSize.Y);
  1167. SetMapPosition(pos - (roomPos + roomSize / 2) * TileSet.TileSize * Scale);
  1168. }
  1169. }
  1170. //房间数据有修改
  1171. private void OnEditorDirty(object obj)
  1172. {
  1173. IsDirty = true;
  1174. MapEditorPanel.SetTitleDirty(true);
  1175. }
  1176.  
  1177. /// <summary>
  1178. /// 创建地牢房间门区域
  1179. /// </summary>
  1180. /// <param name="direction">门方向</param>
  1181. /// <param name="start">起始坐标, 单位: 像素</param>
  1182. /// <param name="end">结束坐标, 单位: 像素</param>
  1183. public DoorAreaInfo CreateDoorArea(DoorDirection direction, int start, int end)
  1184. {
  1185. var doorAreaInfo = new DoorAreaInfo();
  1186. doorAreaInfo.Direction = direction;
  1187. doorAreaInfo.Start = start;
  1188. doorAreaInfo.End = end;
  1189. //doorAreaInfo.CalcPosition(_roomPosition, _roomSize);
  1190. CurrDoorConfigs.Add(doorAreaInfo);
  1191. return doorAreaInfo;
  1192. }
  1193.  
  1194. /// <summary>
  1195. /// 检测门区域数据是否可以提交
  1196. /// </summary>
  1197. /// <param name="direction">门方向</param>
  1198. /// <param name="start">起始坐标, 单位: 像素</param>
  1199. /// <param name="end">结束坐标, 单位: 像素</param>
  1200. /// <returns></returns>
  1201. public bool CheckDoorArea(DoorDirection direction, int start, int end)
  1202. {
  1203. foreach (var item in CurrDoorConfigs)
  1204. {
  1205. if (item.Direction == direction)
  1206. {
  1207. if (CheckValueCollision(item.Start, item.End, start, end))
  1208. {
  1209. return false;
  1210. }
  1211. }
  1212. }
  1213.  
  1214. return true;
  1215. }
  1216. /// <summary>
  1217. /// 检测门区域数据是否可以提交
  1218. /// </summary>
  1219. /// <param name="target">需要检测的门</param>
  1220. /// <param name="start">起始坐标, 单位: 像素</param>
  1221. /// <param name="end">结束坐标, 单位: 像素</param>
  1222. public bool CheckDoorArea(DoorAreaInfo target, int start, int end)
  1223. {
  1224. foreach (var item in CurrDoorConfigs)
  1225. {
  1226. if (item.Direction == target.Direction && item != target)
  1227. {
  1228. if (CheckValueCollision(item.Start, item.End, start, end))
  1229. {
  1230. return false;
  1231. }
  1232. }
  1233. }
  1234.  
  1235. return true;
  1236. }
  1237. private bool CheckValueCollision(float o1, float o2, float h1, float h2)
  1238. {
  1239. var size = GameConfig.TileCellSize;
  1240. return !(h2 < o1 - 3 * size || o2 + 3 * size < h1);
  1241. }
  1242.  
  1243. /// <summary>
  1244. /// 移除门区域数据
  1245. /// </summary>
  1246. public void RemoveDoorArea(DoorAreaInfo doorAreaInfo)
  1247. {
  1248. CurrDoorConfigs.Remove(doorAreaInfo);
  1249. }
  1250. //保存房间配置
  1251. private void SaveRoomInfoConfig()
  1252. {
  1253. //存入本地
  1254. var roomInfo = CurrRoomSplit.RoomInfo;
  1255. if (!HasTerrainError) //没有绘制错误
  1256. {
  1257. roomInfo.Size = new SerializeVector2(CurrRoomSize);
  1258. roomInfo.Position = new SerializeVector2(CurrRoomPosition);
  1259. }
  1260. else
  1261. {
  1262. roomInfo.Position = new SerializeVector2(CurrRoomPosition - Vector2I.One);
  1263. roomInfo.Size = new SerializeVector2(CurrRoomSize + new Vector2I(2, 2));
  1264. }
  1265.  
  1266. roomInfo.DoorAreaInfos.Clear();
  1267. roomInfo.DoorAreaInfos.AddRange(CurrDoorConfigs);
  1268. roomInfo.ClearCompletionDoorArea();
  1269. MapProjectManager.SaveRoomInfo(CurrRoomSplit);
  1270. }
  1271.  
  1272. //保存地块数据
  1273. public void SaveTileInfoConfig()
  1274. {
  1275. //存入本地
  1276. var tileInfo = CurrRoomSplit.TileInfo;
  1277. if (tileInfo.NavigationPolygon == null)
  1278. {
  1279. tileInfo.NavigationPolygon = new List<int[]>();
  1280. }
  1281. else
  1282. {
  1283. tileInfo.NavigationPolygon.Clear();
  1284. }
  1285. if (tileInfo.NavigationVertices == null)
  1286. {
  1287. tileInfo.NavigationVertices = new List<SerializeVector2>();
  1288. }
  1289. else
  1290. {
  1291. tileInfo.NavigationVertices.Clear();
  1292. }
  1293. var polygon = _editorTileMap.L_NavigationRegion.Instance.NavigationPolygon;
  1294. tileInfo.NavigationPolygon.AddRange(polygon.Polygons);
  1295. tileInfo.NavigationVertices.AddRange(polygon.Vertices.Select(v => new SerializeVector2(v)));
  1296. tileInfo.Floor.Clear();
  1297. tileInfo.Middle.Clear();
  1298. tileInfo.Top.Clear();
  1299. tileInfo.CustomFloor1.Clear();
  1300. tileInfo.CustomFloor2.Clear();
  1301. tileInfo.CustomFloor3.Clear();
  1302. tileInfo.CustomMiddle1.Clear();
  1303. tileInfo.CustomMiddle2.Clear();
  1304. tileInfo.CustomTop.Clear();
  1305.  
  1306. //保存图块数据
  1307. PushAutoLayerDataToList(MapLayer.AutoFloorLayer, tileInfo.Floor);
  1308. PushAutoLayerDataToList(MapLayer.AutoMiddleLayer, tileInfo.Middle);
  1309. PushAutoLayerDataToList(MapLayer.AutoTopLayer, tileInfo.Top);
  1310. PushLayerDataToList(MapLayer.CustomFloorLayer1, tileInfo.CustomFloor1);
  1311. PushLayerDataToList(MapLayer.CustomFloorLayer2, tileInfo.CustomFloor2);
  1312. PushLayerDataToList(MapLayer.CustomFloorLayer3, tileInfo.CustomFloor3);
  1313. PushLayerDataToList(MapLayer.CustomMiddleLayer1, tileInfo.CustomMiddle1);
  1314. PushLayerDataToList(MapLayer.CustomMiddleLayer2, tileInfo.CustomMiddle2);
  1315. PushLayerDataToList(MapLayer.CustomTopLayer, tileInfo.CustomTop);
  1316. MapProjectManager.SaveRoomTileInfo(CurrRoomSplit);
  1317. }
  1318.  
  1319. /// <summary>
  1320. /// 保存预设数据
  1321. /// </summary>
  1322. public void SavePreinstallConfig()
  1323. {
  1324. //存入本地
  1325. MapProjectManager.SaveRoomPreinstall(CurrRoomSplit);
  1326. }
  1327.  
  1328. /// <summary>
  1329. /// 获取相机中心点坐标
  1330. /// </summary>
  1331. public Vector2I GetCenterPosition()
  1332. {
  1333. var pos = ToLocal(MapEditorPanel.S_SubViewport.Instance.Size / 2);
  1334. return new Vector2I((int)pos.X, (int)pos.Y);
  1335. }
  1336. /// <summary>
  1337. /// 设置相机看向的点
  1338. /// </summary>
  1339. public void SetLookPosition(Vector2 pos)
  1340. {
  1341. SetMapPosition(-pos * Scale + MapEditorPanel.S_SubViewport.Instance.Size / 2);
  1342. //SetMapPosition(pos * Scale);
  1343. //SetMapPosition(pos + MapEditorPanel.S_SubViewport.Instance.Size / 2);
  1344. }
  1345. /// <summary>
  1346. /// 设置地图坐标
  1347. /// </summary>
  1348. public void SetMapPosition(Vector2 pos)
  1349. {
  1350. Position = pos;
  1351. MapEditorToolsPanel.SetToolTransform(pos, Scale);
  1352. }
  1353.  
  1354. //设置地图大小
  1355. private void SetMapSize(Vector2I size, bool refreshDoorTrans)
  1356. {
  1357. CurrRoomSize = size;
  1358. if (refreshDoorTrans && _cacheToolSizeData != size)
  1359. {
  1360. _cacheToolSizeData = size;
  1361. MapEditorToolsPanel.SetDoorHoverToolTransform(CurrRoomPosition, CurrRoomSize);
  1362. }
  1363. }
  1364.  
  1365. private bool _hasPreviewImage = false;
  1366. private Action _previewFinish;
  1367. private int _previewIndex = 0;
  1368. private Vector2I _tempViewportSize;
  1369. private Vector2 _tempMapPos;
  1370. private Vector2 _tempMapScale;
  1371. private bool _tempAutoFloorLayer;
  1372. private bool _tempCustomFloorLayer1;
  1373. private bool _tempCustomFloorLayer2;
  1374. private bool _tempCustomFloorLayer3;
  1375. private bool _tempAutoMiddleLayer;
  1376. private bool _tempCustomMiddleLayer1;
  1377. private bool _tempCustomMiddleLayer2;
  1378. private bool _tempAutoTopLayer;
  1379. private bool _tempCustomTopLayer;
  1380.  
  1381. private void RunSavePreviewImage(Action action)
  1382. {
  1383. if (_hasPreviewImage)
  1384. {
  1385. return;
  1386. }
  1387.  
  1388. _previewIndex = 0;
  1389. _previewFinish = action;
  1390. _hasPreviewImage = true;
  1391. //先截图, 将图像数据放置到 S_MapView2 节点上
  1392. var subViewport = MapEditorPanel.S_SubViewport.Instance;
  1393. var viewportTexture = subViewport.GetTexture();
  1394. var tex = ImageTexture.CreateFromImage(viewportTexture.GetImage());
  1395. var textureRect = MapEditorPanel.S_MapView2.Instance;
  1396. textureRect.Texture = tex;
  1397. textureRect.Visible = true;
  1398. //调整绘制视图大小
  1399. _tempViewportSize = subViewport.Size;
  1400. subViewport.Size = new Vector2I(GameConfig.PreviewImageSize, GameConfig.PreviewImageSize);
  1401. //调整tileMap
  1402. _tempMapPos = Position;
  1403. _tempMapScale = Scale;
  1404. //中心点
  1405. var pos = new Vector2(GameConfig.PreviewImageSize / 2f, GameConfig.PreviewImageSize / 2f);
  1406. if (CurrRoomSize.X == 0 && CurrRoomSize.Y == 0) //聚焦原点
  1407. {
  1408. Position = pos;
  1409. }
  1410. else //聚焦地图中心点
  1411. {
  1412. var tempPos = new Vector2(CurrRoomSize.X, CurrRoomSize.Y);
  1413. //var tempPos = new Vector2(CurrRoomSize.X + 2, CurrRoomSize.Y + 2);
  1414. var mapSize = tempPos * TileSet.TileSize;
  1415. var axis = Mathf.Max(mapSize.X, mapSize.Y);
  1416. var targetScale = GameConfig.PreviewImageSize / axis;
  1417. Scale = new Vector2(targetScale, targetScale);
  1418. Position = pos - (CurrRoomPosition + tempPos / 2f) * TileSet.TileSize * targetScale;
  1419. }
  1420. //隐藏工具栏
  1421. MapEditorToolsPanel.Visible = false;
  1422. //显示所有层级
  1423. _tempAutoFloorLayer = IsLayerEnabled(MapLayer.AutoFloorLayer);
  1424. _tempCustomFloorLayer1 = IsLayerEnabled(MapLayer.CustomFloorLayer1);
  1425. _tempCustomFloorLayer2 = IsLayerEnabled(MapLayer.CustomFloorLayer2);
  1426. _tempCustomFloorLayer3 = IsLayerEnabled(MapLayer.CustomFloorLayer3);
  1427. _tempAutoMiddleLayer = IsLayerEnabled(MapLayer.AutoMiddleLayer);
  1428. _tempCustomMiddleLayer1 = IsLayerEnabled(MapLayer.CustomMiddleLayer1);
  1429. _tempCustomMiddleLayer2 = IsLayerEnabled(MapLayer.CustomMiddleLayer2);
  1430. _tempAutoTopLayer = IsLayerEnabled(MapLayer.AutoTopLayer);
  1431. _tempCustomTopLayer = IsLayerEnabled(MapLayer.CustomTopLayer);
  1432.  
  1433. SetLayerEnabled(MapLayer.AutoFloorLayer, true);
  1434. SetLayerEnabled(MapLayer.CustomFloorLayer1, true);
  1435. SetLayerEnabled(MapLayer.CustomFloorLayer2, true);
  1436. SetLayerEnabled(MapLayer.CustomFloorLayer3, true);
  1437. SetLayerEnabled(MapLayer.AutoMiddleLayer, true);
  1438. SetLayerEnabled(MapLayer.CustomMiddleLayer1, true);
  1439. SetLayerEnabled(MapLayer.CustomMiddleLayer2, true);
  1440. SetLayerEnabled(MapLayer.AutoTopLayer, true);
  1441. SetLayerEnabled(MapLayer.CustomTopLayer, true);
  1442. SetLayerModulate(MapLayer.AutoFloorLayer, Colors.White);
  1443. SetLayerModulate(MapLayer.CustomFloorLayer1, Colors.White);
  1444. SetLayerModulate(MapLayer.CustomFloorLayer2, Colors.White);
  1445. SetLayerModulate(MapLayer.CustomFloorLayer3, Colors.White);
  1446. SetLayerModulate(MapLayer.AutoMiddleLayer, Colors.White);
  1447. SetLayerModulate(MapLayer.CustomMiddleLayer1, Colors.White);
  1448. SetLayerModulate(MapLayer.CustomMiddleLayer2, Colors.White);
  1449. SetLayerModulate(MapLayer.AutoTopLayer, Colors.White);
  1450. SetLayerModulate(MapLayer.CustomTopLayer, Colors.White);
  1451. }
  1452.  
  1453. private void OnFramePostDraw()
  1454. {
  1455. if (_hasPreviewImage)
  1456. {
  1457. _previewIndex++;
  1458. if (_previewIndex == 2)
  1459. {
  1460. var textureRect = MapEditorPanel.S_MapView2.Instance;
  1461. var texture = textureRect.Texture;
  1462. textureRect.Texture = null;
  1463. texture.Dispose();
  1464. textureRect.Visible = false;
  1465. //还原工具栏
  1466. MapEditorToolsPanel.Visible = true;
  1467. //还原层级显示
  1468. SetLayerEnabled(MapLayer.AutoFloorLayer, _tempAutoFloorLayer);
  1469. SetLayerEnabled(MapLayer.AutoMiddleLayer, _tempAutoMiddleLayer);
  1470. SetLayerEnabled(MapLayer.AutoTopLayer, _tempAutoTopLayer);
  1471. SetLayerEnabled(MapLayer.CustomFloorLayer1, _tempCustomFloorLayer1);
  1472. SetLayerEnabled(MapLayer.CustomFloorLayer2, _tempCustomFloorLayer2);
  1473. SetLayerEnabled(MapLayer.CustomFloorLayer3, _tempCustomFloorLayer3);
  1474. SetLayerEnabled(MapLayer.CustomMiddleLayer1, _tempCustomMiddleLayer1);
  1475. SetLayerEnabled(MapLayer.CustomMiddleLayer2, _tempCustomMiddleLayer2);
  1476. SetLayerEnabled(MapLayer.CustomTopLayer, _tempCustomTopLayer);
  1477. SetCurrentLayer(CurrLayer);
  1478.  
  1479. //保存预览图
  1480. var subViewport = MapEditorPanel.S_SubViewport.Instance;
  1481. var viewportTexture = subViewport.GetTexture();
  1482. var image = viewportTexture.GetImage();
  1483. image.Resize(GameConfig.PreviewImageSize, GameConfig.PreviewImageSize, Image.Interpolation.Nearest);
  1484. CurrRoomSplit.PreviewImage = ImageTexture.CreateFromImage(image);
  1485. MapProjectManager.SaveRoomPreviewImage(CurrRoomSplit, image);
  1486. //还原tileMap
  1487. Position = _tempMapPos;
  1488. Scale = _tempMapScale;
  1489. //还原绘制视图
  1490. subViewport.Size = _tempViewportSize;
  1491. _previewFinish();
  1492. _hasPreviewImage = false;
  1493. }
  1494. }
  1495. }
  1496. private void OnBakeFinished()
  1497. {
  1498. var polygonData = _editorTileMap.L_NavigationRegion.Instance.NavigationPolygon;
  1499. var polygons = polygonData.Polygons;
  1500. var vertices = polygonData.Vertices;
  1501. _polygonData = new Vector2[polygons.Count][];
  1502. for (var i = 0; i < polygons.Count; i++)
  1503. {
  1504. var polygon = polygons[i];
  1505. var v2Array = new Vector2[polygon.Length];
  1506. for (var j = 0; j < polygon.Length; j++)
  1507. {
  1508. v2Array[j] = vertices[polygon[j]];
  1509. }
  1510. _polygonData[i] = v2Array;
  1511. }
  1512. }
  1513. private Color _GetEditorLayerModulate(int layer)
  1514. {
  1515. if (!_desaltOtherLayer)
  1516. {
  1517. return Colors.White;
  1518. }
  1519.  
  1520. return layer == CurrLayer.Layer ? Colors.White : new Color(1, 1, 1, 0.25f);
  1521. }
  1522. }