Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / activity / role / ai / state / AiLeaveForState.cs
  1.  
  2. using System;
  3. using Godot;
  4.  
  5. namespace AiState;
  6.  
  7. /// <summary>
  8. /// 收到其他敌人通知, 前往发现目标的位置
  9. /// </summary>
  10. public class AiLeaveForState : StateBase<AiRole, AIStateEnum>
  11. {
  12. //导航目标点刷新计时器
  13. private float _navigationUpdateTimer = 0;
  14. private float _navigationInterval = 0.3f;
  15. //目标
  16. private ActivityObject _target;
  17. //目标点
  18. private Vector2 _targetPosition;
  19.  
  20. private float _idleTimer = 0;
  21. private bool _playAnimFlag = false;
  22.  
  23. public AiLeaveForState() : base(AIStateEnum.AiLeaveFor)
  24. {
  25. }
  26.  
  27. public override void Enter(AIStateEnum prev, params object[] args)
  28. {
  29. if (args.Length == 0)
  30. {
  31. throw new Exception("进入 AINormalStateEnum.AiLeaveFor 状态必须带上目标对象");
  32. }
  33. _target = (ActivityObject)args[0];
  34. //先检查弹药是否打光
  35. if (Master.IsAllWeaponTotalAmmoEmpty())
  36. {
  37. //再寻找是否有可用的武器
  38. var targetWeapon = Master.FindTargetWeapon();
  39. if (targetWeapon != null)
  40. {
  41. ChangeState(AIStateEnum.AiFindAmmo, targetWeapon, _target);
  42. return;
  43. }
  44. }
  45.  
  46. _idleTimer = 1;
  47. _targetPosition = _target.GetCenterPosition();
  48. Master.LookTargetPosition(_targetPosition);
  49. _playAnimFlag = prev != AIStateEnum.AiFindAmmo;
  50. if (_playAnimFlag)
  51. {
  52. if (Master.AnimationPlayer.HasAnimation(AnimatorNames.Query))
  53. {
  54. Master.AnimationPlayer.Play(AnimatorNames.Query);
  55. }
  56. }
  57. //看向目标位置
  58. Master.LookTargetPosition(_target.GetCenterPosition());
  59. }
  60.  
  61. public override void Exit(AIStateEnum next)
  62. {
  63. Master.AnimationPlayer.Play(AnimatorNames.Reset);
  64. }
  65.  
  66. public override void Process(float delta)
  67. {
  68. if (_playAnimFlag && _idleTimer > 0)
  69. {
  70. _idleTimer -= delta;
  71. return;
  72. }
  73. //这个状态下不会有攻击事件, 所以没必要每一帧检查是否弹药耗尽
  74. //更新玩家位置
  75. if (_navigationUpdateTimer <= 0)
  76. {
  77. //每隔一段时间秒更改目标位置
  78. _navigationUpdateTimer = _navigationInterval;
  79. if (Master.AffiliationArea.RoomInfo.MarkTargetPosition.TryGetValue(_target.Id, out var pos))
  80. {
  81. _targetPosition = pos;
  82. }
  83. Master.NavigationAgent2D.TargetPosition = _targetPosition;
  84. }
  85. else
  86. {
  87. _navigationUpdateTimer -= delta;
  88. }
  89.  
  90. if (!Master.NavigationAgent2D.IsNavigationFinished())
  91. {
  92. Master.LookTargetPosition(_targetPosition);
  93. //移动
  94. Master.DoMove();
  95. }
  96. else
  97. {
  98. //站立
  99. Master.DoIdle();
  100. }
  101. //攻击目标
  102. var attackTarget = Master.GetAttackTarget();
  103. if (attackTarget != null)
  104. {
  105. //切换成发现目标状态
  106. Master.LookTarget = attackTarget;
  107. ChangeState(AIStateEnum.AiAstonished, AIStateEnum.AiFollowUp);
  108. return;
  109. }
  110.  
  111. //移动到目标掉了, 还没发现目标
  112. if (Master.NavigationAgent2D.IsNavigationFinished())
  113. {
  114. ChangeState(AIStateEnum.AiNormal);
  115. }
  116. }
  117.  
  118. public override void DebugDraw()
  119. {
  120. Master.DrawLine(Vector2.Zero, Master.ToLocal(Master.NavigationAgent2D.TargetPosition), Colors.Yellow);
  121. }
  122. }