Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / role / enemy / state / AiFindAmmoState.cs
  1.  
  2. using Godot;
  3.  
  4. /// <summary>
  5. /// Ai 寻找弹药
  6. /// </summary>
  7. public class AiFindAmmoState : StateBase<Enemy, AiStateEnum>
  8. {
  9.  
  10. private Weapon _target;
  11.  
  12. //导航目标点刷新计时器
  13. private float _navigationUpdateTimer = 0;
  14. private float _navigationInterval = 1f;
  15.  
  16. private bool _isInTailAfterRange = false;
  17. private float _tailAfterTimer = 0;
  18.  
  19. public AiFindAmmoState() : base(AiStateEnum.AiFindAmmo)
  20. {
  21. }
  22.  
  23. public override void Enter(AiStateEnum prev, params object[] args)
  24. {
  25. _navigationUpdateTimer = 0;
  26. _isInTailAfterRange = false;
  27. _tailAfterTimer = 0;
  28. //找到能用的武器
  29. FindTargetWeapon();
  30. if (_target == null)
  31. {
  32. ChangeStateLate(prev);
  33. return;
  34. }
  35.  
  36. //标记武器
  37. _target.SetSign(SignNames.AiFindWeaponSign, Master);
  38. }
  39.  
  40. public override void Process(float delta)
  41. {
  42. if (!Master.IsAllWeaponTotalAmmoEmpty()) //已经有弹药了
  43. {
  44. ChangeStateLate(GetNextState());
  45. return;
  46. }
  47.  
  48. //更新目标位置
  49. if (_navigationUpdateTimer <= 0)
  50. {
  51. //每隔一段时间秒更改目标位置
  52. _navigationUpdateTimer = _navigationInterval;
  53. var position = _target.GlobalPosition;
  54. Master.NavigationAgent2D.TargetPosition = position;
  55. }
  56. else
  57. {
  58. _navigationUpdateTimer -= delta;
  59. }
  60.  
  61. var playerPos = Player.Current.GetCenterPosition();
  62. //枪口指向玩家
  63. Master.LookTargetPosition(playerPos);
  64.  
  65. if (_target.IsQueuedForDeletion() || _target.IsTotalAmmoEmpty()) //已经被销毁, 或者弹药已经被其他角色捡走
  66. {
  67. //再去寻找其他武器
  68. FindTargetWeapon();
  69.  
  70. if (_target == null) //也没有其他可用的武器了
  71. {
  72. ChangeStateLate(GetNextState());
  73. }
  74. }
  75. else if (_target.Master == Master) //已经被自己拾起
  76. {
  77. ChangeStateLate(GetNextState());
  78. }
  79. else if (_target.Master != null) //武器已经被其他角色拾起!
  80. {
  81. //再去寻找其他武器
  82. FindTargetWeapon();
  83.  
  84. if (_target == null) //也没有其他可用的武器了
  85. {
  86. ChangeStateLate(GetNextState());
  87. }
  88. }
  89. else
  90. {
  91. //检测目标没有超出跟随视野距离
  92. _isInTailAfterRange = Master.IsInTailAfterViewRange(playerPos);
  93. if (_isInTailAfterRange)
  94. {
  95. _tailAfterTimer = 0;
  96. }
  97. else
  98. {
  99. _tailAfterTimer += delta;
  100. }
  101.  
  102. //向武器移动
  103. if (!Master.NavigationAgent2D.IsNavigationFinished())
  104. {
  105. //计算移动
  106. var nextPos = Master.NavigationAgent2D.GetNextPathPosition();
  107. Master.AnimatedSprite.Play(AnimatorNames.Run);
  108. Master.BasisVelocity =
  109. (nextPos - Master.GlobalPosition - Master.NavigationPoint.Position).Normalized() *
  110. Master.MoveSpeed;
  111. }
  112. else
  113. {
  114. Master.BasisVelocity = Vector2.Zero;
  115. }
  116. }
  117. }
  118.  
  119. private AiStateEnum GetNextState()
  120. {
  121. return _tailAfterTimer > 10 ? AiStateEnum.AiNormal : AiStateEnum.AiTailAfter;
  122. }
  123. public override void DebugDraw()
  124. {
  125. if (_target != null)
  126. {
  127. Master.DrawLine(Vector2.Zero, Master.ToLocal(_target.GlobalPosition), Colors.Purple);
  128.  
  129. if (_tailAfterTimer <= 0)
  130. {
  131. Master.DrawLine(Vector2.Zero, Master.ToLocal(Player.Current.GetCenterPosition()), Colors.Orange);
  132. }
  133. else if (_tailAfterTimer <= 10)
  134. {
  135. Master.DrawLine(Vector2.Zero, Master.ToLocal(Player.Current.GetCenterPosition()), Colors.Blue);
  136. }
  137. }
  138. }
  139.  
  140. private void FindTargetWeapon()
  141. {
  142. _target = null;
  143. var position = Master.Position;
  144. foreach (var weapon in Weapon.UnclaimedWeapons)
  145. {
  146. if (!weapon.IsTotalAmmoEmpty())
  147. {
  148. //查询是否有其他敌人标记要拾起该武器
  149. if (weapon.HasSign(SignNames.AiFindWeaponSign))
  150. {
  151. var enemy = weapon.GetSign<Enemy>(SignNames.AiFindWeaponSign);
  152. if (enemy == Master) //就是自己标记的
  153. {
  154.  
  155. }
  156. else if (enemy == null || enemy.IsQueuedForDeletion()) //标记当前武器的敌人已经被销毁
  157. {
  158. weapon.RemoveSign(SignNames.AiFindWeaponSign);
  159. }
  160. else if (!enemy.IsAllWeaponTotalAmmoEmpty()) //标记当前武器的敌人已经有新的武器了
  161. {
  162. weapon.RemoveSign(SignNames.AiFindWeaponSign);
  163. }
  164. else //放弃这把武器
  165. {
  166. continue;
  167. }
  168. }
  169.  
  170. if (_target == null) //第一把武器
  171. {
  172. _target = weapon;
  173. }
  174. else if (_target.Position.DistanceSquaredTo(position) >
  175. weapon.Position.DistanceSquaredTo(position)) //距离更近
  176. {
  177. _target = weapon;
  178. }
  179. }
  180. }
  181.  
  182. //设置目标点
  183. if (_target != null)
  184. {
  185. Master.NavigationAgent2D.TargetPosition = _target.GlobalPosition;
  186. }
  187. }
  188. }