Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / activity / bullet / explode / Explode.cs
@小李xl 小李xl on 10 Nov 2023 4 KB 更改角色模板继承关系
  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 uint AttackLayer { get; private set; }
  32.  
  33.  
  34. private bool _init = false;
  35. private float _hitRadius;
  36. private int _harm;
  37. private float _repelledRadius;
  38. private float _maxRepelled;
  39. public void Destroy()
  40. {
  41. if (IsDestroyed)
  42. {
  43. return;
  44. }
  45.  
  46. IsDestroyed = true;
  47. QueueFree();
  48. }
  49.  
  50. /// <summary>
  51. /// 初始化爆炸数据
  52. /// </summary>
  53. /// <param name="affiliationArea">爆炸所在区域</param>
  54. /// <param name="attackLayer">攻击的层级</param>
  55. /// <param name="hitRadius">伤害半径</param>
  56. /// <param name="harm">造成的伤害</param>
  57. /// <param name="repelledRadius">击退半径</param>
  58. /// <param name="maxRepelled">最大击退速度</param>
  59. public void Init(AffiliationArea affiliationArea, uint attackLayer, float hitRadius, int harm, float repelledRadius, float maxRepelled)
  60. {
  61. if (!_init)
  62. {
  63. _init = true;
  64. AnimationPlayer = GetNode<AnimationPlayer>("AnimationPlayer");
  65. CollisionShape = GetNode<CollisionShape2D>("CollisionShape2D");
  66. CircleShape = (CircleShape2D)CollisionShape.Shape;
  67. AnimationPlayer.AnimationFinished += OnAnimationFinish;
  68. BodyEntered += OnBodyEntered;
  69. }
  70. AttackLayer = attackLayer;
  71. _hitRadius = hitRadius;
  72. _harm = harm;
  73. _repelledRadius = repelledRadius;
  74. _maxRepelled = maxRepelled;
  75. CollisionMask = attackLayer | PhysicsLayer.Prop | PhysicsLayer.Debris;
  76. CircleShape.Radius = Mathf.Max(hitRadius, maxRepelled);
  77.  
  78. //冲击波
  79. if (affiliationArea != null)
  80. {
  81. ShockWave(affiliationArea);
  82. }
  83. }
  84. /// <summary>
  85. /// 播放爆炸, triggerRole 为触发该爆炸的角色
  86. /// </summary>
  87. public void RunPlay(AdvancedRole triggerRole = null)
  88. {
  89. GameCamera.Main.CreateShake(new Vector2(6, 6), 0.7f, true);
  90. AnimationPlayer.Play(AnimatorNames.Play);
  91. //播放爆炸音效
  92. SoundManager.PlaySoundByConfig("explosion0002", Position, triggerRole);
  93. }
  94.  
  95. //爆炸冲击波
  96. private void ShockWave(AffiliationArea affiliationArea)
  97. {
  98. var position = Position;
  99. var freezeSprites = affiliationArea.RoomInfo.StaticSprite.CollisionCircle(position, _repelledRadius, true);
  100. foreach (var freezeSprite in freezeSprites)
  101. {
  102. var temp = freezeSprite.Position - position;
  103. freezeSprite.ActivityObject.MoveController.AddForce(temp.Normalized() * _maxRepelled * (_repelledRadius - temp.Length()) / _repelledRadius);
  104. }
  105. }
  106.  
  107. public void OnReclaim()
  108. {
  109. GetParent().CallDeferred(Node.MethodName.RemoveChild, this);
  110. }
  111.  
  112. public void OnLeavePool()
  113. {
  114. }
  115.  
  116. private void OnAnimationFinish(StringName name)
  117. {
  118. if (name == AnimatorNames.Play)
  119. {
  120. ObjectPool.Reclaim(this);
  121. }
  122. }
  123.  
  124. private void OnBodyEntered(Node2D node)
  125. {
  126. var o = node.AsActivityObject();
  127. if (o != null)
  128. {
  129. var temp = o.Position - Position;
  130. var len = temp.Length();
  131. var angle = temp.Angle();
  132.  
  133. if (len <= _hitRadius) //在伤害半径内
  134. {
  135. if (o is Role role) //是角色
  136. {
  137. role.CallDeferred(nameof(role.Hurt), _harm, angle);
  138. }
  139. else if (o is Bullet bullet) //是子弹
  140. {
  141. if (bullet is BoomBullet boomBullet) //如果是爆炸子弹, 则直接销毁
  142. {
  143. boomBullet.PlayBoom();
  144. }
  145. bullet.Destroy();
  146. return;
  147. }
  148. }
  149. if (len <= _repelledRadius) //击退半径内
  150. {
  151. var repelled = (_repelledRadius - len) / _repelledRadius * _maxRepelled;
  152. //o.MoveController.SetAllVelocity(Vector2.Zero);
  153. o.MoveController.AddForce(Vector2.FromAngle(angle) * repelled);
  154. }
  155. }
  156. }
  157. }