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