Newer
Older
DungeonShooting / DungeonShooting_Godot / src / framework / map / AffiliationArea.cs
  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.Props | PhysicsLayer.Player | PhysicsLayer.Enemy;
  52.  
  53. BodyEntered += OnBodyEntered;
  54. }
  55.  
  56. /// <summary>
  57. /// 将物体添加到当前所属区域中
  58. /// </summary>
  59. public void InsertItem(ActivityObject activityObject)
  60. {
  61. if (activityObject.Affiliation == this)
  62. {
  63. return;
  64. }
  65.  
  66. if (activityObject.Affiliation != null)
  67. {
  68. _includeItems.Remove(activityObject);
  69. }
  70. activityObject.Affiliation = 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.Affiliation == null)
  86. {
  87. return;
  88. }
  89. activityObject.Affiliation = 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. private void OnBodyEntered(Node2D body)
  118. {
  119. if (body is ActivityObject activityObject)
  120. {
  121. //注意需要延时调用
  122. CallDeferred(nameof(InsertItem), activityObject);
  123. }
  124. }
  125.  
  126. //玩家进入房间
  127. private void OnPlayerEnterRoom()
  128. {
  129. if (IsFirstEnterFlag)
  130. {
  131. EventManager.EmitEvent(EventEnum.OnPlayerFirstEnterRoom, RoomInfo);
  132. IsFirstEnterFlag = false;
  133. }
  134. EventManager.EmitEvent(EventEnum.OnPlayerEnterRoom, RoomInfo);
  135. }
  136. }