Newer
Older
DungeonShooting / DungeonShooting_Godot / src / framework / map / RoomInfo.cs
@小李xl 小李xl on 5 Apr 2023 6 KB 完成生成在标记处
  1.  
  2. using System.Collections.Generic;
  3. using Godot;
  4.  
  5. /// <summary>
  6. /// 房间的数据描述
  7. /// </summary>
  8. public class RoomInfo : IDestroy
  9. {
  10. public RoomInfo(int id, DungeonRoomSplit roomSplit)
  11. {
  12. Id = id;
  13. RoomSplit = roomSplit;
  14. }
  15.  
  16. /// <summary>
  17. /// 房间 id
  18. /// </summary>
  19. public int Id;
  20.  
  21. /// <summary>
  22. /// 生成该房间使用的配置数据
  23. /// </summary>
  24. public DungeonRoomSplit RoomSplit;
  25. /// <summary>
  26. /// 房间大小, 单位: 格
  27. /// </summary>
  28. public Vector2I Size;
  29.  
  30. /// <summary>
  31. /// 房间位置, 单位: 格
  32. /// </summary>
  33. public Vector2I Position;
  34. /// <summary>
  35. /// 门
  36. /// </summary>
  37. public List<RoomDoorInfo> Doors = new List<RoomDoorInfo>();
  38.  
  39. /// <summary>
  40. /// 下一个房间
  41. /// </summary>
  42. public List<RoomInfo> Next = new List<RoomInfo>();
  43. /// <summary>
  44. /// 上一个房间
  45. /// </summary>
  46. public RoomInfo Prev;
  47.  
  48. /// <summary>
  49. /// 物体生成标记
  50. /// </summary>
  51. public List<ActivityMark> ActivityMarks = new List<ActivityMark>();
  52.  
  53. /// <summary>
  54. /// 当前房间归属区域
  55. /// </summary>
  56. public AffiliationArea Affiliation;
  57.  
  58. /// <summary>
  59. /// 是否处于闭关状态, 也就是房间门没有主动打开
  60. /// </summary>
  61. public bool IsSeclusion { get; private set; } = false;
  62. public bool IsDestroyed { get; private set; }
  63. private bool _beReady = false;
  64. private bool _waveStart = false;
  65. private int _currWaveIndex = 0;
  66. private int _currWaveNumber = 0;
  67. private List<ActivityMark> _currActivityMarks = new List<ActivityMark>();
  68.  
  69. /// <summary>
  70. /// 获取房间的全局坐标, 单位: 像素
  71. /// </summary>
  72. public Vector2 GetWorldPosition()
  73. {
  74. return new Vector2(
  75. Position.X * GameConfig.TileCellSize,
  76. Position.Y * GameConfig.TileCellSize
  77. );
  78. }
  79.  
  80. /// <summary>
  81. /// 获取房间左上角的 Tile 距离全局坐标原点的偏移, 单位: 像素
  82. /// </summary>
  83. /// <returns></returns>
  84. public Vector2 GetOffsetPosition()
  85. {
  86. return RoomSplit.RoomInfo.Position.AsVector2() * GameConfig.TileCellSize;
  87. }
  88. /// <summary>
  89. /// 获取房间横轴结束位置, 单位: 格
  90. /// </summary>
  91. public int GetHorizontalEnd()
  92. {
  93. return Position.X + Size.X;
  94. }
  95.  
  96. /// <summary>
  97. /// 获取房间纵轴结束位置, 单位: 格
  98. /// </summary>
  99. public int GetVerticalEnd()
  100. {
  101. return Position.Y + Size.Y;
  102. }
  103. /// <summary>
  104. /// 获取房间横轴开始位置, 单位: 格
  105. /// </summary>
  106. public int GetHorizontalStart()
  107. {
  108. return Position.X;
  109. }
  110.  
  111. /// <summary>
  112. /// 获取房间纵轴开始位置, 单位: 格
  113. /// </summary>
  114. public int GetVerticalStart()
  115. {
  116. return Position.Y;
  117. }
  118. public void Destroy()
  119. {
  120. if (IsDestroyed)
  121. {
  122. return;
  123. }
  124.  
  125. IsDestroyed = true;
  126. foreach (var nextRoom in Next)
  127. {
  128. nextRoom.Destroy();
  129. }
  130. Next.Clear();
  131. foreach (var activityMark in ActivityMarks)
  132. {
  133. activityMark.QueueFree();
  134. }
  135. ActivityMarks.Clear();
  136. }
  137. /// <summary>
  138. /// 房间准备好了, 准备刷敌人, 并且关闭所有门,
  139. /// 当清完每一波刷新的敌人后即可开门
  140. /// </summary>
  141. public void BeReady()
  142. {
  143. //没有标记, 啥都不要做
  144. if (ActivityMarks.Count == 0)
  145. {
  146. _beReady = true;
  147. IsSeclusion = false;
  148. return;
  149. }
  150. IsSeclusion = true;
  151. _waveStart = false;
  152.  
  153. if (!_beReady)
  154. {
  155. _beReady = true;
  156. //按照 WaveNumber 排序
  157. ActivityMarks.Sort((x, y) =>
  158. {
  159. return x.WaveNumber - y.WaveNumber;
  160. });
  161. }
  162.  
  163. //不是初始房间才能关门
  164. if (RoomSplit.RoomInfo.RoomType != DungeonRoomType.Inlet)
  165. {
  166. //关门
  167. foreach (var doorInfo in Doors)
  168. {
  169. doorInfo.Door.CloseDoor();
  170. }
  171. }
  172. //执行第一波生成
  173. NextWave();
  174. }
  175.  
  176. /// <summary>
  177. /// 当前房间所有敌人都被清除了
  178. /// </summary>
  179. public void OnClearRoom()
  180. {
  181. if (_currWaveIndex >= ActivityMarks.Count) //所有 mark 全部走完了
  182. {
  183. IsSeclusion = false;
  184. _currActivityMarks.Clear();
  185. //开门
  186. if (RoomSplit.RoomInfo.RoomType != DungeonRoomType.Inlet)
  187. {
  188. foreach (var doorInfo in Doors)
  189. {
  190. doorInfo.Door.OpenDoor();
  191. }
  192. }
  193. }
  194. else //执行下一波
  195. {
  196. NextWave();
  197. }
  198. }
  199.  
  200. /// <summary>
  201. /// 返回当前这一波所有的标记的 Doing 函数是否执行完成
  202. /// </summary>
  203. public bool IsCurrWaveOver()
  204. {
  205. for (var i = 0; i < _currActivityMarks.Count; i++)
  206. {
  207. if (!_currActivityMarks[i].IsOver())
  208. {
  209. return false;
  210. }
  211. }
  212.  
  213. return true;
  214. }
  215.  
  216. /// <summary>
  217. /// 执行下一轮标记
  218. /// </summary>
  219. private void NextWave()
  220. {
  221. if (!_waveStart)
  222. {
  223. _waveStart = true;
  224. _currWaveIndex = 0;
  225. _currWaveNumber = ActivityMarks[0].WaveNumber;
  226. }
  227. GD.Print("执行下一波, 当前: " + _currWaveNumber);
  228. _currActivityMarks.Clear();
  229. //根据标记生成对象
  230. for (; _currWaveIndex < ActivityMarks.Count; _currWaveIndex++)
  231. {
  232. var mark = ActivityMarks[_currWaveIndex];
  233. if (mark.WaveNumber != _currWaveNumber) //当前这波已经执行完成了
  234. {
  235. _currWaveNumber = mark.WaveNumber;
  236. break;
  237. }
  238. else //生成操作
  239. {
  240. mark.BeReady(this);
  241. _currActivityMarks.Add(mark);
  242. }
  243. }
  244. }
  245. }