Newer
Older
DungeonShooting / DungeonShooting_Godot / src / framework / map / AffiliationArea.cs
@小李xl 小李xl on 26 Jun 2023 4 KB 移速道具
  1.  
  2. using System;
  3. using System.Collections.Generic;
  4. using Godot;
  5.  
  6. /// <summary>
  7. /// 归属区域
  8. /// </summary>
  9. public partial class AffiliationArea : Area2D
  10. {
  11. /// <summary>
  12. /// 当前实例所属房间
  13. /// </summary>
  14. public RoomInfo RoomInfo;
  15. /// <summary>
  16. /// 当前归属区域包含的所有物体对象
  17. /// </summary>
  18. private readonly HashSet<ActivityObject> _includeItems = new HashSet<ActivityObject>();
  19. /// <summary>
  20. /// 玩家是否是第一次进入
  21. /// </summary>
  22. public bool IsFirstEnterFlag { get; private set; } = true;
  23. private bool _init = false;
  24. /// <summary>
  25. /// 根据矩形区域初始化归属区域
  26. /// </summary>
  27. public void Init(RoomInfo roomInfo, Rect2 rect2)
  28. {
  29. if (_init)
  30. {
  31. return;
  32. }
  33.  
  34. _init = true;
  35.  
  36. RoomInfo = roomInfo;
  37. var collisionShape = new CollisionShape2D();
  38. collisionShape.GlobalPosition = rect2.Position + rect2.Size / 2;
  39. var shape = new RectangleShape2D();
  40. shape.Size = rect2.Size;
  41. collisionShape.Shape = shape;
  42. AddChild(collisionShape);
  43. _Init();
  44. }
  45.  
  46. private void _Init()
  47. {
  48. Monitoring = true;
  49. Monitorable = false;
  50. CollisionLayer = PhysicsLayer.None;
  51. CollisionMask = PhysicsLayer.Prop | PhysicsLayer.Player | PhysicsLayer.Enemy | PhysicsLayer.Shell | PhysicsLayer.Throwing;
  52.  
  53. BodyEntered += OnBodyEntered;
  54. }
  55.  
  56. /// <summary>
  57. /// 将物体添加到当前所属区域中
  58. /// </summary>
  59. public void InsertItem(ActivityObject activityObject)
  60. {
  61. if (activityObject.AffiliationArea == this)
  62. {
  63. return;
  64. }
  65.  
  66. if (activityObject.AffiliationArea != null)
  67. {
  68. _includeItems.Remove(activityObject);
  69. }
  70. activityObject.AffiliationArea = this;
  71. _includeItems.Add(activityObject);
  72.  
  73. //如果是玩家
  74. if (activityObject == Player.Current)
  75. {
  76. OnPlayerEnterRoom();
  77. }
  78. }
  79.  
  80. /// <summary>
  81. /// 将物体从当前所属区域移除
  82. /// </summary>
  83. public void RemoveItem(ActivityObject activityObject)
  84. {
  85. if (activityObject.AffiliationArea == null)
  86. {
  87. return;
  88. }
  89. activityObject.AffiliationArea = null;
  90. _includeItems.Remove(activityObject);
  91. }
  92.  
  93. /// <summary>
  94. /// 获取该区域中物体的总数
  95. /// </summary>
  96. public int GetIncludeItemsCount()
  97. {
  98. return _includeItems.Count;
  99. }
  100.  
  101. /// <summary>
  102. /// 统计符合条件的数量
  103. /// </summary>
  104. /// <param name="handler">操作函数, 返回是否满足要求</param>
  105. public int FindIncludeItemsCount(Func<ActivityObject, bool> handler)
  106. {
  107. var count = 0;
  108. foreach (var activityObject in _includeItems)
  109. {
  110. if (handler(activityObject))
  111. {
  112. count++;
  113. }
  114. }
  115. return count;
  116. }
  117.  
  118. /// <summary>
  119. /// 查询所有符合条件的对象并返回
  120. /// </summary>
  121. /// <param name="handler">操作函数, 返回是否满足要求</param>
  122. public ActivityObject[] FindIncludeItems(Func<ActivityObject, bool> handler)
  123. {
  124. var list = new List<ActivityObject>();
  125. foreach (var activityObject in _includeItems)
  126. {
  127. if (handler(activityObject))
  128. {
  129. list.Add(activityObject);
  130. }
  131. }
  132. return list.ToArray();
  133. }
  134.  
  135. /// <summary>
  136. /// 检查是否有符合条件的对象
  137. /// </summary>
  138. /// <param name="handler">操作函数, 返回是否满足要求</param>
  139. public bool ExistIncludeItem(Func<ActivityObject, bool> handler)
  140. {
  141. foreach (var activityObject in _includeItems)
  142. {
  143. if (handler(activityObject))
  144. {
  145. return true;
  146. }
  147. }
  148.  
  149. return false;
  150. }
  151. private void OnBodyEntered(Node2D body)
  152. {
  153. if (body is ActivityObject activityObject)
  154. {
  155. //注意需要延时调用
  156. CallDeferred(nameof(InsertItem), activityObject);
  157. }
  158. }
  159.  
  160. //玩家进入房间
  161. private void OnPlayerEnterRoom()
  162. {
  163. if (IsFirstEnterFlag)
  164. {
  165. EventManager.EmitEvent(EventEnum.OnPlayerFirstEnterRoom, RoomInfo);
  166. IsFirstEnterFlag = false;
  167. }
  168. EventManager.EmitEvent(EventEnum.OnPlayerEnterRoom, RoomInfo);
  169. }
  170. }