Newer
Older
DungeonShooting / DungeonShooting_Godot / src / framework / map / room / RoomInfo.cs
  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. /// 静态渲染精灵根节点, 用于放置sprite
  76. /// </summary>
  77. public RoomStaticSprite StaticSprite;
  78. /// <summary>
  79. /// 静态精灵绘制画布
  80. /// </summary>
  81. public ImageCanvas StaticImageCanvas;
  82.  
  83. /// <summary>
  84. /// 房间坐标相对于画布坐标偏移量, 单位: 像素
  85. /// </summary>
  86. public Vector2I RoomOffset;
  87.  
  88. /// <summary>
  89. /// 房间迷雾
  90. /// </summary>
  91. public FogMask RoomFogMask;
  92. /// <summary>
  93. /// 房间算上连接通道所占用的区域
  94. /// </summary>
  95. public Rect2I OuterRange { get; private set; }
  96.  
  97. /// <summary>
  98. /// 是否处于闭关状态, 也就是房间门没有主动打开
  99. /// </summary>
  100. public bool IsSeclusion { get; private set; } = false;
  101. public bool IsDestroyed { get; private set; }
  102. private bool _openDoorFlag = true;
  103. // private bool _beReady = false;
  104. // private bool _waveStart = false;
  105. // private int _currWaveIndex = 0;
  106. // private int _currWaveNumber = 0;
  107. //private List<ActivityMark> _currActivityMarks = new List<ActivityMark>();
  108.  
  109. /// <summary>
  110. /// 重新计算占用的区域
  111. /// </summary>
  112. public void CalcOuterRange()
  113. {
  114. var worldPos = GetWorldPosition();
  115. var pos = new Vector2I(worldPos.X, worldPos.Y);
  116. var minX = pos.X;
  117. var minY = pos.Y;
  118. var maxX = minX + GetWidth();
  119. var maxY = minY + GetHeight();
  120.  
  121. //遍历每一个连接的门, 计算计算canvas覆盖范围
  122. foreach (var doorInfo in Doors)
  123. {
  124. var connectDoor = doorInfo.ConnectDoor;
  125. switch (connectDoor.Direction)
  126. {
  127. case DoorDirection.E:
  128. case DoorDirection.W:
  129. {
  130. var (px1, py1) = connectDoor.GetWorldOriginPosition();
  131. var py2 = py1 + 4 * GameConfig.TileCellSize;
  132. if (px1 < minX)
  133. {
  134. minX = px1;
  135. }
  136. else if (px1 > maxX)
  137. {
  138. maxX = px1;
  139. }
  140.  
  141. if (py1 < minY)
  142. {
  143. minY = py1;
  144. }
  145. else if (py1 > maxY)
  146. {
  147. maxY = py1;
  148. }
  149. if (py2 < minY)
  150. {
  151. minY = py2;
  152. }
  153. else if (py2 > maxY)
  154. {
  155. maxY = py2;
  156. }
  157. }
  158. break;
  159. case DoorDirection.S:
  160. case DoorDirection.N:
  161. {
  162. var (px1, py1) = connectDoor.GetWorldOriginPosition();
  163. var px2 = px1 + 4 * GameConfig.TileCellSize;
  164. if (px1 < minX)
  165. {
  166. minX = px1;
  167. }
  168. else if (px1 > maxX)
  169. {
  170. maxX = px1;
  171. }
  172.  
  173. if (py1 < minY)
  174. {
  175. minY = py1;
  176. }
  177. else if (py1 > maxY)
  178. {
  179. maxY = py1;
  180. }
  181. if (px2 < minX)
  182. {
  183. minX = px2;
  184. }
  185. else if (px2 > maxX)
  186. {
  187. maxX = px2;
  188. }
  189. }
  190. break;
  191. }
  192. }
  193.  
  194. OuterRange = new Rect2I(minX, minY, maxX - minX, maxY - minY);
  195. }
  196. /// <summary>
  197. /// 获取房间的全局坐标, 单位: 像素
  198. /// </summary>
  199. public Vector2I GetWorldPosition()
  200. {
  201. return new Vector2I(
  202. Position.X * GameConfig.TileCellSize,
  203. Position.Y * GameConfig.TileCellSize
  204. );
  205. }
  206.  
  207. /// <summary>
  208. /// 获取房间左上角的 Tile 距离全局坐标原点的偏移, 单位: 像素
  209. /// </summary>
  210. /// <returns></returns>
  211. public Vector2I GetOffsetPosition()
  212. {
  213. return RoomSplit.RoomInfo.Position.AsVector2I() * GameConfig.TileCellSize;
  214. }
  215. /// <summary>
  216. /// 将房间配置中的坐标转为全局坐标, 单位: 像素
  217. /// </summary>
  218. public Vector2 ToGlobalPosition(Vector2 pos)
  219. {
  220. return GetWorldPosition() + pos - GetOffsetPosition();
  221. }
  222. /// <summary>
  223. /// 获取房间横轴结束位置, 单位: 格
  224. /// </summary>
  225. public int GetHorizontalEnd()
  226. {
  227. return Position.X + Size.X;
  228. }
  229.  
  230. /// <summary>
  231. /// 获取房间纵轴结束位置, 单位: 格
  232. /// </summary>
  233. public int GetVerticalEnd()
  234. {
  235. return Position.Y + Size.Y;
  236. }
  237. /// <summary>
  238. /// 获取房间横轴开始位置, 单位: 格
  239. /// </summary>
  240. public int GetHorizontalStart()
  241. {
  242. return Position.X;
  243. }
  244.  
  245. /// <summary>
  246. /// 获取房间纵轴开始位置, 单位: 格
  247. /// </summary>
  248. public int GetVerticalStart()
  249. {
  250. return Position.Y;
  251. }
  252.  
  253. /// <summary>
  254. /// 获取房间宽度, 单位: 像素
  255. /// </summary>
  256. public int GetWidth()
  257. {
  258. return Size.X * GameConfig.TileCellSize;
  259. }
  260. /// <summary>
  261. /// 获取房间高度, 单位: 像素
  262. /// </summary>
  263. public int GetHeight()
  264. {
  265. return Size.Y * GameConfig.TileCellSize;
  266. }
  267. /// <summary>
  268. /// 将世界坐标转为画布下的坐标
  269. /// </summary>
  270. public Vector2 ToImageCanvasPosition(Vector2 pos)
  271. {
  272. return pos - StaticImageCanvas.Position;
  273. }
  274. public void Destroy()
  275. {
  276. if (IsDestroyed)
  277. {
  278. return;
  279. }
  280.  
  281. IsDestroyed = true;
  282. //递归销毁下一个房间
  283. foreach (var nextRoom in Next)
  284. {
  285. nextRoom.Destroy();
  286. }
  287. Next.Clear();
  288. //销毁连接的门
  289. foreach (var roomDoorInfo in Doors)
  290. {
  291. roomDoorInfo.Destroy();
  292. }
  293. //销毁预设
  294. if (RoomPreinstall != null)
  295. {
  296. RoomPreinstall.Destroy();
  297. RoomPreinstall = null;
  298. }
  299. //销毁画布
  300. if (StaticImageCanvas != null)
  301. {
  302. StaticImageCanvas.Destroy();
  303. }
  304. //
  305. if (StaticSprite != null)
  306. {
  307. StaticSprite.Destroy();
  308. }
  309.  
  310. //销毁迷雾
  311. if (RoomFogMask != null)
  312. {
  313. RoomFogMask.Destroy();
  314. }
  315.  
  316. //销毁所属区域对象
  317. if (AffiliationArea != null)
  318. {
  319. AffiliationArea.Destroy();
  320. }
  321. }
  322. /// <summary>
  323. /// 加载地牢完成
  324. /// </summary>
  325. public void OnReady()
  326. {
  327. //提前加载波
  328. RoomPreinstall.OnReady();
  329. }
  330. /// <summary>
  331. /// 玩家第一次进入房间, 房间准备好了, 准备刷敌人, 并且关闭所有<br/>
  332. /// 当清完每一波刷新的敌人后即可开门
  333. /// </summary>
  334. public void OnFirstEnter()
  335. {
  336. if (RoomPreinstall.IsRunWave)
  337. {
  338. return;
  339. }
  340. //房间内有敌人, 或者会刷新敌人才会关门
  341. var hasEnemy = false;
  342. if (AffiliationArea.ExistEnterItem(activityObject => activityObject.CollisionWithMask(PhysicsLayer.Enemy))) //先判断房间里面是否有敌人
  343. {
  344. hasEnemy = true;
  345. }
  346. else if (RoomPreinstall.HasEnemy()) //在判断是否会刷出敌人
  347. {
  348. hasEnemy = true;
  349. }
  350. if (!hasEnemy) //没有敌人, 不关门
  351. {
  352. IsSeclusion = false;
  353. //执行第一波生成
  354. RoomPreinstall.StartWave();
  355. return;
  356. }
  357.  
  358. //关门
  359. CloseDoor();
  360. IsSeclusion = true;
  361.  
  362. //执行第一波生成
  363. RoomPreinstall.StartWave();
  364. }
  365.  
  366. /// <summary>
  367. /// 当前房间所有敌人都被清除了
  368. /// </summary>
  369. public void OnClearRoom()
  370. {
  371. if (RoomPreinstall.IsLastWave) //所有 mark 都走完了
  372. {
  373. IsSeclusion = false;
  374. if (RoomPreinstall.HasEnemy())
  375. {
  376. //开门
  377. OpenDoor();
  378. }
  379. //所有标记执行完成
  380. RoomPreinstall.OverWave();
  381. }
  382. else //执行下一波
  383. {
  384. RoomPreinstall.NextWave();
  385. }
  386. }
  387.  
  388. /// <summary>
  389. /// 打开所有门
  390. /// </summary>
  391. public void OpenDoor()
  392. {
  393. if (!_openDoorFlag)
  394. {
  395. _openDoorFlag = true;
  396. AffiliationArea.RestoreRegion();
  397. }
  398. foreach (var doorInfo in Doors)
  399. {
  400. doorInfo.Door.OpenDoor();
  401. //过道迷雾
  402. doorInfo.AisleFogArea.Monitoring = true;
  403. if (doorInfo.AisleFogMask.IsExplored)
  404. {
  405. //doorInfo.ClearFog();
  406. FogMaskHandler.RefreshAisleFog(doorInfo);
  407. }
  408. }
  409. }
  410.  
  411. /// <summary>
  412. /// 关闭所有门
  413. /// </summary>
  414. public void CloseDoor()
  415. {
  416. if (_openDoorFlag)
  417. {
  418. _openDoorFlag = false;
  419. AffiliationArea.ExtendedRegion(new Vector2(GameConfig.TileCellSize * 4, GameConfig.TileCellSize * 4));
  420. }
  421.  
  422. foreach (var doorInfo in Doors)
  423. {
  424. doorInfo.Door.CloseDoor();
  425. //过道迷雾
  426. doorInfo.AisleFogArea.Monitoring = false;
  427. if (doorInfo.AisleFogMask.IsExplored)
  428. {
  429. //doorInfo.DarkFog();
  430. FogMaskHandler.RefreshAisleFog(doorInfo);
  431. }
  432. }
  433. }
  434. }