Newer
Older
DungeonShooting / DungeonShooting_Godot / src / framework / map / room / RoomDoorInfo.cs
@小李xl 小李xl on 18 Feb 2024 8 KB 2格高墙壁, 开发中
  1.  
  2. using System;
  3. using System.Collections.Generic;
  4. using Godot;
  5.  
  6. /// <summary>
  7. /// 房间的门
  8. /// </summary>
  9. public class RoomDoorInfo : IDestroy
  10. {
  11. public bool IsDestroyed { get; private set; }
  12.  
  13. /// <summary>
  14. /// 所在墙面方向
  15. /// </summary>
  16. public DoorDirection Direction;
  17.  
  18. /// <summary>
  19. /// 是否是正向的门
  20. /// </summary>
  21. public bool IsForward;
  22.  
  23. /// <summary>
  24. /// 所在的房间
  25. /// </summary>
  26. public RoomInfo RoomInfo;
  27.  
  28. /// <summary>
  29. /// 连接的门
  30. /// </summary>
  31. public RoomDoorInfo ConnectDoor;
  32.  
  33. /// <summary>
  34. /// 连接的房间
  35. /// </summary>
  36. public RoomInfo ConnectRoom;
  37.  
  38. /// <summary>
  39. /// 原点坐标, 单位: 格
  40. /// </summary>
  41. public Vector2I OriginPosition;
  42.  
  43. /// <summary>
  44. /// 地板所占的地板格子, 单位: 格, 使用时不需要加上 OriginPosition
  45. /// </summary>
  46. public HashSet<Vector2I> AisleFloorCell;
  47. /// <summary>
  48. /// 地板所占的矩形, 单位: 格, 使用时不需要加上 OriginPosition
  49. /// </summary>
  50. public Rect2I AisleFloorRect;
  51.  
  52. /// <summary>
  53. /// 与下一道门是否有交叉点
  54. /// </summary>
  55. public bool HasCross;
  56.  
  57. /// <summary>
  58. /// 与下一道门的交叉点, 单位: 格
  59. /// </summary>
  60. public Vector2I Cross;
  61.  
  62. /// <summary>
  63. /// 占位导航网格
  64. /// </summary>
  65. public DoorNavigationInfo Navigation;
  66.  
  67. /// <summary>
  68. /// 连接过道使用预览纹理, 用于小地图
  69. /// </summary>
  70. public ImageTexture AislePreviewTexture;
  71.  
  72. /// <summary>
  73. /// 连接过道使用预览图, 用于小地图
  74. /// </summary>
  75. public TextureRect AislePreviewSprite;
  76.  
  77. /// <summary>
  78. /// 门实例
  79. /// </summary>
  80. public RoomDoor Door;
  81.  
  82. /// <summary>
  83. /// 过道的迷雾
  84. /// </summary>
  85. public FogMask AisleFogMask;
  86.  
  87. /// <summary>
  88. /// 过道迷雾区域
  89. /// </summary>
  90. public AisleFogArea AisleFogArea;
  91.  
  92. /// <summary>
  93. /// 门区域预览房间迷雾
  94. /// </summary>
  95. public PreviewFogMask PreviewRoomFogMask;
  96. /// <summary>
  97. /// 门区域预览过道迷雾
  98. /// </summary>
  99. public PreviewFogMask PreviewAisleFogMask;
  100.  
  101. /// <summary>
  102. /// 未探索的区域显示的问号
  103. /// </summary>
  104. public Sprite2D UnknownSprite;
  105.  
  106. /// <summary>
  107. /// 世界坐标下的原点坐标, 单位: 像素
  108. /// </summary>
  109. public Vector2I GetWorldOriginPosition()
  110. {
  111. return new Vector2I(
  112. OriginPosition.X * GameConfig.TileCellSize,
  113. OriginPosition.Y * GameConfig.TileCellSize
  114. );
  115. }
  116.  
  117. /// <summary>
  118. /// 终点坐标, 单位: 格
  119. /// </summary>
  120. public Vector2I GetEndPosition()
  121. {
  122. if (Direction == DoorDirection.E || Direction == DoorDirection.W)
  123. {
  124. return OriginPosition + new Vector2I(0, 4);
  125. }
  126. else if (Direction == DoorDirection.N || Direction == DoorDirection.S)
  127. {
  128. return OriginPosition + new Vector2I(4, 0);
  129. }
  130.  
  131. return default;
  132. }
  133. /// <summary>
  134. /// 世界坐标下的终点坐标, 单位: 像素
  135. /// </summary>
  136. public Vector2I GetWorldEndPosition()
  137. {
  138. if (Direction == DoorDirection.E || Direction == DoorDirection.W)
  139. {
  140. return GetWorldOriginPosition() + new Vector2I(0, 4 * GameConfig.TileCellSize);
  141. }
  142. else if (Direction == DoorDirection.N || Direction == DoorDirection.S)
  143. {
  144. return GetWorldOriginPosition() + new Vector2I(4 * GameConfig.TileCellSize, 0);
  145. }
  146.  
  147. return default;
  148. }
  149.  
  150. /// <summary>
  151. /// 获取直连门过道区域数据, 单位: 格, 如果当前门连接区域带交叉点, 则报错
  152. /// </summary>
  153. public Rect2I GetAisleRect()
  154. {
  155. if (HasCross)
  156. {
  157. throw new Exception("当前门连接的过道包含交叉点, 请改用 GetCrossAisleRect() 函数!");
  158. }
  159. var rect = Utils.CalcRect(
  160. OriginPosition.X,
  161. OriginPosition.Y,
  162. ConnectDoor.OriginPosition.X,
  163. ConnectDoor.OriginPosition.Y
  164. );
  165. switch (Direction)
  166. {
  167. case DoorDirection.E:
  168. rect.Size = new Vector2I(rect.Size.X, GameConfig.CorridorWidth);
  169. break;
  170. case DoorDirection.W:
  171. rect.Size = new Vector2I(rect.Size.X, GameConfig.CorridorWidth);
  172. break;
  173. case DoorDirection.S:
  174. rect.Size = new Vector2I(GameConfig.CorridorWidth, rect.Size.Y);
  175. break;
  176. case DoorDirection.N:
  177. rect.Size = new Vector2I(GameConfig.CorridorWidth, rect.Size.Y);
  178. break;
  179. }
  180.  
  181. return rect;
  182. }
  183.  
  184. /// <summary>
  185. /// 获取交叉门过道区域数据, 单位: 格, 如果当前门连接区域不带交叉点, 则报错
  186. /// </summary>
  187. public CrossAisleRectData GetCrossAisleRect()
  188. {
  189. if (!HasCross)
  190. {
  191. throw new Exception("当前门连接的过道不包含交叉点, 请改用 GetAisleRect() 函数!");
  192. }
  193.  
  194. Rect2I rect;
  195. Rect2I rect2;
  196.  
  197. //计算范围
  198. switch (Direction)
  199. {
  200. case DoorDirection.E: //→
  201. rect = new Rect2I(
  202. OriginPosition.X,
  203. OriginPosition.Y,
  204. Cross.X - OriginPosition.X,
  205. GameConfig.CorridorWidth
  206. );
  207. break;
  208. case DoorDirection.W: //←
  209. rect = new Rect2I(
  210. Cross.X + GameConfig.CorridorWidth,
  211. Cross.Y,
  212. OriginPosition.X - (Cross.X + GameConfig.CorridorWidth),
  213. GameConfig.CorridorWidth
  214. );
  215. break;
  216. case DoorDirection.S: //↓
  217. rect = new Rect2I(
  218. OriginPosition.X,
  219. OriginPosition.Y,
  220. GameConfig.CorridorWidth,
  221. Cross.Y - OriginPosition.Y
  222. );
  223. break;
  224. case DoorDirection.N: //↑
  225. rect = new Rect2I(
  226. Cross.X,
  227. Cross.Y + GameConfig.CorridorWidth,
  228. GameConfig.CorridorWidth,
  229. OriginPosition.Y - (Cross.Y + GameConfig.CorridorWidth)
  230. );
  231. break;
  232. default:
  233. rect = new Rect2I();
  234. break;
  235. }
  236.  
  237. switch (ConnectDoor.Direction)
  238. {
  239. case DoorDirection.E: //→
  240. rect2 = new Rect2I(
  241. ConnectDoor.OriginPosition.X,
  242. ConnectDoor.OriginPosition.Y,
  243. Cross.X - ConnectDoor.OriginPosition.X,
  244. GameConfig.CorridorWidth
  245. );
  246. break;
  247. case DoorDirection.W: //←
  248. rect2 = new Rect2I(
  249. Cross.X + GameConfig.CorridorWidth,
  250. Cross.Y,
  251. ConnectDoor.OriginPosition.X -
  252. (Cross.X + GameConfig.CorridorWidth),
  253. GameConfig.CorridorWidth
  254. );
  255. break;
  256. case DoorDirection.S: //↓
  257. rect2 = new Rect2I(
  258. ConnectDoor.OriginPosition.X,
  259. ConnectDoor.OriginPosition.Y,
  260. GameConfig.CorridorWidth,
  261. Cross.Y - ConnectDoor.OriginPosition.Y
  262. );
  263. break;
  264. case DoorDirection.N: //↑
  265. rect2 = new Rect2I(
  266. Cross.X,
  267. Cross.Y + GameConfig.CorridorWidth,
  268. GameConfig.CorridorWidth,
  269. ConnectDoor.OriginPosition.Y -
  270. (Cross.Y + GameConfig.CorridorWidth)
  271. );
  272. break;
  273. default:
  274. rect2 = new Rect2I();
  275. break;
  276. }
  277.  
  278. return new CrossAisleRectData()
  279. {
  280. Rect1 = rect,
  281. Rect2 = rect2,
  282. Cross = new Rect2I(Cross + Vector2I.One, new Vector2I(GameConfig.CorridorWidth - 2, GameConfig.CorridorWidth - 2))
  283. };
  284. }
  285. public void Destroy()
  286. {
  287. if (IsDestroyed)
  288. {
  289. return;
  290. }
  291.  
  292. IsDestroyed = true;
  293. if (AisleFogMask != null)
  294. {
  295. AisleFogMask.Destroy();
  296. }
  297.  
  298. if (AisleFogArea != null)
  299. {
  300. AisleFogArea.Destroy();
  301. }
  302.  
  303. if (PreviewRoomFogMask != null)
  304. {
  305. PreviewRoomFogMask.Destroy();
  306. }
  307. if (PreviewAisleFogMask != null)
  308. {
  309. PreviewAisleFogMask.Destroy();
  310. }
  311.  
  312. if (AislePreviewTexture != null)
  313. {
  314. AislePreviewTexture.Dispose();
  315. }
  316.  
  317. if (AislePreviewSprite != null)
  318. {
  319. AislePreviewSprite.QueueFree();
  320. }
  321. }
  322. }