Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / ui / mapEditor / TileView / EditorTileMap.cs
@小李xl 小李xl on 25 Jul 2023 23 KB 门区域添加限制
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Text.Json;
  6. using Godot;
  7. using Godot.Collections;
  8. using UI.MapEditorTools;
  9.  
  10. namespace UI.MapEditor;
  11.  
  12. public partial class EditorTileMap : TileMap
  13. {
  14. public enum MouseLeftButtonType
  15. {
  16. /// <summary>
  17. /// 无状态
  18. /// </summary>
  19. None,
  20. /// <summary>
  21. /// 拖拽模式
  22. /// </summary>
  23. Drag,
  24. /// <summary>
  25. /// 笔
  26. /// </summary>
  27. Pen,
  28. /// <summary>
  29. /// 区域模式
  30. /// </summary>
  31. Area
  32. }
  33. /// <summary>
  34. /// 自动图块地板层
  35. /// </summary>
  36. public const int AutoFloorLayer = 0;
  37. /// <summary>
  38. /// 自定义图块地板层
  39. /// </summary>
  40. public const int CustomFloorLayer = 1;
  41. /// <summary>
  42. /// 自动图块中间层
  43. /// </summary>
  44. public const int AutoMiddleLayer = 2;
  45. /// <summary>
  46. /// 自定义图块中间层
  47. /// </summary>
  48. public const int CustomMiddleLayer = 3;
  49. /// <summary>
  50. /// 自动图块顶层
  51. /// </summary>
  52. public const int AutoTopLayer = 4;
  53. /// <summary>
  54. /// 自定义图块顶层
  55. /// </summary>
  56. public const int CustomTopLayer = 5;
  57. /// <summary>
  58. /// 所属地图编辑器UI
  59. /// </summary>
  60. public MapEditorPanel MapEditorPanel { get; set; }
  61. /// <summary>
  62. /// 编辑器工具UI
  63. /// </summary>
  64. public MapEditorToolsPanel MapEditorToolsPanel { get; set; }
  65. //是否启用绘制图块
  66. private MouseLeftButtonType _mouseLeftButtonType = MouseLeftButtonType.None;
  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 Grid<bool> _autoCellLayerGrid = new Grid<bool>();
  88. //用于生成导航网格
  89. private DungeonTileMap _dungeonTileMap;
  90. //停止绘制多久后开始执行生成操作
  91. private float _generateInterval = 3f;
  92. //生成自动图块和导航网格的计时器
  93. private float _generateTimer = -1;
  94. //检测地形结果
  95. private bool _checkTerrainFlag = true;
  96. //错误地形位置
  97. private Vector2I _checkTerrainErrorPosition = Vector2I.Zero;
  98. //是否执行生成地形成功
  99. private bool _isGenerateTerrain = false;
  100. private bool _initLayer = false;
  101.  
  102. //--------- 配置数据 -------------
  103. private int _sourceId = 0;
  104. private int _terrainSet = 0;
  105. private int _terrain = 0;
  106. private AutoTileConfig _autoTileConfig = new AutoTileConfig();
  107. //原数据
  108. private DungeonRoomSplit _roomSplit;
  109.  
  110. //变动过的数据
  111. private Vector2I _roomPosition;
  112. private Vector2I _roomSize;
  113. private List<DoorAreaInfo> _doorConfigs = new List<DoorAreaInfo>();
  114. //-------------------------------
  115.  
  116. public override void _Ready()
  117. {
  118. InitLayer();
  119. }
  120.  
  121. public override void _Process(double delta)
  122. {
  123. var newDelta = (float)delta;
  124. _drawFullRect = false;
  125. var position = GetLocalMousePosition();
  126. _mouseCellPosition = LocalToMap(position);
  127. _mousePosition = new Vector2(
  128. _mouseCellPosition.X * GameConfig.TileCellSize,
  129. _mouseCellPosition.Y * GameConfig.TileCellSize
  130. );
  131. if (!MapEditorToolsPanel.S_HBoxContainer.Instance.IsPositionOver(GetGlobalMousePosition())) //不在Ui节点上
  132. {
  133. //左键绘制
  134. if (_isLeftPressed && _mouseLeftButtonType == MouseLeftButtonType.Pen)
  135. {
  136. if (Input.IsKeyPressed(Key.Shift)) //按住shift绘制矩形
  137. {
  138. _drawFullRect = true;
  139. }
  140. else if (_prevMouseCellPosition != _mouseCellPosition || !_changeFlag) //鼠标位置变过
  141. {
  142. _changeFlag = true;
  143. _prevMouseCellPosition = _mouseCellPosition;
  144. //绘制自动图块
  145. SetSingleAutoCell(_mouseCellPosition);
  146. }
  147. }
  148. else if (_isRightPressed && _mouseLeftButtonType == MouseLeftButtonType.Pen) //右键擦除
  149. {
  150. if (Input.IsKeyPressed(Key.Shift)) //按住shift擦除矩形
  151. {
  152. _drawFullRect = true;
  153. }
  154. else if (_prevMouseCellPosition != _mouseCellPosition || !_changeFlag) //鼠标位置变过
  155. {
  156. _changeFlag = true;
  157. _prevMouseCellPosition = _mouseCellPosition;
  158. EraseSingleAutoCell(_mouseCellPosition);
  159. }
  160. }
  161. else if (_isMiddlePressed) //中键移动
  162. {
  163. //GD.Print("移动...");
  164. SetMapPosition(GetGlobalMousePosition() + _moveOffset);
  165. }
  166. }
  167.  
  168. //绘制停止指定时间后, 生成导航网格
  169. if (_generateTimer > 0)
  170. {
  171. _generateTimer -= newDelta;
  172. if (_generateTimer <= 0)
  173. {
  174. //计算区域
  175. CalcTileRect();
  176. GD.Print("开始检测是否可以生成地形...");
  177. if (CheckTerrain())
  178. {
  179. GD.Print("开始绘制导航网格...");
  180. if (GenerateNavigation())
  181. {
  182. GD.Print("开始绘制自动贴图...");
  183. GenerateTerrain();
  184. _isGenerateTerrain = true;
  185. }
  186. }
  187. else
  188. {
  189. SetErrorCell(_checkTerrainErrorPosition);
  190. }
  191. }
  192. }
  193. }
  194.  
  195. /// <summary>
  196. /// 绘制辅助线
  197. /// </summary>
  198. public void DrawGuides(CanvasItem canvasItem)
  199. {
  200. //轴线
  201. canvasItem.DrawLine(new Vector2(0, 2000), new Vector2(0, -2000), Colors.Green);
  202. canvasItem.DrawLine(new Vector2(2000, 0), new Vector2( -2000, 0), Colors.Red);
  203. //绘制房间区域
  204. if (_roomSize.X != 0 && _roomSize.Y != 0)
  205. {
  206. var size = TileSet.TileSize;
  207. canvasItem.DrawRect(new Rect2(_roomPosition * size, _roomSize * size),
  208. Colors.Aqua, false, 5f / Scale.X);
  209. }
  210. if (_checkTerrainFlag) //已经通过地形检测
  211. {
  212. //绘制导航网格
  213. var result = _dungeonTileMap.GetGenerateNavigationResult();
  214. if (result != null && result.Success)
  215. {
  216. var polygonData = _dungeonTileMap.GetPolygonData();
  217. Utils.DrawNavigationPolygon(canvasItem, polygonData, 3f / Scale.X);
  218. }
  219. }
  220.  
  221. if (_mouseLeftButtonType == MouseLeftButtonType.Pen || _mouseLeftButtonType == MouseLeftButtonType.Area)
  222. {
  223. if (_drawFullRect) //绘制填充矩形
  224. {
  225. var size = TileSet.TileSize;
  226. var cellPos = _mouseStartCellPosition;
  227. var temp = size;
  228. if (_mouseStartCellPosition.X > _mouseCellPosition.X)
  229. {
  230. cellPos.X += 1;
  231. temp.X -= size.X;
  232. }
  233. if (_mouseStartCellPosition.Y > _mouseCellPosition.Y)
  234. {
  235. cellPos.Y += 1;
  236. temp.Y -= size.Y;
  237. }
  238.  
  239. var pos = cellPos * size;
  240. canvasItem.DrawRect(new Rect2(pos, _mousePosition - pos + temp), Colors.White, false, 2f / Scale.X);
  241. }
  242. else //绘制单格
  243. {
  244. canvasItem.DrawRect(new Rect2(_mousePosition, TileSet.TileSize), Colors.White, false, 2f / Scale.X);
  245. }
  246. }
  247. }
  248.  
  249. public override void _Input(InputEvent @event)
  250. {
  251. if (@event is InputEventMouseButton mouseButton)
  252. {
  253. if (mouseButton.ButtonIndex == MouseButton.Left) //左键
  254. {
  255. if (mouseButton.Pressed) //按下
  256. {
  257. _mouseStartCellPosition = LocalToMap(GetLocalMousePosition());
  258. }
  259. else
  260. {
  261. _changeFlag = false;
  262. if (_drawFullRect) //松开, 提交绘制的矩形区域
  263. {
  264. SetRectAutoCell(_mouseStartCellPosition, _mouseCellPosition);
  265. _drawFullRect = false;
  266. }
  267. }
  268.  
  269. _isLeftPressed = mouseButton.Pressed;
  270. }
  271. else if (mouseButton.ButtonIndex == MouseButton.Right) //右键
  272. {
  273. if (mouseButton.Pressed) //按下
  274. {
  275. _mouseStartCellPosition = LocalToMap(GetLocalMousePosition());
  276. }
  277. else
  278. {
  279. _changeFlag = false;
  280. if (_drawFullRect) //松开, 提交擦除的矩形区域
  281. {
  282. EraseRectAutoCell(_mouseStartCellPosition, _mouseCellPosition);
  283. _drawFullRect = false;
  284. }
  285. }
  286. _isRightPressed = mouseButton.Pressed;
  287. }
  288. else if (mouseButton.ButtonIndex == MouseButton.WheelDown)
  289. {
  290. //缩小
  291. Shrink();
  292. }
  293. else if (mouseButton.ButtonIndex == MouseButton.WheelUp)
  294. {
  295. //放大
  296. Magnify();
  297. }
  298. else if (mouseButton.ButtonIndex == MouseButton.Middle)
  299. {
  300. _isMiddlePressed = mouseButton.Pressed;
  301. if (_isMiddlePressed)
  302. {
  303. _moveOffset = Position - GetGlobalMousePosition();
  304. }
  305. }
  306. }
  307. else if (@event is InputEventKey eventKey)
  308. {
  309. if (eventKey.Pressed && eventKey.Keycode == Key.M)
  310. {
  311. GD.Print("保存地牢房间数据...");
  312. TriggerSave();
  313. }
  314. }
  315. }
  316.  
  317. //将指定层数据存入list中
  318. private void PushLayerDataToList(int layer, int sourceId, List<int> list)
  319. {
  320. var layerArray = GetUsedCellsById(layer, sourceId);
  321. foreach (var pos in layerArray)
  322. {
  323. var atlasCoords = GetCellAtlasCoords(layer, pos);
  324. list.Add(pos.X);
  325. list.Add(pos.Y);
  326. list.Add(_sourceId);
  327. list.Add(atlasCoords.X);
  328. list.Add(atlasCoords.Y);
  329. }
  330. }
  331.  
  332. private void SetLayerDataFromList(int layer, List<int> list)
  333. {
  334. for (var i = 0; i < list.Count; i += 5)
  335. {
  336. var pos = new Vector2I(list[i], list[i + 1]);
  337. var sourceId = list[i + 2];
  338. var atlasCoords = new Vector2I(list[i + 3], list[i + 4]);
  339. SetCell(layer, pos, sourceId, atlasCoords);
  340. if (layer == AutoFloorLayer)
  341. {
  342. _autoCellLayerGrid.Set(pos, true);
  343. }
  344. }
  345. }
  346.  
  347. //保存地牢
  348. private void TriggerSave()
  349. {
  350. SaveRoomInfoConfig();
  351. SaveTileInfoConfig();
  352. }
  353.  
  354. /// <summary>
  355. /// 加载地牢, 返回是否加载成功
  356. /// </summary>
  357. public bool Load(DungeonRoomSplit roomSplit)
  358. {
  359. _roomSplit = roomSplit;
  360. var roomInfo = roomSplit.RoomInfo;
  361. var tileInfo = roomSplit.TileInfo;
  362.  
  363. _roomPosition = roomInfo.Position.AsVector2I();
  364. _roomSize = roomInfo.Size.AsVector2I();
  365. _doorConfigs.Clear();
  366. _doorConfigs.AddRange(roomInfo.DoorAreaInfos);
  367.  
  368. //初始化层级数据
  369. InitLayer();
  370. //地块数据
  371. SetLayerDataFromList(AutoFloorLayer, tileInfo.Floor);
  372. SetLayerDataFromList(AutoMiddleLayer, tileInfo.Middle);
  373. SetLayerDataFromList(AutoTopLayer, tileInfo.Top);
  374. //导航网格数据
  375. _dungeonTileMap.SetPolygonData(tileInfo.NavigationList);
  376.  
  377. //聚焦
  378. //MapEditorPanel.CallDelay(0.1f, OnClickCenterTool);
  379. CallDeferred(nameof(OnClickCenterTool));
  380. return true;
  381. }
  382.  
  383. private void InitLayer()
  384. {
  385. if (_initLayer)
  386. {
  387. return;
  388. }
  389.  
  390. _initLayer = true;
  391. //初始化层级数据
  392. AddLayer(CustomFloorLayer);
  393. SetLayerZIndex(CustomFloorLayer, CustomFloorLayer);
  394. AddLayer(AutoMiddleLayer);
  395. SetLayerZIndex(AutoMiddleLayer, AutoMiddleLayer);
  396. AddLayer(CustomMiddleLayer);
  397. SetLayerZIndex(CustomMiddleLayer, CustomMiddleLayer);
  398. AddLayer(AutoTopLayer);
  399. SetLayerZIndex(AutoTopLayer, AutoTopLayer);
  400. AddLayer(CustomTopLayer);
  401. SetLayerZIndex(CustomTopLayer, CustomTopLayer);
  402.  
  403. _dungeonTileMap = new DungeonTileMap(this);
  404. _dungeonTileMap.SetFloorAtlasCoords(new List<Vector2I>(new []{ _autoTileConfig.Floor.AutoTileCoord }));
  405. }
  406.  
  407. //缩小
  408. private void Shrink()
  409. {
  410. var pos = GetLocalMousePosition();
  411. var scale = Scale / 1.1f;
  412. if (scale.LengthSquared() >= 0.5f)
  413. {
  414. Scale = scale;
  415. SetMapPosition(Position + pos * 0.1f * scale);
  416. }
  417. else
  418. {
  419. GD.Print("太小了");
  420. }
  421. }
  422. //放大
  423. private void Magnify()
  424. {
  425. var pos = GetLocalMousePosition();
  426. var prevScale = Scale;
  427. var scale = prevScale * 1.1f;
  428. if (scale.LengthSquared() <= 2000)
  429. {
  430. Scale = scale;
  431. SetMapPosition(Position - pos * 0.1f * prevScale);
  432. }
  433. else
  434. {
  435. GD.Print("太大了");
  436. }
  437. }
  438.  
  439. //绘制单个自动贴图
  440. private void SetSingleAutoCell(Vector2I position)
  441. {
  442. SetCell(GetFloorLayer(), position, _sourceId, _autoTileConfig.Floor.AutoTileCoord);
  443. if (!_autoCellLayerGrid.Contains(position.X, position.Y))
  444. {
  445. ResetGenerateTimer();
  446. _autoCellLayerGrid.Set(position.X, position.Y, true);
  447. }
  448. }
  449. //绘制区域自动贴图
  450. private void SetRectAutoCell(Vector2I start, Vector2I end)
  451. {
  452. ResetGenerateTimer();
  453. if (start.X > end.X)
  454. {
  455. var temp = end.X;
  456. end.X = start.X;
  457. start.X = temp;
  458. }
  459. if (start.Y > end.Y)
  460. {
  461. var temp = end.Y;
  462. end.Y = start.Y;
  463. start.Y = temp;
  464. }
  465.  
  466. var width = end.X - start.X + 1;
  467. var height = end.Y - start.Y + 1;
  468. for (var i = 0; i < width; i++)
  469. {
  470. for (var j = 0; j < height; j++)
  471. {
  472. SetCell(GetFloorLayer(), new Vector2I(start.X + i, start.Y + j), _sourceId, _autoTileConfig.Floor.AutoTileCoord);
  473. }
  474. }
  475.  
  476. _autoCellLayerGrid.SetRect(start, new Vector2I(width, height), true);
  477. }
  478.  
  479. //擦除单个自动图块
  480. private void EraseSingleAutoCell(Vector2I position)
  481. {
  482. EraseCell(GetFloorLayer(), position);
  483. if (_autoCellLayerGrid.Remove(position.X, position.Y))
  484. {
  485. ResetGenerateTimer();
  486. }
  487. }
  488. //擦除一个区域内的自动贴图
  489. private void EraseRectAutoCell(Vector2I start, Vector2I end)
  490. {
  491. ResetGenerateTimer();
  492. if (start.X > end.X)
  493. {
  494. var temp = end.X;
  495. end.X = start.X;
  496. start.X = temp;
  497. }
  498. if (start.Y > end.Y)
  499. {
  500. var temp = end.Y;
  501. end.Y = start.Y;
  502. start.Y = temp;
  503. }
  504.  
  505. var width = end.X - start.X + 1;
  506. var height = end.Y - start.Y + 1;
  507. for (var i = 0; i < width; i++)
  508. {
  509. for (var j = 0; j < height; j++)
  510. {
  511. EraseCell(GetFloorLayer(), new Vector2I(start.X + i, start.Y + j));
  512. }
  513. }
  514. _autoCellLayerGrid.RemoveRect(start, new Vector2I(width, height));
  515. }
  516.  
  517. //重置计时器
  518. private void ResetGenerateTimer()
  519. {
  520. _generateTimer = _generateInterval;
  521. _isGenerateTerrain = false;
  522. _dungeonTileMap.ClearPolygonData();
  523. ClearLayer(AutoTopLayer);
  524. ClearLayer(AutoMiddleLayer);
  525. }
  526.  
  527. //从新计算房间区域
  528. private void CalcTileRect()
  529. {
  530. var rect = GetUsedRect();
  531. _roomPosition = rect.Position;
  532. _roomSize = rect.Size;
  533. }
  534. //检测是否有不合规的图块, 返回true表示图块正常
  535. private bool CheckTerrain()
  536. {
  537. var x = _roomPosition.X;
  538. var y = _roomPosition.Y;
  539. var w = _roomSize.X;
  540. var h = _roomSize.Y;
  541.  
  542. for (var i = 0; i < w; i++)
  543. {
  544. for (var j = 0; j < h; j++)
  545. {
  546. var pos = new Vector2I(x + i, y + j);
  547. if (GetCellSourceId(AutoFloorLayer, pos) == -1)
  548. {
  549. //先检测对角是否有地板
  550. var left = _autoCellLayerGrid.Get(pos.X - 1, pos.Y);
  551. var right = _autoCellLayerGrid.Get(pos.X + 1, pos.Y);
  552. var top = _autoCellLayerGrid.Get(pos.X, pos.Y + 1);
  553. var down = _autoCellLayerGrid.Get(pos.X, pos.Y - 1);
  554. if ((left && right) || (top && down))
  555. {
  556. _checkTerrainFlag = false;
  557. _checkTerrainErrorPosition = pos;
  558. return false;
  559. }
  560. }
  561. }
  562. }
  563.  
  564. _checkTerrainFlag = true;
  565. return true;
  566. }
  567. //生成自动图块 (地形)
  568. private void GenerateTerrain()
  569. {
  570. ClearLayer(AutoFloorLayer);
  571. var list = new List<Vector2I>();
  572. _autoCellLayerGrid.ForEach((x, y, data) =>
  573. {
  574. if (data)
  575. {
  576. list.Add(new Vector2I(x, y));
  577. }
  578. });
  579. var arr = new Array<Vector2I>(list);
  580. //绘制自动图块
  581. SetCellsTerrainConnect(AutoFloorLayer, arr, _terrainSet, _terrain, false);
  582. //计算区域
  583. CalcTileRect();
  584. //将墙壁移动到指定层
  585. MoveTerrainCell();
  586. }
  587.  
  588. //将自动生成的图块从 AutoFloorLayer 移动到指定图层中
  589. private void MoveTerrainCell()
  590. {
  591. ClearLayer(AutoTopLayer);
  592. ClearLayer(AutoMiddleLayer);
  593. var x = _roomPosition.X;
  594. var y = _roomPosition.Y;
  595. var w = _roomSize.X;
  596. var h = _roomSize.Y;
  597.  
  598. for (var i = 0; i < w; i++)
  599. {
  600. for (var j = 0; j < h; j++)
  601. {
  602. var pos = new Vector2I(x + i, y + j);
  603. if (!_autoCellLayerGrid.Contains(pos) && GetCellSourceId(AutoFloorLayer, pos) != -1)
  604. {
  605. var atlasCoords = GetCellAtlasCoords(AutoFloorLayer, pos);
  606. var layer = _autoTileConfig.GetLayer(atlasCoords);
  607. if (layer == GameConfig.MiddleMapLayer)
  608. {
  609. layer = AutoMiddleLayer;
  610. }
  611. else if (layer == GameConfig.TopMapLayer)
  612. {
  613. layer = AutoTopLayer;
  614. }
  615. else
  616. {
  617. GD.PrintErr($"异常图块: {pos}, 这个图块的图集坐标'{atlasCoords}'不属于'MiddleMapLayer'和'TopMapLayer'!");
  618. continue;
  619. }
  620. EraseCell(AutoFloorLayer, pos);
  621. SetCell(layer, pos, _sourceId, atlasCoords);
  622. }
  623. }
  624. }
  625. }
  626.  
  627. //生成导航网格
  628. private bool GenerateNavigation()
  629. {
  630. _dungeonTileMap.GenerateNavigationPolygon(AutoFloorLayer);
  631. var result = _dungeonTileMap.GetGenerateNavigationResult();
  632. if (result.Success)
  633. {
  634. CloseErrorCell();
  635. }
  636. else
  637. {
  638. SetErrorCell(result.Exception.Point);
  639. }
  640.  
  641. return result.Success;
  642. }
  643.  
  644. //设置显示的错误cell, 会标记上红色的闪烁动画
  645. private void SetErrorCell(Vector2I pos)
  646. {
  647. MapEditorPanel.S_ErrorCell.Instance.Position = pos * CellQuadrantSize;
  648. MapEditorPanel.S_ErrorCellAnimationPlayer.Instance.Play(AnimatorNames.Show);
  649. }
  650.  
  651. //关闭显示的错误cell
  652. private void CloseErrorCell()
  653. {
  654. MapEditorPanel.S_ErrorCellAnimationPlayer.Instance.Stop();
  655. }
  656.  
  657. private int GetFloorLayer()
  658. {
  659. return AutoFloorLayer;
  660. }
  661.  
  662. private int GetMiddleLayer()
  663. {
  664. return AutoMiddleLayer;
  665. }
  666.  
  667. private int GetTopLayer()
  668. {
  669. return AutoTopLayer;
  670. }
  671.  
  672. /// <summary>
  673. /// 选中拖拽功能
  674. /// </summary>
  675. public void OnSelectHandTool()
  676. {
  677. }
  678. /// <summary>
  679. /// 选中画笔攻击
  680. /// </summary>
  681. public void OnSelectPenTool()
  682. {
  683. }
  684.  
  685. /// <summary>
  686. /// 选中绘制区域功能
  687. /// </summary>
  688. public void OnSelectRectTool()
  689. {
  690. }
  691.  
  692. /// <summary>
  693. /// 聚焦
  694. /// </summary>
  695. public void OnClickCenterTool()
  696. {
  697. var pos = MapEditorPanel.S_SubViewport.Instance.Size / 2;
  698. if (_roomSize.X == 0 && _roomSize.Y == 0) //聚焦原点
  699. {
  700. SetMapPosition(pos);
  701. }
  702. else //聚焦地图中心点
  703. {
  704. SetMapPosition(pos - (_roomPosition + _roomSize / 2) * TileSet.TileSize * Scale);
  705. }
  706. }
  707.  
  708. //保存房间配置
  709. private void SaveRoomInfoConfig()
  710. {
  711. //存入本地
  712. var roomInfo = _roomSplit.RoomInfo;
  713. var path = MapProjectManager.GetConfigPath(roomInfo.GroupName,roomInfo.RoomType, roomInfo.RoomName);
  714. if (!Directory.Exists(path))
  715. {
  716. Directory.CreateDirectory(path);
  717. }
  718. roomInfo.Position = new SerializeVector2(_roomPosition);
  719. roomInfo.Size = new SerializeVector2(_roomSize);
  720. roomInfo.DoorAreaInfos.Clear();
  721. roomInfo.DoorAreaInfos.AddRange(_doorConfigs);
  722.  
  723. path += "/" + MapProjectManager.GetRoomInfoConfigName(roomInfo.RoomName);
  724. var jsonStr = JsonSerializer.Serialize(roomInfo);
  725. File.WriteAllText(path, jsonStr);
  726. }
  727.  
  728. //保存地块数据
  729. public void SaveTileInfoConfig()
  730. {
  731. //存入本地
  732. var roomInfo = _roomSplit.RoomInfo;
  733. var path = MapProjectManager.GetConfigPath(roomInfo.GroupName,roomInfo.RoomType, roomInfo.RoomName);
  734. if (!Directory.Exists(path))
  735. {
  736. Directory.CreateDirectory(path);
  737. }
  738.  
  739. var tileInfo = _roomSplit.TileInfo;
  740. tileInfo.NavigationList.Clear();
  741. tileInfo.NavigationList.AddRange(_dungeonTileMap.GetPolygonData());
  742. tileInfo.Floor.Clear();
  743. tileInfo.Middle.Clear();
  744. tileInfo.Top.Clear();
  745.  
  746. PushLayerDataToList(AutoFloorLayer, _sourceId, tileInfo.Floor);
  747. PushLayerDataToList(AutoMiddleLayer, _sourceId, tileInfo.Middle);
  748. PushLayerDataToList(AutoTopLayer, _sourceId, tileInfo.Top);
  749. path += "/" + MapProjectManager.GetTileInfoConfigName(roomInfo.RoomName);
  750. var jsonStr = JsonSerializer.Serialize(tileInfo);
  751. File.WriteAllText(path, jsonStr);
  752. }
  753.  
  754. //设置地图坐标
  755. private void SetMapPosition(Vector2 pos)
  756. {
  757. Position = pos;
  758. MapEditorToolsPanel.SetDoorToolTransform(pos, Scale);
  759. }
  760. }