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. activityObject.Affiliation.RemoveItem(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. activityObject.Affiliation = null;
  86. _includeItems.Remove(activityObject);
  87. }
  88.  
  89. /// <summary>
  90. /// 获取该区域中物体的总数
  91. /// </summary>
  92. public int GetIncludeItemsCount()
  93. {
  94. return _includeItems.Count;
  95. }
  96.  
  97. /// <summary>
  98. /// 统计符合条件的数量
  99. /// </summary>
  100. /// <param name="handler">操作函数, 返回是否满足要求</param>
  101. public int FindIncludeItemsCount(Func<ActivityObject, bool> handler)
  102. {
  103. var count = 0;
  104. foreach (var activityObject in _includeItems)
  105. {
  106. if (handler(activityObject))
  107. {
  108. count++;
  109. }
  110. }
  111. return count;
  112. }
  113. private void OnBodyEntered(Node2D body)
  114. {
  115. if (body is ActivityObject activityObject)
  116. {
  117. //注意需要延时调用
  118. CallDeferred(nameof(InsertItem), activityObject);
  119. }
  120. }
  121.  
  122. //玩家进入房间
  123. private void OnPlayerEnterRoom()
  124. {
  125. if (IsFirstEnterFlag)
  126. {
  127. EventManager.EmitEvent(EventEnum.OnPlayerFirstEnterRoom, RoomInfo);
  128. IsFirstEnterFlag = false;
  129. }
  130. EventManager.EmitEvent(EventEnum.OnPlayerEnterRoom, RoomInfo);
  131. }
  132. }