Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / activity / role / enemy / state / AiFindAmmoState.cs
  1.  
  2. using System;
  3. using Godot;
  4.  
  5. namespace EnemyState;
  6.  
  7. /// <summary>
  8. /// Ai 寻找弹药, 进入该状态需要在参数中传入目标武器对象
  9. /// </summary>
  10. public class AiFindAmmoState : StateBase<Enemy, AIStateEnum>
  11. {
  12.  
  13. private Weapon _target;
  14.  
  15. //导航目标点刷新计时器
  16. private float _navigationUpdateTimer = 0;
  17. private float _navigationInterval = 1f;
  18.  
  19. private bool _isInTailAfterRange = false;
  20. private float _tailAfterTimer = 0;
  21.  
  22. public AiFindAmmoState() : base(AIStateEnum.AiFindAmmo)
  23. {
  24. }
  25.  
  26. public override void Enter(AIStateEnum prev, params object[] args)
  27. {
  28. if (Master.LookTarget == null)
  29. {
  30. throw new Exception("进入 AIAdvancedStateEnum.AiFindAmmo 状态时角色没有攻击目标!");
  31. }
  32. if (args.Length == 0)
  33. {
  34. throw new Exception("进入 AiStateEnum.AiFindAmmo 状态必须要把目标武器当成参数传过来");
  35. }
  36.  
  37. SetTargetWeapon((Weapon)args[0]);
  38. _navigationUpdateTimer = 0;
  39. _isInTailAfterRange = false;
  40. _tailAfterTimer = 0;
  41.  
  42. //标记武器
  43. _target.SetSign(SignNames.AiFindWeaponSign, Master);
  44. }
  45.  
  46. public override void Process(float delta)
  47. {
  48. if (!Master.IsAllWeaponTotalAmmoEmpty()) //已经有弹药了
  49. {
  50. ChangeState(GetNextState());
  51. return;
  52. }
  53.  
  54. //更新目标位置
  55. if (_navigationUpdateTimer <= 0)
  56. {
  57. //每隔一段时间秒更改目标位置
  58. _navigationUpdateTimer = _navigationInterval;
  59. var position = _target.GlobalPosition;
  60. Master.NavigationAgent2D.TargetPosition = position;
  61. }
  62. else
  63. {
  64. _navigationUpdateTimer -= delta;
  65. }
  66.  
  67. if (_target.IsDestroyed || _target.IsTotalAmmoEmpty()) //已经被销毁, 或者弹药已经被其他角色捡走
  68. {
  69. //再去寻找其他武器
  70. SetTargetWeapon(Master.FindTargetWeapon());
  71.  
  72. if (_target == null) //也没有其他可用的武器了
  73. {
  74. ChangeState(GetNextState());
  75. }
  76. }
  77. else if (_target.Master == Master) //已经被自己拾起
  78. {
  79. ChangeState(GetNextState());
  80. }
  81. else if (_target.Master != null) //武器已经被其他角色拾起!
  82. {
  83. //再去寻找其他武器
  84. SetTargetWeapon(Master.FindTargetWeapon());
  85.  
  86. if (_target == null) //也没有其他可用的武器了
  87. {
  88. ChangeState(GetNextState());
  89. }
  90. }
  91. else
  92. {
  93. //检测目标没有超出跟随视野距离
  94. _isInTailAfterRange = Master.IsInTailAfterViewRange(Master.LookTarget.GetCenterPosition());
  95. if (_isInTailAfterRange)
  96. {
  97. _tailAfterTimer = 0;
  98. }
  99. else
  100. {
  101. _tailAfterTimer += delta;
  102. }
  103.  
  104. //向武器移动
  105. if (!Master.NavigationAgent2D.IsNavigationFinished())
  106. {
  107. //移动
  108. Master.DoMove();
  109. }
  110. else
  111. {
  112. //站立
  113. Master.DoIdle();
  114. }
  115. }
  116. }
  117.  
  118. private AIStateEnum GetNextState()
  119. {
  120. return _tailAfterTimer > 10 ? AIStateEnum.AiNormal : AIStateEnum.AiTailAfter;
  121. }
  122.  
  123. private void SetTargetWeapon(Weapon weapon)
  124. {
  125. _target = weapon;
  126. //设置目标点
  127. if (_target != null)
  128. {
  129. Master.NavigationAgent2D.TargetPosition = _target.GlobalPosition;
  130. }
  131. }
  132. public override void DebugDraw()
  133. {
  134. if (_target != null)
  135. {
  136. Master.DrawLine(Vector2.Zero, Master.ToLocal(_target.GlobalPosition), Colors.Purple);
  137.  
  138. if (_tailAfterTimer <= 0)
  139. {
  140. Master.DrawLine(Vector2.Zero, Master.ToLocal(Master.LookTarget.GetCenterPosition()), Colors.Orange);
  141. }
  142. else if (_tailAfterTimer <= 10)
  143. {
  144. Master.DrawLine(Vector2.Zero, Master.ToLocal(Master.LookTarget.GetCenterPosition()), Colors.Blue);
  145. }
  146. }
  147. }
  148. }