Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / item / weapon / knife / Knife.cs
  1.  
  2. using Godot;
  3.  
  4. [RegisterWeapon("1004", typeof(KnifeAttribute))]
  5. public class Knife : Weapon
  6. {
  7. private class KnifeAttribute : WeaponAttribute
  8. {
  9. public KnifeAttribute()
  10. {
  11. Sprite = ResourcePath.resource_sprite_gun_knife1_png;
  12. WeaponPrefab = ResourcePath.prefab_weapon_Knife_tscn;
  13. //攻速设置
  14. StartFiringSpeed = 180;
  15. FinalFiringSpeed = StartFiringSpeed;
  16. //关闭连发
  17. ContinuousShoot = false;
  18. //设置成松发开火
  19. LooseShoot = true;
  20. //弹药量, 可以理解为耐久度
  21. AmmoCapacity = 180;
  22. MaxAmmoCapacity = AmmoCapacity;
  23. //握把位置
  24. HoldPosition = new Vector2(10, 0);
  25. MaxDistance = MinDistance = 35;
  26. //后坐力改为向前, 模拟手伸长的效果
  27. MaxBacklash = -8;
  28. MinBacklash = -8;
  29. BacklashRegressionSpeed = 24;
  30. UpliftAngle = -95;
  31. }
  32. }
  33.  
  34. private Area2D _hitArea;
  35.  
  36. private int _attackIndex = 0;
  37. public Knife(string typeId, WeaponAttribute attribute) : base(typeId, attribute)
  38. {
  39. _hitArea = GetNode<Area2D>("HitArea");
  40. _hitArea.Monitoring = false;
  41. _hitArea.Monitorable = false;
  42.  
  43. _hitArea.Connect("body_entered", this, nameof(OnBodyEntered));
  44. }
  45.  
  46. protected override void Process(float delta)
  47. {
  48. base.Process(delta);
  49. if (IsActive)
  50. {
  51. //让碰撞节点与武器挂载节点位置保持一致, 而不跟着武器走
  52. _hitArea.GlobalPosition = Master.MountPoint.GlobalPosition;
  53. }
  54. }
  55.  
  56. protected override void PhysicsProcess(float delta)
  57. {
  58. base.PhysicsProcess(delta);
  59. //过去两个物理帧后就能关闭碰撞了
  60. if (++_attackIndex >= 2)
  61. {
  62. _hitArea.Monitoring = false;
  63. }
  64. }
  65.  
  66. protected override void OnStartCharge()
  67. {
  68. //开始蓄力时武器角度上抬120度
  69. RotationDegrees = -120;
  70. }
  71.  
  72. protected override void OnFire()
  73. {
  74. GD.Print("近战武器攻击! 蓄力时长: " + GetTriggerChargeTime() + ", 扳机按下时长: " + GetTriggerDownTime());
  75. //更新碰撞层级
  76. _hitArea.CollisionMask = GetAttackLayer();
  77. //启用碰撞
  78. _hitArea.Monitoring = true;
  79. _attackIndex = 0;
  80.  
  81. if (IsActive) //被使用
  82. {
  83. //播放挥刀特效
  84. SpecialEffectManager.Play(
  85. ResourcePath.resource_effects_KnifeHit1_tres, "default",
  86. Master.MountPoint.GlobalPosition, GlobalRotation + Mathf.Pi * 0.5f, new Vector2((int)Master.Face, 1) * AnimatedSprite.Scale,
  87. new Vector2(17, 4), 1
  88. );
  89. }
  90.  
  91.  
  92. if (Master == GameApplication.Instance.Room.Player)
  93. {
  94. //创建抖动
  95. //GameCamera.Main.ProcessDirectionalShake(Vector2.Right.Rotated(GlobalRotation - Mathf.Pi * 0.5f) * 1.5f);
  96. }
  97. }
  98.  
  99. protected override void OnShoot(float fireRotation)
  100. {
  101. }
  102.  
  103. protected override int UseAmmoCount()
  104. {
  105. //这里要做判断, 如果没有碰到敌人, 则不消耗弹药 (耐久)
  106. return 0;
  107. }
  108.  
  109. private void OnBodyEntered(Node2D body)
  110. {
  111. GD.Print("碰到物体: " + body.Name);
  112. var activityObject = body.AsActivityObject();
  113. if (activityObject != null)
  114. {
  115. if (activityObject is Role role)
  116. {
  117. role.CallDeferred(nameof(Role.Hurt), 10, (role.GetCenterPosition() - GlobalPosition).Angle());
  118. }
  119. }
  120. }
  121. }