Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / activity / role / enemy / normalState / AiFollowUpState.cs
  1.  
  2. using Godot;
  3.  
  4. namespace NnormalState;
  5.  
  6. /// <summary>
  7. /// 目标在视野内, 跟进目标, 如果距离在子弹有效射程内, 则开火
  8. /// </summary>
  9. public class AiFollowUpState : StateBase<Enemy, AiStateEnum>
  10. {
  11. //导航目标点刷新计时器
  12. private float _navigationUpdateTimer = 0;
  13. private float _navigationInterval = 0.3f;
  14.  
  15. public AiFollowUpState() : base(AiStateEnum.AiFollowUp)
  16. {
  17. }
  18.  
  19. public override void Enter(AiStateEnum prev, params object[] args)
  20. {
  21. _navigationUpdateTimer = 0;
  22. Master.TargetInView = true;
  23. }
  24.  
  25. public override void Process(float delta)
  26. {
  27. var playerPos = Player.Current.GetCenterPosition();
  28.  
  29. //更新玩家位置
  30. if (_navigationUpdateTimer <= 0)
  31. {
  32. //每隔一段时间秒更改目标位置
  33. _navigationUpdateTimer = _navigationInterval;
  34. Master.NavigationAgent2D.TargetPosition = playerPos;
  35. }
  36. else
  37. {
  38. _navigationUpdateTimer -= delta;
  39. }
  40.  
  41. var masterPosition = Master.GlobalPosition;
  42.  
  43. //是否在攻击范围内
  44. var inAttackRange = masterPosition.DistanceSquaredTo(playerPos) <= Mathf.Pow(Master.GetAttackRange(0.7f), 2);
  45.  
  46. //枪口指向玩家
  47. Master.LookTargetPosition(playerPos);
  48. if (!Master.NavigationAgent2D.IsNavigationFinished())
  49. {
  50. if (Master.AttackState != AiAttackState.LockingTime && Master.AttackState != AiAttackState.Attack)
  51. {
  52. //计算移动
  53. var nextPos = Master.NavigationAgent2D.GetNextPathPosition();
  54. Master.AnimatedSprite.Play(AnimatorNames.Run);
  55. Master.BasisVelocity = (nextPos - masterPosition - Master.NavigationPoint.Position).Normalized() *
  56. Master.RoleState.MoveSpeed;
  57. }
  58. else
  59. {
  60. Master.AnimatedSprite.Play(AnimatorNames.Idle);
  61. Master.BasisVelocity = Vector2.Zero;
  62. }
  63. }
  64. else
  65. {
  66. Master.BasisVelocity = Vector2.Zero;
  67. }
  68.  
  69. //检测玩家是否在视野内
  70. if (Master.IsInTailAfterViewRange(playerPos))
  71. {
  72. Master.TargetInView = !Master.TestViewRayCast(playerPos);
  73. //关闭射线检测
  74. Master.TestViewRayCastOver();
  75. }
  76. else
  77. {
  78. Master.TargetInView = false;
  79. }
  80.  
  81. //在视野中, 或者锁敌状态下, 或者攻击状态下, 继续保持原本逻辑
  82. if (Master.TargetInView || Master.AttackState == AiAttackState.LockingTime || Master.AttackState == AiAttackState.Attack)
  83. {
  84. if (inAttackRange) //在攻击范围内
  85. {
  86. //发起攻击
  87. //Master.AnimatedSprite.Play(AnimatorNames.Attack);
  88. Master.Attack();
  89. //距离够近, 可以切换到环绕模式
  90. // if (Master.GlobalPosition.DistanceSquaredTo(playerPos) <= Mathf.Pow(Utils.GetConfigRangeStart(weapon.Attribute.Bullet.DistanceRange), 2) * 0.7f)
  91. // {
  92. // ChangeState(AiStateEnum.AiSurround);
  93. // }
  94. }
  95. }
  96. else //不在视野中
  97. {
  98. ChangeState(AiStateEnum.AiTailAfter);
  99. }
  100. }
  101.  
  102. public override void DebugDraw()
  103. {
  104. var playerPos = Player.Current.GetCenterPosition();
  105. Master.DrawLine(new Vector2(0, -8), Master.ToLocal(playerPos), Colors.Red);
  106. }
  107. }