Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / activity / weapon / knife / Knife.cs
  1.  
  2. using Godot;
  3.  
  4. /// <summary>
  5. /// 近战武器,刀
  6. /// </summary>
  7. [Tool]
  8. public partial class Knife : Weapon
  9. {
  10. /// <summary>
  11. /// 近战攻击范围
  12. /// </summary>
  13. [Export]
  14. public int AttackRange { get; set; } = 41;
  15.  
  16. /// <summary>
  17. /// 开始蓄力时武器抬起角度
  18. /// </summary>
  19. [Export]
  20. public int BeginChargeAngle { get; set; } = 120;
  21. private Area2D _hitArea;
  22. private int _attackIndex = 0;
  23. private CollisionPolygon2D _collisionPolygon;
  24. public override void OnInit()
  25. {
  26. base.OnInit();
  27.  
  28. //没有Master时不能触发开火
  29. NoMasterCanTrigger = false;
  30. _hitArea = GetNode<Area2D>("HitArea");
  31. _collisionPolygon = new CollisionPolygon2D();
  32. var a = Mathf.Abs(-BeginChargeAngle + Attribute.UpliftAngle);
  33. var ca = Utils.ConvertAngle(-a / 2f);
  34. _collisionPolygon.Polygon = Utils.CreateSectorPolygon(ca, AttackRange, a, 6);
  35. _hitArea.AddChild(_collisionPolygon);
  36. _hitArea.Monitoring = false;
  37. _hitArea.Monitorable = false;
  38. _hitArea.BodyEntered += OnBodyEntered;
  39.  
  40. //禁用自动播放动画
  41. IsAutoPlaySpriteFrames = false;
  42. }
  43.  
  44. protected override void Process(float delta)
  45. {
  46. base.Process(delta);
  47. if (IsActive)
  48. {
  49. //让碰撞节点与武器挂载节点位置保持一致, 而不跟着武器走
  50. _hitArea.GlobalPosition = Master.MountPoint.GlobalPosition;
  51. }
  52. }
  53.  
  54. protected override void PhysicsProcess(float delta)
  55. {
  56. base.PhysicsProcess(delta);
  57. //过去两个物理帧后就能关闭碰撞了
  58. if (++_attackIndex >= 2)
  59. {
  60. _hitArea.Monitoring = false;
  61. }
  62. }
  63.  
  64. protected override void OnBeginCharge()
  65. {
  66. //开始蓄力时武器角度
  67. RotationDegrees = -BeginChargeAngle;
  68. }
  69.  
  70. protected override void OnFire()
  71. {
  72. Debug.Log("近战武器攻击! 蓄力时长: " + GetTriggerChargeTime() + ", 扳机按下时长: " + GetTriggerDownTime());
  73. //更新碰撞层级
  74. _hitArea.CollisionMask = GetAttackLayer() | PhysicsLayer.Bullet;
  75. //启用碰撞
  76. _hitArea.Monitoring = true;
  77. _attackIndex = 0;
  78.  
  79. if (IsActive) //被使用
  80. {
  81. //播放挥刀特效
  82. SpecialEffectManager.Play(
  83. Master,
  84. ResourcePath.resource_spriteFrames_weapon_Weapon0004_hit_tres, "default",
  85. Master.MountPoint.Position,
  86. Master.MountPoint.Rotation + Mathf.DegToRad(Attribute.UpliftAngle + 60),
  87. AnimatedSprite.Scale,
  88. new Vector2(17, 4), 1
  89. );
  90. }
  91.  
  92.  
  93. if (Master == Player.Current)
  94. {
  95. var r = Master.MountPoint.RotationDegrees;
  96. //创建屏幕抖动
  97. if (Master.Face == FaceDirection.Right)
  98. {
  99. //GameCamera.Main.DirectionalShake(Vector2.FromAngle(Mathf.DegToRad(r - 90)) * 5);
  100. GameCamera.Main.DirectionalShake(Vector2.FromAngle(Mathf.DegToRad(r - 180)) * Attribute.CameraShake);
  101. }
  102. else
  103. {
  104. //GameCamera.Main.DirectionalShake(Vector2.FromAngle(Mathf.DegToRad(270 - r)) * 5);
  105. GameCamera.Main.DirectionalShake(Vector2.FromAngle(Mathf.DegToRad(-r)) * Attribute.CameraShake);
  106. }
  107. }
  108. }
  109.  
  110. protected override void OnShoot(float fireRotation)
  111. {
  112. }
  113.  
  114. protected override int UseAmmoCount()
  115. {
  116. //这里要做判断, 如果没有碰到敌人, 则不消耗弹药 (耐久)
  117. return 0;
  118. }
  119.  
  120. private void OnBodyEntered(Node2D body)
  121. {
  122. //Debug.Log("碰到物体: " + body.Name);
  123. var activityObject = body.AsActivityObject();
  124. if (activityObject != null)
  125. {
  126. if (activityObject is Role role) //碰到角色
  127. {
  128. var damage = Utils.Random.RandomConfigRange(Attribute.Bullet.HarmRange);
  129. //计算子弹造成的伤害
  130. if (TriggerRole != null)
  131. {
  132. damage = TriggerRole.RoleState.CalcDamage(damage);
  133. }
  134. //击退
  135. var attr = GetUseAttribute(TriggerRole);
  136. var repel = Utils.Random.RandomConfigRange(attr.Bullet.RepelRange);
  137. //计算击退
  138. if (TriggerRole != null)
  139. {
  140. repel = TriggerRole.RoleState.CalcBulletRepel(repel);
  141. }
  142. if (repel != 0)
  143. {
  144. Vector2 position;
  145. if (TriggerRole != null)
  146. {
  147. position = role.GlobalPosition - TriggerRole.MountPoint.GlobalPosition;
  148. }
  149. else
  150. {
  151. position = role.GlobalPosition - GlobalPosition;
  152. }
  153. var v2 = position.Normalized() * repel;
  154. role.AddRepelForce(v2);
  155. }
  156. //造成伤害
  157. role.CallDeferred(nameof(Role.Hurt), TriggerRole, damage, (role.GetCenterPosition() - GlobalPosition).Angle());
  158. }
  159. else if (activityObject is Bullet bullet) //攻击子弹
  160. {
  161. var attackLayer = bullet.AttackLayer;
  162. if (TriggerRole != null && TriggerRole.CollisionWithMask(attackLayer)) //是攻击玩家的子弹
  163. {
  164. //反弹子弹
  165. bullet.OnPlayDisappearEffect();
  166. bullet.MoveController.ScaleAllVelocity(-1);
  167. bullet.Rotation += Mathf.Pi;
  168. bullet.AttackLayer = TriggerRole.AttackLayer;
  169. }
  170. }
  171. }
  172. }
  173. }