Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / activity / bullet / explode / Explode.cs
  1.  
  2. using Config;
  3. using Godot;
  4.  
  5. /// <summary>
  6. /// 爆炸
  7. /// </summary>
  8. public partial class Explode : Area2D, IPoolItem
  9. {
  10. public bool IsRecycled { get; set; }
  11. public string Logotype { get; set; }
  12.  
  13. public bool IsDestroyed { get; private set; }
  14.  
  15. /// <summary>
  16. /// 动画播放器
  17. /// </summary>
  18. public AnimationPlayer AnimationPlayer { get; private set; }
  19. /// <summary>
  20. /// 碰撞器
  21. /// </summary>
  22. public CollisionShape2D CollisionShape { get; private set; }
  23. /// <summary>
  24. /// 碰撞器形状对象
  25. /// </summary>
  26. public CircleShape2D CircleShape { get; private set; }
  27.  
  28. /// <summary>
  29. /// 产生爆炸的子弹数据
  30. /// </summary>
  31. public BulletData BulletData { get; private set; }
  32.  
  33. private bool _init = false;
  34. private float _hitRadius;
  35. private int _harm;
  36. private float _repelledRadius;
  37. private float _maxRepelled;
  38.  
  39. public override void _Ready()
  40. {
  41. CollisionMask = Role.AttackLayer;
  42. }
  43.  
  44. public void Destroy()
  45. {
  46. if (IsDestroyed)
  47. {
  48. return;
  49. }
  50.  
  51. IsDestroyed = true;
  52. QueueFree();
  53. }
  54.  
  55. /// <summary>
  56. /// 初始化爆炸数据
  57. /// </summary>
  58. /// <param name="bulletData">产生爆炸的子弹数据</param>
  59. /// <param name="hitRadius">伤害半径</param>
  60. /// <param name="harm">造成的伤害</param>
  61. /// <param name="repelledRadius">击退半径</param>
  62. /// <param name="maxRepelled">最大击退速度</param>
  63. public void Init(BulletData bulletData, float hitRadius, int harm, float repelledRadius, float maxRepelled)
  64. {
  65. if (!_init)
  66. {
  67. _init = true;
  68. AnimationPlayer = GetNode<AnimationPlayer>("AnimationPlayer");
  69. CollisionShape = GetNode<CollisionShape2D>("CollisionShape2D");
  70. CircleShape = (CircleShape2D)CollisionShape.Shape;
  71. AnimationPlayer.AnimationFinished += OnAnimationFinish;
  72. AreaEntered += OnArea2dEntered;
  73. BodyEntered += OnBodyEntered;
  74. }
  75.  
  76. BulletData = bulletData;
  77. _hitRadius = hitRadius;
  78. _harm = harm;
  79. _repelledRadius = repelledRadius;
  80. _maxRepelled = maxRepelled;
  81. CircleShape.Radius = Mathf.Max(hitRadius, maxRepelled);
  82.  
  83. //冲击波
  84. var affiliationArea = bulletData.TriggerRole?.AffiliationArea;
  85. if (affiliationArea != null)
  86. {
  87. ShockWave(affiliationArea);
  88. }
  89. }
  90. /// <summary>
  91. /// 播放爆炸, triggerRole 为触发该爆炸的角色
  92. /// </summary>
  93. public void RunPlay(Role triggerRole = null)
  94. {
  95. GameCamera.Main.CreateShake(new Vector2(6, 6), 0.7f, true);
  96. AnimationPlayer.Play(AnimatorNames.Play);
  97. //播放爆炸音效
  98. SoundManager.PlaySoundByConfig("explosion0002", Position, triggerRole);
  99. }
  100.  
  101. //爆炸冲击波
  102. private void ShockWave(AffiliationArea affiliationArea)
  103. {
  104. var position = Position;
  105. var freezeSprites = affiliationArea.RoomInfo.StaticSprite.CollisionCircle(position, _repelledRadius, true);
  106. foreach (var freezeSprite in freezeSprites)
  107. {
  108. var temp = freezeSprite.Position - position;
  109. freezeSprite.ActivityObject.MoveController.AddForce(temp.Normalized() * _maxRepelled * (_repelledRadius - temp.Length()) / _repelledRadius);
  110. }
  111. }
  112.  
  113. public void OnReclaim()
  114. {
  115. GetParent().CallDeferred(Node.MethodName.RemoveChild, this);
  116. }
  117.  
  118. public void OnLeavePool()
  119. {
  120. }
  121.  
  122. private void OnAnimationFinish(StringName name)
  123. {
  124. if (name == AnimatorNames.Play)
  125. {
  126. ObjectPool.Reclaim(this);
  127. }
  128. }
  129.  
  130. private void OnBodyEntered(Node2D node)
  131. {
  132. if (node is IHurt hurt)
  133. {
  134. HandlerCollision(hurt);
  135. }
  136. else if (node is Bullet bullet) //是子弹
  137. {
  138. if (bullet is BoomBullet boomBullet) //如果是爆炸子弹, 则直接销毁
  139. {
  140. boomBullet.PlayBoom();
  141. }
  142. bullet.Destroy();
  143. }
  144. }
  145. private void OnArea2dEntered(Area2D other)
  146. {
  147. if (other is IHurt hurt)
  148. {
  149. HandlerCollision(hurt);
  150. }
  151. }
  152.  
  153. private void HandlerCollision(IHurt hurt)
  154. {
  155. var temp = hurt.GetPosition() - Position;
  156. var len = temp.Length();
  157. var angle = temp.Angle();
  158.  
  159. var target = BulletData.TriggerRole.IsDestroyed ? null : BulletData.TriggerRole;
  160. if (hurt.CanHurt(target))
  161. {
  162. if (len <= _hitRadius) //在伤害半径内
  163. {
  164. hurt.Hurt(target, _harm, angle);
  165. }
  166. if (len <= _repelledRadius) //击退半径内
  167. {
  168. var o = hurt.GetActivityObject();
  169. if (o != null)
  170. {
  171. var repelled = (_repelledRadius - len) / _repelledRadius * _maxRepelled;
  172. o.AddRepelForce(Vector2.FromAngle(angle) * repelled);
  173. }
  174. }
  175. }
  176. }
  177. }