Newer
Older
DungeonShooting / DungeonShooting_Godot / src / framework / map / room / RoomDoorInfo.cs
@小李xl 小李xl on 20 Feb 2024 8 KB 弓箭功能开发中
  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 ImageTexture AislePreviewTexture;
  66.  
  67. /// <summary>
  68. /// 连接过道使用预览图, 用于小地图
  69. /// </summary>
  70. public TextureRect AislePreviewSprite;
  71.  
  72. /// <summary>
  73. /// 门实例
  74. /// </summary>
  75. public RoomDoor Door;
  76.  
  77. /// <summary>
  78. /// 过道的迷雾
  79. /// </summary>
  80. public FogMask AisleFogMask;
  81.  
  82. /// <summary>
  83. /// 过道迷雾区域
  84. /// </summary>
  85. public AisleFogArea AisleFogArea;
  86.  
  87. /// <summary>
  88. /// 门区域预览房间迷雾
  89. /// </summary>
  90. public PreviewFogMask PreviewRoomFogMask;
  91. /// <summary>
  92. /// 门区域预览过道迷雾
  93. /// </summary>
  94. public PreviewFogMask PreviewAisleFogMask;
  95.  
  96. /// <summary>
  97. /// 未探索的区域显示的问号
  98. /// </summary>
  99. public Sprite2D UnknownSprite;
  100.  
  101. /// <summary>
  102. /// 世界坐标下的原点坐标, 单位: 像素
  103. /// </summary>
  104. public Vector2I GetWorldOriginPosition()
  105. {
  106. return new Vector2I(
  107. OriginPosition.X * GameConfig.TileCellSize,
  108. OriginPosition.Y * GameConfig.TileCellSize
  109. );
  110. }
  111.  
  112. /// <summary>
  113. /// 终点坐标, 单位: 格
  114. /// </summary>
  115. public Vector2I GetEndPosition()
  116. {
  117. if (Direction == DoorDirection.E || Direction == DoorDirection.W)
  118. {
  119. return OriginPosition + new Vector2I(0, 4);
  120. }
  121. else if (Direction == DoorDirection.N || Direction == DoorDirection.S)
  122. {
  123. return OriginPosition + new Vector2I(4, 0);
  124. }
  125.  
  126. return default;
  127. }
  128. /// <summary>
  129. /// 世界坐标下的终点坐标, 单位: 像素
  130. /// </summary>
  131. public Vector2I GetWorldEndPosition()
  132. {
  133. if (Direction == DoorDirection.E || Direction == DoorDirection.W)
  134. {
  135. return GetWorldOriginPosition() + new Vector2I(0, 4 * GameConfig.TileCellSize);
  136. }
  137. else if (Direction == DoorDirection.N || Direction == DoorDirection.S)
  138. {
  139. return GetWorldOriginPosition() + new Vector2I(4 * GameConfig.TileCellSize, 0);
  140. }
  141.  
  142. return default;
  143. }
  144.  
  145. /// <summary>
  146. /// 获取直连门过道区域数据, 单位: 格, 如果当前门连接区域带交叉点, 则报错
  147. /// </summary>
  148. public Rect2I GetAisleRect()
  149. {
  150. if (HasCross)
  151. {
  152. throw new Exception("当前门连接的过道包含交叉点, 请改用 GetCrossAisleRect() 函数!");
  153. }
  154. var rect = Utils.CalcRect(
  155. OriginPosition.X,
  156. OriginPosition.Y,
  157. ConnectDoor.OriginPosition.X,
  158. ConnectDoor.OriginPosition.Y
  159. );
  160. switch (Direction)
  161. {
  162. case DoorDirection.E:
  163. rect.Size = new Vector2I(rect.Size.X, GameConfig.CorridorWidth);
  164. break;
  165. case DoorDirection.W:
  166. rect.Size = new Vector2I(rect.Size.X, GameConfig.CorridorWidth);
  167. break;
  168. case DoorDirection.S:
  169. rect.Size = new Vector2I(GameConfig.CorridorWidth, rect.Size.Y);
  170. break;
  171. case DoorDirection.N:
  172. rect.Size = new Vector2I(GameConfig.CorridorWidth, rect.Size.Y);
  173. break;
  174. }
  175.  
  176. return rect;
  177. }
  178.  
  179. /// <summary>
  180. /// 获取交叉门过道区域数据, 单位: 格, 如果当前门连接区域不带交叉点, 则报错
  181. /// </summary>
  182. public CrossAisleRectData GetCrossAisleRect()
  183. {
  184. if (!HasCross)
  185. {
  186. throw new Exception("当前门连接的过道不包含交叉点, 请改用 GetAisleRect() 函数!");
  187. }
  188.  
  189. Rect2I rect;
  190. Rect2I rect2;
  191.  
  192. //计算范围
  193. switch (Direction)
  194. {
  195. case DoorDirection.E: //→
  196. rect = new Rect2I(
  197. OriginPosition.X,
  198. OriginPosition.Y,
  199. Cross.X - OriginPosition.X,
  200. GameConfig.CorridorWidth
  201. );
  202. break;
  203. case DoorDirection.W: //←
  204. rect = new Rect2I(
  205. Cross.X + GameConfig.CorridorWidth,
  206. Cross.Y,
  207. OriginPosition.X - (Cross.X + GameConfig.CorridorWidth),
  208. GameConfig.CorridorWidth
  209. );
  210. break;
  211. case DoorDirection.S: //↓
  212. rect = new Rect2I(
  213. OriginPosition.X,
  214. OriginPosition.Y,
  215. GameConfig.CorridorWidth,
  216. Cross.Y - OriginPosition.Y
  217. );
  218. break;
  219. case DoorDirection.N: //↑
  220. rect = new Rect2I(
  221. Cross.X,
  222. Cross.Y + GameConfig.CorridorWidth,
  223. GameConfig.CorridorWidth,
  224. OriginPosition.Y - (Cross.Y + GameConfig.CorridorWidth)
  225. );
  226. break;
  227. default:
  228. rect = new Rect2I();
  229. break;
  230. }
  231.  
  232. switch (ConnectDoor.Direction)
  233. {
  234. case DoorDirection.E: //→
  235. rect2 = new Rect2I(
  236. ConnectDoor.OriginPosition.X,
  237. ConnectDoor.OriginPosition.Y,
  238. Cross.X - ConnectDoor.OriginPosition.X,
  239. GameConfig.CorridorWidth
  240. );
  241. break;
  242. case DoorDirection.W: //←
  243. rect2 = new Rect2I(
  244. Cross.X + GameConfig.CorridorWidth,
  245. Cross.Y,
  246. ConnectDoor.OriginPosition.X -
  247. (Cross.X + GameConfig.CorridorWidth),
  248. GameConfig.CorridorWidth
  249. );
  250. break;
  251. case DoorDirection.S: //↓
  252. rect2 = new Rect2I(
  253. ConnectDoor.OriginPosition.X,
  254. ConnectDoor.OriginPosition.Y,
  255. GameConfig.CorridorWidth,
  256. Cross.Y - ConnectDoor.OriginPosition.Y
  257. );
  258. break;
  259. case DoorDirection.N: //↑
  260. rect2 = new Rect2I(
  261. Cross.X,
  262. Cross.Y + GameConfig.CorridorWidth,
  263. GameConfig.CorridorWidth,
  264. ConnectDoor.OriginPosition.Y -
  265. (Cross.Y + GameConfig.CorridorWidth)
  266. );
  267. break;
  268. default:
  269. rect2 = new Rect2I();
  270. break;
  271. }
  272.  
  273. return new CrossAisleRectData()
  274. {
  275. Rect1 = rect,
  276. Rect2 = rect2,
  277. Cross = new Rect2I(Cross + Vector2I.One, new Vector2I(GameConfig.CorridorWidth - 2, GameConfig.CorridorWidth - 2))
  278. };
  279. }
  280. public void Destroy()
  281. {
  282. if (IsDestroyed)
  283. {
  284. return;
  285. }
  286.  
  287. IsDestroyed = true;
  288. if (AisleFogMask != null)
  289. {
  290. AisleFogMask.Destroy();
  291. }
  292.  
  293. if (AisleFogArea != null)
  294. {
  295. AisleFogArea.Destroy();
  296. }
  297.  
  298. if (PreviewRoomFogMask != null)
  299. {
  300. PreviewRoomFogMask.Destroy();
  301. }
  302. if (PreviewAisleFogMask != null)
  303. {
  304. PreviewAisleFogMask.Destroy();
  305. }
  306.  
  307. if (AislePreviewTexture != null)
  308. {
  309. AislePreviewTexture.Dispose();
  310. }
  311.  
  312. if (AislePreviewSprite != null)
  313. {
  314. AislePreviewSprite.QueueFree();
  315. }
  316. }
  317. }