Newer
Older
DungeonShooting / DungeonShooting_Godot / src / framework / map / room / RoomInfo.cs
@小李xl 小李xl on 11 Oct 2023 10 KB 过道迷雾过渡, 开发完成
  1.  
  2. using System;
  3. using System.Collections.Generic;
  4. using Godot;
  5.  
  6. /// <summary>
  7. /// 房间的数据描述
  8. /// </summary>
  9. public class RoomInfo : IDestroy
  10. {
  11. public RoomInfo(int id, DungeonRoomType type, DungeonRoomSplit roomSplit)
  12. {
  13. Id = id;
  14. RoomType = type;
  15. RoomSplit = roomSplit;
  16. }
  17.  
  18. /// <summary>
  19. /// 房间 id
  20. /// </summary>
  21. public int Id;
  22.  
  23. /// <summary>
  24. /// 房间类型
  25. /// </summary>
  26. public DungeonRoomType RoomType;
  27.  
  28. /// <summary>
  29. /// 层级, 也就是离初始房间间隔多少个房间
  30. /// </summary>
  31. public int Layer;
  32. /// <summary>
  33. /// 生成该房间使用的配置数据
  34. /// </summary>
  35. public DungeonRoomSplit RoomSplit;
  36. /// <summary>
  37. /// 房间大小, 单位: 格
  38. /// </summary>
  39. public Vector2I Size;
  40.  
  41. /// <summary>
  42. /// 房间位置, 单位: 格
  43. /// </summary>
  44. public Vector2I Position;
  45. /// <summary>
  46. /// 门
  47. /// </summary>
  48. public List<RoomDoorInfo> Doors = new List<RoomDoorInfo>();
  49.  
  50. /// <summary>
  51. /// 连接该房间的过道占用区域信息
  52. /// </summary>
  53. public List<Rect2I> AisleArea = new List<Rect2I>();
  54.  
  55. /// <summary>
  56. /// 下一个房间
  57. /// </summary>
  58. public List<RoomInfo> Next = new List<RoomInfo>();
  59. /// <summary>
  60. /// 上一个房间
  61. /// </summary>
  62. public RoomInfo Prev;
  63.  
  64. /// <summary>
  65. /// 当前房间使用的预设
  66. /// </summary>
  67. public RoomPreinstall RoomPreinstall;
  68.  
  69. /// <summary>
  70. /// 当前房间归属区域
  71. /// </summary>
  72. public AffiliationArea AffiliationArea;
  73.  
  74. /// <summary>
  75. /// 静态精灵绘制画布
  76. /// </summary>
  77. public RoomStaticImageCanvas StaticImageCanvas;
  78.  
  79. /// <summary>
  80. /// 房间迷雾
  81. /// </summary>
  82. public FogMask RoomFogMask;
  83. /// <summary>
  84. /// 房间算上连接通道所占用的区域
  85. /// </summary>
  86. public Rect2I OuterRange { get; private set; }
  87.  
  88. /// <summary>
  89. /// 是否处于闭关状态, 也就是房间门没有主动打开
  90. /// </summary>
  91. public bool IsSeclusion { get; private set; } = false;
  92. public bool IsDestroyed { get; private set; }
  93. private bool _openDoorFlag = true;
  94. // private bool _beReady = false;
  95. // private bool _waveStart = false;
  96. // private int _currWaveIndex = 0;
  97. // private int _currWaveNumber = 0;
  98. //private List<ActivityMark> _currActivityMarks = new List<ActivityMark>();
  99.  
  100. /// <summary>
  101. /// 重新计算占用的区域
  102. /// </summary>
  103. public void CalcOuterRange()
  104. {
  105. var worldPos = GetWorldPosition();
  106. var pos = new Vector2I(worldPos.X, worldPos.Y);
  107. var minX = pos.X;
  108. var minY = pos.Y;
  109. var maxX = minX + GetWidth();
  110. var maxY = minY + GetHeight();
  111.  
  112. //遍历每一个连接的门, 计算计算canvas覆盖范围
  113. foreach (var doorInfo in Doors)
  114. {
  115. var connectDoor = doorInfo.ConnectDoor;
  116. switch (connectDoor.Direction)
  117. {
  118. case DoorDirection.E:
  119. case DoorDirection.W:
  120. {
  121. var (px1, py1) = connectDoor.GetWorldOriginPosition();
  122. var py2 = py1 + 4 * GameConfig.TileCellSize;
  123. if (px1 < minX)
  124. {
  125. minX = px1;
  126. }
  127. else if (px1 > maxX)
  128. {
  129. maxX = px1;
  130. }
  131.  
  132. if (py1 < minY)
  133. {
  134. minY = py1;
  135. }
  136. else if (py1 > maxY)
  137. {
  138. maxY = py1;
  139. }
  140. if (py2 < minY)
  141. {
  142. minY = py2;
  143. }
  144. else if (py2 > maxY)
  145. {
  146. maxY = py2;
  147. }
  148. }
  149. break;
  150. case DoorDirection.S:
  151. case DoorDirection.N:
  152. {
  153. var (px1, py1) = connectDoor.GetWorldOriginPosition();
  154. var px2 = px1 + 4 * GameConfig.TileCellSize;
  155. if (px1 < minX)
  156. {
  157. minX = px1;
  158. }
  159. else if (px1 > maxX)
  160. {
  161. maxX = px1;
  162. }
  163.  
  164. if (py1 < minY)
  165. {
  166. minY = py1;
  167. }
  168. else if (py1 > maxY)
  169. {
  170. maxY = py1;
  171. }
  172. if (px2 < minX)
  173. {
  174. minX = px2;
  175. }
  176. else if (px2 > maxX)
  177. {
  178. maxX = px2;
  179. }
  180. }
  181. break;
  182. }
  183. }
  184.  
  185. OuterRange = new Rect2I(minX, minY, maxX - minX, maxY - minY);
  186. }
  187. /// <summary>
  188. /// 获取房间的全局坐标, 单位: 像素
  189. /// </summary>
  190. public Vector2I GetWorldPosition()
  191. {
  192. return new Vector2I(
  193. Position.X * GameConfig.TileCellSize,
  194. Position.Y * GameConfig.TileCellSize
  195. );
  196. }
  197.  
  198. /// <summary>
  199. /// 获取房间左上角的 Tile 距离全局坐标原点的偏移, 单位: 像素
  200. /// </summary>
  201. /// <returns></returns>
  202. public Vector2I GetOffsetPosition()
  203. {
  204. return RoomSplit.RoomInfo.Position.AsVector2I() * GameConfig.TileCellSize;
  205. }
  206. /// <summary>
  207. /// 获取房间横轴结束位置, 单位: 格
  208. /// </summary>
  209. public int GetHorizontalEnd()
  210. {
  211. return Position.X + Size.X;
  212. }
  213.  
  214. /// <summary>
  215. /// 获取房间纵轴结束位置, 单位: 格
  216. /// </summary>
  217. public int GetVerticalEnd()
  218. {
  219. return Position.Y + Size.Y;
  220. }
  221. /// <summary>
  222. /// 获取房间横轴开始位置, 单位: 格
  223. /// </summary>
  224. public int GetHorizontalStart()
  225. {
  226. return Position.X;
  227. }
  228.  
  229. /// <summary>
  230. /// 获取房间纵轴开始位置, 单位: 格
  231. /// </summary>
  232. public int GetVerticalStart()
  233. {
  234. return Position.Y;
  235. }
  236.  
  237. /// <summary>
  238. /// 获取房间宽度, 单位: 像素
  239. /// </summary>
  240. public int GetWidth()
  241. {
  242. return Size.X * GameConfig.TileCellSize;
  243. }
  244. /// <summary>
  245. /// 获取房间高度, 单位: 像素
  246. /// </summary>
  247. public int GetHeight()
  248. {
  249. return Size.Y * GameConfig.TileCellSize;
  250. }
  251. public void Destroy()
  252. {
  253. if (IsDestroyed)
  254. {
  255. return;
  256. }
  257.  
  258. IsDestroyed = true;
  259. //递归销毁下一个房间
  260. foreach (var nextRoom in Next)
  261. {
  262. nextRoom.Destroy();
  263. }
  264. Next.Clear();
  265. //销毁连接的门
  266. foreach (var roomDoorInfo in Doors)
  267. {
  268. roomDoorInfo.Destroy();
  269. }
  270. //销毁预设
  271. if (RoomPreinstall != null)
  272. {
  273. RoomPreinstall.Destroy();
  274. RoomPreinstall = null;
  275. }
  276. //销毁画布
  277. if (StaticImageCanvas != null)
  278. {
  279. StaticImageCanvas.Destroy();
  280. }
  281.  
  282. //销毁迷雾
  283. if (RoomFogMask != null)
  284. {
  285. RoomFogMask.Destroy();
  286. }
  287.  
  288. //销毁所属区域对象
  289. if (AffiliationArea != null)
  290. {
  291. AffiliationArea.Destroy();
  292. }
  293. }
  294. /// <summary>
  295. /// 加载地牢完成
  296. /// </summary>
  297. public void OnReady()
  298. {
  299. //提前加载波
  300. RoomPreinstall.OnReady();
  301. }
  302. /// <summary>
  303. /// 玩家第一次进入房间, 房间准备好了, 准备刷敌人, 并且关闭所有<br/>
  304. /// 当清完每一波刷新的敌人后即可开门
  305. /// </summary>
  306. public void OnFirstEnter()
  307. {
  308. if (RoomPreinstall.IsRunWave)
  309. {
  310. return;
  311. }
  312. //房间内有敌人, 或者会刷新敌人才会关门
  313. var hasEnemy = false;
  314. if (AffiliationArea.ExistEnterItem(activityObject => activityObject.CollisionWithMask(PhysicsLayer.Enemy))) //先判断房间里面是否有敌人
  315. {
  316. hasEnemy = true;
  317. }
  318. else if (RoomPreinstall.HasEnemy()) //在判断是否会刷出敌人
  319. {
  320. hasEnemy = true;
  321. }
  322. if (!hasEnemy) //没有敌人, 不关门
  323. {
  324. IsSeclusion = false;
  325. //执行第一波生成
  326. RoomPreinstall.StartWave();
  327. return;
  328. }
  329.  
  330. //关门
  331. CloseDoor();
  332. IsSeclusion = true;
  333.  
  334. //执行第一波生成
  335. RoomPreinstall.StartWave();
  336. }
  337.  
  338. /// <summary>
  339. /// 当前房间所有敌人都被清除了
  340. /// </summary>
  341. public void OnClearRoom()
  342. {
  343. if (RoomPreinstall.IsLastWave) //所有 mark 都走完了
  344. {
  345. IsSeclusion = false;
  346. if (RoomPreinstall.HasEnemy())
  347. {
  348. //开门
  349. OpenDoor();
  350. }
  351. //所有标记执行完成
  352. RoomPreinstall.OverWave();
  353. }
  354. else //执行下一波
  355. {
  356. RoomPreinstall.NextWave();
  357. }
  358. }
  359.  
  360. /// <summary>
  361. /// 打开所有门
  362. /// </summary>
  363. public void OpenDoor()
  364. {
  365. if (!_openDoorFlag)
  366. {
  367. _openDoorFlag = true;
  368. AffiliationArea.RestoreRegion();
  369. }
  370. foreach (var doorInfo in Doors)
  371. {
  372. doorInfo.Door.OpenDoor();
  373. //过道迷雾
  374. doorInfo.AisleFogArea.Monitoring = true;
  375. if (doorInfo.AisleFogMask.IsExplored)
  376. {
  377. //doorInfo.ClearFog();
  378. FogMaskHandler.RefreshAisleFog(doorInfo);
  379. }
  380. }
  381. }
  382.  
  383. /// <summary>
  384. /// 关闭所有门
  385. /// </summary>
  386. public void CloseDoor()
  387. {
  388. if (_openDoorFlag)
  389. {
  390. _openDoorFlag = false;
  391. AffiliationArea.ExtendedRegion(new Vector2(GameConfig.TileCellSize * 4, GameConfig.TileCellSize * 4));
  392. }
  393.  
  394. foreach (var doorInfo in Doors)
  395. {
  396. doorInfo.Door.CloseDoor();
  397. //过道迷雾
  398. doorInfo.AisleFogArea.Monitoring = false;
  399. if (doorInfo.AisleFogMask.IsExplored)
  400. {
  401. //doorInfo.DarkFog();
  402. FogMaskHandler.RefreshAisleFog(doorInfo);
  403. }
  404. }
  405. }
  406. }