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