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