Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / activity / role / ai / state / AiFindAmmoState.cs
@小李xl 小李xl on 9 Apr 2024 5 KB 完善ai改变阵营逻辑
  1.  
  2. using System;
  3. using Godot;
  4.  
  5. namespace AiState;
  6.  
  7. /// <summary>
  8. /// Ai 寻找弹药, 进入该状态需要在参数中传入目标武器对象
  9. /// </summary>
  10. public class AiFindAmmoState : StateBase<AiRole, AIStateEnum>
  11. {
  12. /// <summary>
  13. /// 目标武器
  14. /// </summary>
  15. public Weapon TargetWeapon;
  16.  
  17. //导航目标点刷新计时器
  18. private float _navigationUpdateTimer = 0;
  19. private float _navigationInterval = 1f;
  20. private float _tailAfterTimer = 0;
  21. private ActivityObject _attackTarget;
  22.  
  23. private float _idleTimer = 0;
  24. private bool _playAnimFlag = false;
  25.  
  26. public AiFindAmmoState() : base(AIStateEnum.AiFindAmmo)
  27. {
  28. }
  29.  
  30. public override void Enter(AIStateEnum prev, params object[] args)
  31. {
  32. if (args.Length == 0)
  33. {
  34. throw new Exception("进入 AiStateEnum.AiFindAmmo 状态必须要把目标武器当成参数传过来");
  35. }
  36.  
  37. if (args.Length >= 2)
  38. {
  39. _attackTarget = (ActivityObject)args[1];
  40. }
  41. else
  42. {
  43. _attackTarget = null;
  44. }
  45. SetTargetWeapon((Weapon)args[0]);
  46. _navigationUpdateTimer = _navigationInterval;
  47. _tailAfterTimer = 0;
  48.  
  49. //标记武器
  50. TargetWeapon.SetSign(SignNames.AiFindWeaponSign, Master);
  51. _playAnimFlag = prev == AIStateEnum.AiLeaveFor;
  52. if (_playAnimFlag)
  53. {
  54. if (Master.AnimationPlayer.HasAnimation(AnimatorNames.Query))
  55. {
  56. Master.AnimationPlayer.Play(AnimatorNames.Query);
  57. }
  58. }
  59. }
  60.  
  61. public override void Process(float delta)
  62. {
  63. if (_playAnimFlag && _idleTimer > 0)
  64. {
  65. _idleTimer -= delta;
  66. return;
  67. }
  68. if (!Master.IsAllWeaponTotalAmmoEmpty()) //已经有弹药了
  69. {
  70. RunNextState();
  71. return;
  72. }
  73.  
  74. if (Master.LookTarget == null) //没有目标
  75. {
  76. //攻击目标
  77. var attackTarget = Master.GetAttackTarget();
  78. if (attackTarget != null)
  79. {
  80. //发现玩家
  81. Master.LookTarget = attackTarget;
  82. //进入惊讶状态, 然后再进入通知状态
  83. ChangeState(AIStateEnum.AiAstonished, AIStateEnum.AiFindAmmo, TargetWeapon);
  84. return;
  85. }
  86. }
  87.  
  88. //更新目标位置
  89. if (_navigationUpdateTimer <= 0)
  90. {
  91. //每隔一段时间秒更改目标位置
  92. _navigationUpdateTimer = _navigationInterval;
  93. var position = TargetWeapon.GlobalPosition;
  94. Master.NavigationAgent2D.TargetPosition = position;
  95. }
  96. else
  97. {
  98. _navigationUpdateTimer -= delta;
  99. }
  100.  
  101. if (TargetWeapon.IsDestroyed || TargetWeapon.IsTotalAmmoEmpty()) //已经被销毁, 或者弹药已经被其他角色捡走
  102. {
  103. //再去寻找其他武器
  104. SetTargetWeapon(Master.FindTargetWeapon());
  105.  
  106. if (TargetWeapon == null) //也没有其他可用的武器了
  107. {
  108. RunNextState();
  109. }
  110. }
  111. else if (TargetWeapon.Master == Master) //已经被自己拾起
  112. {
  113. RunNextState();
  114. }
  115. else if (TargetWeapon.Master != null) //武器已经被其他角色拾起!
  116. {
  117. //再去寻找其他武器
  118. SetTargetWeapon(Master.FindTargetWeapon());
  119.  
  120. if (TargetWeapon == null) //也没有其他可用的武器了
  121. {
  122. RunNextState();
  123. }
  124. }
  125. else
  126. {
  127. if (Master.LookTarget != null)
  128. {
  129. //检测目标没有超出跟随视野距离
  130. var isInTailAfterRange = Master.TargetInViewRange;
  131. if (isInTailAfterRange)
  132. {
  133. _tailAfterTimer = 0;
  134. }
  135. else
  136. {
  137. _tailAfterTimer += delta;
  138. }
  139. }
  140.  
  141. //向武器移动
  142. if (!Master.NavigationAgent2D.IsNavigationFinished())
  143. {
  144. //移动
  145. Master.DoMove();
  146. }
  147. else
  148. {
  149. //站立
  150. Master.DoIdle();
  151. }
  152. }
  153. }
  154.  
  155. private void RunNextState()
  156. {
  157. if (_attackTarget != null)
  158. {
  159. ChangeState(AIStateEnum.AiLeaveFor, _attackTarget);
  160. }
  161. else if (Master.LookTarget != null)
  162. {
  163. ChangeState(_tailAfterTimer > 10 ? AIStateEnum.AiNormal : AIStateEnum.AiTailAfter);
  164. }
  165. else
  166. {
  167. ChangeState(AIStateEnum.AiNormal);
  168. }
  169. }
  170.  
  171. private void SetTargetWeapon(Weapon weapon)
  172. {
  173. TargetWeapon = weapon;
  174. if (weapon != null)
  175. {
  176. //设置目标点
  177. Master.NavigationAgent2D.TargetPosition = TargetWeapon.GlobalPosition;
  178. }
  179. }
  180. public override void DebugDraw()
  181. {
  182. if (TargetWeapon != null)
  183. {
  184. Master.DrawLine(Vector2.Zero, Master.ToLocal(TargetWeapon.GlobalPosition), Colors.Purple);
  185.  
  186. if (Master.LookTarget != null)
  187. {
  188. if (_tailAfterTimer <= 0)
  189. {
  190. Master.DrawLine(Vector2.Zero, Master.ToLocal(Master.LookTarget.GetCenterPosition()), Colors.Orange);
  191. }
  192. else if (_tailAfterTimer <= 10)
  193. {
  194. Master.DrawLine(Vector2.Zero, Master.ToLocal(Master.LookTarget.GetCenterPosition()), Colors.Blue);
  195. }
  196. }
  197. }
  198. }
  199. }