Newer
Older
DungeonShooting / DungeonShooting_Godot / src / framework / map / DungeonRoomTemplate.cs
@小李xl 小李xl on 19 Feb 2023 28 KB 自动整合RoomConfig配置
  1.  
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Text.Json;
  6. using Godot;
  7.  
  8. [Tool]
  9. public partial class DungeonRoomTemplate : TileMap
  10. {
  11. /// <summary>
  12. /// 地图路径
  13. /// </summary>
  14. public static readonly string RoomTileDir = System.Environment.CurrentDirectory + "\\resource\\map\\tileMaps\\";
  15. /// <summary>
  16. /// 地图描述数据路径
  17. /// </summary>
  18. public static readonly string RoomTileDataDir = System.Environment.CurrentDirectory + "\\resource\\map\\tiledata\\";
  19. /// <summary>
  20. /// 房间配置汇总
  21. /// </summary>
  22. public static readonly string RoomTileConfigFile = System.Environment.CurrentDirectory + "\\resource\\map\\RoomConfig.json";
  23. #if TOOLS
  24. //是否悬停在线上
  25. private bool _hover = false;
  26.  
  27. //悬停点
  28. private Vector2 _hoverPoint1;
  29. private Vector2 _hoverPoint2;
  30. private DoorDirection _hoverDirection;
  31. private bool _canPut = false;
  32.  
  33. //选中点
  34. private bool _hasActivePoint = false;
  35. //选中左/右点
  36. private byte _activePointType = 0;
  37. private DoorAreaInfo _activeArea = null;
  38. //拖拽
  39. private bool _isDrag = false;
  40. private float _startDragValue;
  41. private Vector2 _startDragPositionValue;
  42. private bool _dragHasCollision = false;
  43.  
  44. private bool _mouseDown = false;
  45.  
  46. //
  47. private List<DoorAreaInfo> _doorConfigs;
  48. private Rect2 _prevRect;
  49. public override void _Process(double delta)
  50. {
  51. if (!Engine.IsEditorHint())
  52. {
  53. return;
  54. }
  55.  
  56. var initConfigs = false;
  57. if (_doorConfigs == null)
  58. {
  59. initConfigs = true;
  60. _doorConfigs = ReadConfig(CalcTileRange(this), Name);
  61. }
  62. var isClick = false;
  63. if (Input.IsMouseButtonPressed(MouseButton.Left))
  64. {
  65. if (!_mouseDown)
  66. {
  67. _mouseDown = true;
  68. isClick = true;
  69. }
  70. }
  71. else if (_mouseDown)
  72. {
  73. _mouseDown = false;
  74. isClick = false;
  75. }
  76.  
  77. if (Input.IsMouseButtonPressed(MouseButton.Middle)) //中键移除门
  78. {
  79. if (_activeArea != null)
  80. {
  81. RemoveDoorArea(_activeArea);
  82. _hasActivePoint = false;
  83. _activeArea = null;
  84. }
  85. }
  86. else if (TileSet != null)
  87. {
  88. var mapRect = CalcTileRange(this);
  89. var mousePosition = GetLocalMousePosition();
  90. if (mapRect != _prevRect)
  91. {
  92. if (!initConfigs)
  93. {
  94. OnMapRectChange(mapRect);
  95. }
  96. }
  97. _prevRect = mapRect;
  98. var tileSize = TileSet.TileSize;
  99. if (_isDrag) //拖拽中
  100. {
  101. if (_activeArea != null)
  102. {
  103. //拖拽节点操作
  104. if (_activeArea.Direction == DoorDirection.N || _activeArea.Direction == DoorDirection.S)
  105. {
  106. if (_activePointType == 0)
  107. {
  108. var mouseOffset = Approach(mousePosition.X, tileSize.X);
  109. _activeArea.StartPosition = new Vector2(mouseOffset, _activeArea.StartPosition.Y);
  110. _activeArea.Start = mouseOffset - mapRect.Position.X;
  111. _dragHasCollision = _activeArea.StartPosition.X <= mapRect.Position.X ||
  112. _activeArea.StartPosition.X + 3 * tileSize.X >= _activeArea.EndPosition.X ||
  113. CheckDoorCollision(_activeArea.Direction, _activeArea);
  114. }
  115. else
  116. {
  117. var mouseOffset = Approach(mousePosition.X, tileSize.X);
  118. _activeArea.EndPosition = new Vector2(mouseOffset, _activeArea.EndPosition.Y);
  119. _activeArea.End = mouseOffset - mapRect.Position.X;
  120. _dragHasCollision = _activeArea.EndPosition.X >= mapRect.Position.X + mapRect.Size.X ||
  121. _activeArea.EndPosition.X - 3 * tileSize.X <= _activeArea.StartPosition.X ||
  122. CheckDoorCollision(_activeArea.Direction, _activeArea);
  123. }
  124. }
  125. else
  126. {
  127. if (_activePointType == 0)
  128. {
  129. var mouseOffset = Approach(mousePosition.Y, tileSize.Y);
  130. _activeArea.StartPosition = new Vector2(_activeArea.StartPosition.X, mouseOffset);
  131. _activeArea.Start = mouseOffset - mapRect.Position.Y;
  132. _dragHasCollision = _activeArea.StartPosition.Y <= mapRect.Position.Y ||
  133. _activeArea.StartPosition.Y + 3 * tileSize.Y >= _activeArea.EndPosition.Y ||
  134. CheckDoorCollision(_activeArea.Direction, _activeArea);
  135. }
  136. else
  137. {
  138. var mouseOffset = Approach(mousePosition.Y, tileSize.Y);
  139. _activeArea.EndPosition = new Vector2(_activeArea.EndPosition.X, mouseOffset);
  140. _activeArea.End = mouseOffset - mapRect.Position.Y;
  141. _dragHasCollision = _activeArea.EndPosition.Y >= mapRect.Position.Y + mapRect.Size.Y ||
  142. _activeArea.EndPosition.Y - 3 * tileSize.Y <= _activeArea.StartPosition.Y ||
  143. CheckDoorCollision(_activeArea.Direction, _activeArea);
  144. }
  145. }
  146. }
  147. }
  148. else
  149. {
  150. if (Mathf.Abs(mousePosition.Y - mapRect.Position.Y) <= 8 && mousePosition.X >= mapRect.Position.X &&
  151. mousePosition.X <= mapRect.Position.X + mapRect.Size.X) //上
  152. {
  153. _hover = true;
  154. _hoverDirection = DoorDirection.N;
  155. var mouseOffset = Approach(mousePosition.X, tileSize.X);
  156. _hoverPoint1 = new Vector2(mouseOffset - tileSize.X * 2, mapRect.Position.Y);
  157. _hoverPoint2 = new Vector2(_hoverPoint1.X + tileSize.X * 4, _hoverPoint1.Y);
  158.  
  159. //判断是否能放下新的门
  160. if (_hoverPoint1.X <= mapRect.Position.X || _hoverPoint2.X >= mapRect.Position.X + mapRect.Size.X ||
  161. CheckDoorCollision())
  162. {
  163. _canPut = false;
  164. FindHoverPoint(mouseOffset);
  165. }
  166. else
  167. {
  168. _canPut = true;
  169. _hasActivePoint = false;
  170. _activeArea = null;
  171. }
  172. }
  173. else if (Mathf.Abs(mousePosition.X - mapRect.Position.X) <= 8 &&
  174. mousePosition.Y >= mapRect.Position.Y &&
  175. mousePosition.Y <= mapRect.Position.Y + mapRect.Size.Y) //左
  176. {
  177. _hover = true;
  178. _hoverDirection = DoorDirection.W;
  179. var mouseOffset = Approach(mousePosition.Y, tileSize.Y);
  180. _hoverPoint1 = new Vector2(mapRect.Position.X, mouseOffset - tileSize.Y * 2);
  181. _hoverPoint2 = new Vector2(_hoverPoint1.X, _hoverPoint1.Y + tileSize.X * 4);
  182.  
  183. //判断是否能放下新的门
  184. if (_hoverPoint1.Y <= mapRect.Position.Y || _hoverPoint2.Y >= mapRect.Position.Y + mapRect.Size.Y ||
  185. CheckDoorCollision())
  186. {
  187. _canPut = false;
  188. FindHoverPoint(mouseOffset);
  189. }
  190. else
  191. {
  192. _canPut = true;
  193. _hasActivePoint = false;
  194. _activeArea = null;
  195. }
  196. }
  197. else if (Mathf.Abs(mousePosition.Y - (mapRect.Position.Y + mapRect.Size.Y)) <= 8 &&
  198. mousePosition.X >= mapRect.Position.X &&
  199. mousePosition.X <= mapRect.Position.X + mapRect.Size.X) //下
  200. {
  201. _hover = true;
  202. _hoverDirection = DoorDirection.S;
  203. var mouseOffset = Approach(mousePosition.X, tileSize.X);
  204. _hoverPoint1 = new Vector2(mouseOffset - tileSize.X * 2,
  205. mapRect.Position.Y + mapRect.Size.Y);
  206. _hoverPoint2 = new Vector2(_hoverPoint1.X + tileSize.X * 4, _hoverPoint1.Y);
  207.  
  208. //判断是否能放下新的门
  209. if (_hoverPoint1.X <= mapRect.Position.X || _hoverPoint2.X >= mapRect.Position.X + mapRect.Size.X ||
  210. CheckDoorCollision())
  211. {
  212. _canPut = false;
  213. FindHoverPoint(mouseOffset);
  214. }
  215. else
  216. {
  217. _canPut = true;
  218. _hasActivePoint = false;
  219. _activeArea = null;
  220. }
  221. }
  222. else if (Mathf.Abs(mousePosition.X - (mapRect.Position.X + mapRect.Size.X)) <= 8 &&
  223. mousePosition.Y >= mapRect.Position.Y &&
  224. mousePosition.Y <= mapRect.Position.Y + mapRect.Size.Y) //右
  225. {
  226. _hover = true;
  227. _hoverDirection = DoorDirection.E;
  228. var mouseOffset = Approach(mousePosition.Y, tileSize.Y);
  229. _hoverPoint1 = new Vector2(mapRect.Position.X + mapRect.Size.X,
  230. mouseOffset - tileSize.Y * 2);
  231. _hoverPoint2 = new Vector2(_hoverPoint1.X, _hoverPoint1.Y + tileSize.X * 4);
  232.  
  233. //判断是否能放下新的门
  234. if (_hoverPoint1.Y <= mapRect.Position.Y || _hoverPoint2.Y >= mapRect.Position.Y + mapRect.Size.Y ||
  235. CheckDoorCollision())
  236. {
  237. _canPut = false;
  238. FindHoverPoint(mouseOffset);
  239. }
  240. else
  241. {
  242. _canPut = true;
  243. _hasActivePoint = false;
  244. _activeArea = null;
  245. }
  246. }
  247. else
  248. {
  249. _hover = false;
  250. _canPut = false;
  251. _hasActivePoint = false;
  252. _activeArea = null;
  253. }
  254. }
  255.  
  256.  
  257. if (isClick && _canPut) //判断是否可以创建新的点
  258. {
  259. CreateDoorArea(mapRect);
  260. }
  261. else if (_mouseDown && !_isDrag) //拖拽节点
  262. {
  263. _isDrag = true;
  264. _dragHasCollision = false;
  265. if (_activeArea != null)
  266. {
  267. if (_activePointType == 0)
  268. {
  269. _startDragValue = _activeArea.Start;
  270. _startDragPositionValue = _activeArea.StartPosition;
  271. }
  272. else
  273. {
  274. _startDragValue = _activeArea.End;
  275. _startDragPositionValue = _activeArea.EndPosition;
  276. }
  277. }
  278. }
  279. else if (!_mouseDown && _isDrag) //松开拖拽的点
  280. {
  281. _isDrag = false;
  282. if (_activeArea != null) //提交拖拽结果
  283. {
  284. if (_dragHasCollision)
  285. {
  286. if (_activePointType == 0)
  287. {
  288. _activeArea.Start = _startDragValue;
  289. _activeArea.StartPosition = _startDragPositionValue;
  290. }
  291. else
  292. {
  293. _activeArea.End = _startDragValue;
  294. _activeArea.EndPosition = _startDragPositionValue;
  295. }
  296. }
  297. OnDoorAreaChange();
  298. }
  299.  
  300. _dragHasCollision = false;
  301. }
  302. QueueRedraw();
  303. }
  304. else
  305. {
  306. _hover = false;
  307. _canPut = false;
  308. _hasActivePoint = false;
  309. _activeArea = null;
  310. }
  311. }
  312.  
  313. public override void _Draw()
  314. {
  315. if (!Engine.IsEditorHint())
  316. {
  317. return;
  318. }
  319. if (TileSet != null)
  320. {
  321. //绘制地图轮廓
  322. var mapRange = CalcTileRange(this);
  323. mapRange.Position -= new Vector2(2, 2);
  324. mapRange.Size += new Vector2(4, 4);
  325. DrawRect(mapRange, _hover ? Colors.Green : new Color(0.03137255F, 0.59607846F, 0.03137255F), false, 2);
  326.  
  327. //绘制悬停
  328. if (_hover && !_isDrag)
  329. {
  330. if (!_hasActivePoint) //这里判断是否悬停在拖动点上
  331. {
  332. var color = _canPut ? new Color(0, 1, 0, 0.2f) : new Color(1, 0, 0, 0.2f);
  333. switch (_hoverDirection)
  334. {
  335. case DoorDirection.E:
  336. DrawRect(
  337. new Rect2(new Vector2(_hoverPoint1.X + 2, _hoverPoint1.Y), 30,
  338. _hoverPoint2.Y - _hoverPoint1.Y), color);
  339. DrawCircle(new Vector2(_hoverPoint1.X + 2, _hoverPoint1.Y), 5, color);
  340. DrawCircle(new Vector2(_hoverPoint2.X + 2, _hoverPoint2.Y), 5, color);
  341. break;
  342. case DoorDirection.W:
  343. DrawRect(
  344. new Rect2(new Vector2(_hoverPoint1.X - 2 - 30, _hoverPoint1.Y), 30,
  345. _hoverPoint2.Y - _hoverPoint1.Y), color);
  346. DrawCircle(new Vector2(_hoverPoint1.X - 2, _hoverPoint1.Y), 5, color);
  347. DrawCircle(new Vector2(_hoverPoint2.X - 2, _hoverPoint2.Y), 5, color);
  348. break;
  349. case DoorDirection.S:
  350. DrawRect(
  351. new Rect2(new Vector2(_hoverPoint1.X, _hoverPoint1.Y + 2),
  352. _hoverPoint2.X - _hoverPoint1.X, 30), color);
  353. DrawCircle(new Vector2(_hoverPoint1.X, _hoverPoint1.Y + 2), 5, color);
  354. DrawCircle(new Vector2(_hoverPoint2.X, _hoverPoint2.Y + 2), 5, color);
  355. break;
  356. case DoorDirection.N:
  357. DrawRect(
  358. new Rect2(new Vector2(_hoverPoint1.X, _hoverPoint1.Y - 30 - 2),
  359. _hoverPoint2.X - _hoverPoint1.X, 30), color);
  360. DrawCircle(new Vector2(_hoverPoint1.X, _hoverPoint1.Y - 2), 5, color);
  361. DrawCircle(new Vector2(_hoverPoint2.X, _hoverPoint2.Y - 2), 5, color);
  362. break;
  363. }
  364. }
  365. }
  366.  
  367. if (_doorConfigs != null)
  368. {
  369. var color2 = new Color(0, 1, 0, 0.8f);
  370. //绘制已经存在的
  371. foreach (var doorAreaInfo in _doorConfigs)
  372. {
  373. var flag = _hasActivePoint && _activeArea == doorAreaInfo;
  374. var color3 = (flag && _activePointType == 0)
  375. ? (_isDrag
  376. ? (_dragHasCollision
  377. ? new Color(1, 0, 0, 0.8f)
  378. : new Color(0.2F, 0.4117647F, 0.8392157F, 0.8f))
  379. : new Color(1, 1, 1, 0.8f))
  380. : color2;
  381. var color4 = (flag && _activePointType == 1)
  382. ? (_isDrag
  383. ? (_dragHasCollision
  384. ? new Color(1, 0, 0, 0.8f)
  385. : new Color(0.2F, 0.4117647F, 0.8392157F, 0.8f))
  386. : new Color(1, 1, 1, 0.8f))
  387. : color2;
  388. switch (doorAreaInfo.Direction)
  389. {
  390. case DoorDirection.E:
  391. DrawRect(
  392. new Rect2(
  393. new Vector2(mapRange.Position.X + mapRange.Size.X,
  394. mapRange.Position.Y + doorAreaInfo.Start + 2), 30,
  395. doorAreaInfo.End - doorAreaInfo.Start), color2);
  396. DrawCircle(
  397. new Vector2(mapRange.Position.X + mapRange.Size.X,
  398. mapRange.Position.Y + doorAreaInfo.Start + 2), 5, color3);
  399. DrawCircle(
  400. new Vector2(mapRange.Position.X + mapRange.Size.X,
  401. mapRange.Position.Y + doorAreaInfo.End + 2),
  402. 5, color4);
  403. break;
  404. case DoorDirection.W:
  405. DrawRect(
  406. new Rect2(
  407. new Vector2(mapRange.Position.X - 30, mapRange.Position.Y + doorAreaInfo.Start + 2),
  408. 30, doorAreaInfo.End - doorAreaInfo.Start), color2);
  409. DrawCircle(new Vector2(mapRange.Position.X, mapRange.Position.Y + doorAreaInfo.Start + 2),
  410. 5,
  411. color3);
  412. DrawCircle(new Vector2(mapRange.Position.X, mapRange.Position.Y + doorAreaInfo.End + 2), 5,
  413. color4);
  414. break;
  415. case DoorDirection.S:
  416. DrawRect(
  417. new Rect2(
  418. new Vector2(mapRange.Position.X + doorAreaInfo.Start + 2,
  419. mapRange.Position.Y + mapRange.Size.Y), doorAreaInfo.End - doorAreaInfo.Start,
  420. 30),
  421. color2);
  422. DrawCircle(
  423. new Vector2(mapRange.Position.X + doorAreaInfo.Start + 2,
  424. mapRange.Position.Y + mapRange.Size.Y), 5, color3);
  425. DrawCircle(
  426. new Vector2(mapRange.Position.X + doorAreaInfo.End + 2,
  427. mapRange.Position.Y + mapRange.Size.Y),
  428. 5, color4);
  429. break;
  430. case DoorDirection.N:
  431. DrawRect(
  432. new Rect2(
  433. new Vector2(mapRange.Position.X + doorAreaInfo.Start + 2, mapRange.Position.Y - 30),
  434. doorAreaInfo.End - doorAreaInfo.Start, 30), color2);
  435. DrawCircle(new Vector2(mapRange.Position.X + doorAreaInfo.Start + 2, mapRange.Position.Y),
  436. 5,
  437. color3);
  438. DrawCircle(new Vector2(mapRange.Position.X + doorAreaInfo.End + 2, mapRange.Position.Y), 5,
  439. color4);
  440. break;
  441. }
  442. }
  443. }
  444. }
  445. }
  446.  
  447. //创建门
  448. private void CreateDoorArea(Rect2 mapRect)
  449. {
  450. var doorAreaInfo = new DoorAreaInfo();
  451. doorAreaInfo.Direction = _hoverDirection;
  452. doorAreaInfo.StartPosition = _hoverPoint1;
  453. doorAreaInfo.EndPosition = _hoverPoint2;
  454. switch (_hoverDirection)
  455. {
  456. case DoorDirection.E:
  457. case DoorDirection.W:
  458. doorAreaInfo.Start = _hoverPoint1.Y - mapRect.Position.Y;
  459. doorAreaInfo.End = _hoverPoint2.Y - mapRect.Position.Y;
  460. break;
  461. case DoorDirection.N:
  462. case DoorDirection.S:
  463. doorAreaInfo.Start = _hoverPoint1.X - mapRect.Position.X;
  464. doorAreaInfo.End = _hoverPoint2.X - mapRect.Position.X;
  465. break;
  466. }
  467.  
  468. _doorConfigs.Add(doorAreaInfo);
  469. OnDoorAreaChange();
  470. }
  471.  
  472. //移除门
  473. private void RemoveDoorArea(DoorAreaInfo doorAreaInfo)
  474. {
  475. _doorConfigs.Remove(doorAreaInfo);
  476. OnDoorAreaChange();
  477. }
  478.  
  479. //检查门是否有碰撞
  480. private bool CheckDoorCollision()
  481. {
  482. foreach (var doorAreaInfo in _doorConfigs)
  483. {
  484. if (doorAreaInfo.Direction == _hoverDirection)
  485. {
  486. switch (_hoverDirection)
  487. {
  488. case DoorDirection.E:
  489. case DoorDirection.W:
  490. if (CheckValueCollision(doorAreaInfo.StartPosition.Y, doorAreaInfo.EndPosition.Y, _hoverPoint1.Y, _hoverPoint2.Y))
  491. {
  492. return true;
  493. }
  494. break;
  495. case DoorDirection.S:
  496. case DoorDirection.N:
  497. if (CheckValueCollision(doorAreaInfo.StartPosition.X, doorAreaInfo.EndPosition.X, _hoverPoint1.X, _hoverPoint2.X))
  498. {
  499. return true;
  500. }
  501. break;
  502. }
  503. }
  504. }
  505.  
  506. return false;
  507. }
  508.  
  509. //检查门是否有碰撞
  510. private bool CheckDoorCollision(DoorDirection direction, DoorAreaInfo info)
  511. {
  512. foreach (var doorAreaInfo in _doorConfigs)
  513. {
  514. if (doorAreaInfo.Direction == direction && info != doorAreaInfo &&
  515. CheckValueCollision(doorAreaInfo.Start, doorAreaInfo.End, info.Start, info.End))
  516. {
  517. return true;
  518. }
  519. }
  520.  
  521. return false;
  522. }
  523. private bool CheckValueCollision(float o1, float o2, float h1, float h2)
  524. {
  525. var size = TileSet.TileSize.X;
  526. return !(h2 < o1 - 3 * size || o2 + 3 * size < h1);
  527. }
  528.  
  529. private void FindHoverPoint(float mouseOffset)
  530. {
  531. if (_isDrag)
  532. {
  533. return;
  534. }
  535. //检测是否有碰撞的点
  536. var flag = false;
  537. foreach (var doorAreaInfo in _doorConfigs)
  538. {
  539. if (doorAreaInfo.Direction == _hoverDirection)
  540. {
  541. if (_hoverDirection == DoorDirection.N || _hoverDirection == DoorDirection.S)
  542. {
  543. if (Math.Abs(doorAreaInfo.StartPosition.X - mouseOffset) < 0.0001f)
  544. {
  545. _hasActivePoint = true;
  546. _activePointType = 0;
  547. _activeArea = doorAreaInfo;
  548. flag = true;
  549. break;
  550. }
  551. else if (Math.Abs(doorAreaInfo.EndPosition.X - mouseOffset) < 0.0001f)
  552. {
  553. _hasActivePoint = true;
  554. _activePointType = 1;
  555. _activeArea = doorAreaInfo;
  556. flag = true;
  557. break;
  558. }
  559. }
  560. else
  561. {
  562. if (Math.Abs(doorAreaInfo.StartPosition.Y - mouseOffset) < 0.0001f)
  563. {
  564. _hasActivePoint = true;
  565. _activePointType = 0;
  566. _activeArea = doorAreaInfo;
  567. flag = true;
  568. break;
  569. }
  570. else if (Math.Abs(doorAreaInfo.EndPosition.Y - mouseOffset) < 0.0001f)
  571. {
  572. _hasActivePoint = true;
  573. _activePointType = 1;
  574. _activeArea = doorAreaInfo;
  575. flag = true;
  576. break;
  577. }
  578. }
  579. }
  580. }
  581.  
  582. if (!flag)
  583. {
  584. _hasActivePoint = false;
  585. _activeArea = null;
  586. }
  587. }
  588.  
  589. private float Approach(float value, float period)
  590. {
  591. var temp = value % period;
  592. if (Mathf.Abs(temp) >= period / 2)
  593. {
  594. return ((int)(value / period) + (value >= 0 ? 1 : -1)) * period;
  595. }
  596.  
  597. return (int)(value / period) * period;
  598. }
  599.  
  600. //地图大小改变
  601. private void OnMapRectChange(Rect2 mapRect)
  602. {
  603. _doorConfigs.Clear();
  604. _canPut = false;
  605. _hasActivePoint = false;
  606. _activeArea = null;
  607. OnDoorAreaChange();
  608. }
  609.  
  610. //区域数据修改
  611. private void OnDoorAreaChange()
  612. {
  613. SaveConfig(_doorConfigs, CalcTileRange(this), Name);
  614. }
  615. /// <summary>
  616. /// 计算tile所占区域
  617. /// </summary>
  618. /// <returns></returns>
  619. public static Rect2 CalcTileRange(TileMap tileMap)
  620. {
  621. var usedRect = tileMap.GetUsedRect();
  622. var pos = usedRect.Position * tileMap.TileSet.TileSize;
  623. var size = usedRect.Size * tileMap.TileSet.TileSize;
  624. return new Rect2(tileMap.ToLocal(pos), size);
  625. }
  626. /// <summary>
  627. /// 保存房间配置
  628. /// </summary>
  629. public static void SaveConfig(List<DoorAreaInfo> doorConfigs, Rect2 mapRect, string name)
  630. {
  631. //存入本地
  632. var path = RoomTileDataDir + name + ".json";
  633. var roomInfo = new DungeonRoomInfo();
  634. roomInfo.Position = new SerializeVector2(mapRect.Position.X, mapRect.Position.Y);
  635. roomInfo.Size = new SerializeVector2(mapRect.Size.X, mapRect.Size.Y);
  636. roomInfo.DoorAreaInfos = doorConfigs;
  637. var config = new JsonSerializerOptions();
  638. config.WriteIndented = true;
  639. var jsonStr = JsonSerializer.Serialize(roomInfo, config);
  640. File.WriteAllText(path, jsonStr);
  641. }
  642.  
  643. /// <summary>
  644. /// 读取房间配置
  645. /// </summary>
  646. public static List<DoorAreaInfo> ReadConfig(Rect2 mapRect, string name)
  647. {
  648. var path = RoomTileDataDir + name + ".json";
  649. if (File.Exists(path))
  650. {
  651. var text = File.ReadAllText(path);
  652. try
  653. {
  654. var roomInfo = JsonSerializer.Deserialize<DungeonRoomInfo>(text);
  655. foreach (var doorAreaInfo in roomInfo.DoorAreaInfos)
  656. {
  657. switch (doorAreaInfo.Direction)
  658. {
  659. case DoorDirection.E:
  660. doorAreaInfo.StartPosition = new Vector2(mapRect.Position.X, mapRect.Position.Y + doorAreaInfo.Start);
  661. doorAreaInfo.EndPosition = new Vector2(mapRect.Position.X, mapRect.Position.Y + doorAreaInfo.End);
  662. break;
  663. case DoorDirection.W:
  664. doorAreaInfo.StartPosition = new Vector2(mapRect.Position.X + mapRect.Size.X, mapRect.Position.Y + doorAreaInfo.Start);
  665. doorAreaInfo.EndPosition = new Vector2(mapRect.Position.X + mapRect.Size.X, mapRect.Position.Y + doorAreaInfo.End);
  666. break;
  667. case DoorDirection.S:
  668. doorAreaInfo.StartPosition = new Vector2(mapRect.Position.X + doorAreaInfo.Start, mapRect.Position.Y + mapRect.Size.Y);
  669. doorAreaInfo.EndPosition = new Vector2(mapRect.Position.X + doorAreaInfo.End, mapRect.Position.Y + mapRect.Size.Y);
  670. break;
  671. case DoorDirection.N:
  672. doorAreaInfo.StartPosition = new Vector2(mapRect.Position.X + doorAreaInfo.Start, mapRect.Position.Y);
  673. doorAreaInfo.EndPosition = new Vector2(mapRect.Position.X + doorAreaInfo.End, mapRect.Position.Y);
  674. break;
  675. }
  676. }
  677.  
  678. return roomInfo.DoorAreaInfos;
  679. }
  680. catch (Exception e)
  681. {
  682. GD.PrintErr($"加载房间数据'{path}'发生异常: " + e);
  683. return new List<DoorAreaInfo>();
  684. }
  685. }
  686. else
  687. {
  688. return new List<DoorAreaInfo>();
  689. }
  690. }
  691. #endif
  692. }