Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / activity / role / enemy / state / AiFindAmmoState.cs
@小李xl 小李xl on 11 Oct 2023 4 KB 日志系统
  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. if (args.Length == 0)
  26. {
  27. Debug.LogError("进入 AiStateEnum.AiFindAmmo 状态必须要把目标武器当成参数传过来");
  28. ChangeState(prev);
  29. return;
  30. }
  31.  
  32. SetTargetWeapon((Weapon)args[0]);
  33. _navigationUpdateTimer = 0;
  34. _isInTailAfterRange = false;
  35. _tailAfterTimer = 0;
  36.  
  37. //标记武器
  38. _target.SetSign(SignNames.AiFindWeaponSign, Master);
  39. }
  40.  
  41. public override void Process(float delta)
  42. {
  43. if (!Master.IsAllWeaponTotalAmmoEmpty()) //已经有弹药了
  44. {
  45. ChangeState(GetNextState());
  46. return;
  47. }
  48.  
  49. //更新目标位置
  50. if (_navigationUpdateTimer <= 0)
  51. {
  52. //每隔一段时间秒更改目标位置
  53. _navigationUpdateTimer = _navigationInterval;
  54. var position = _target.GlobalPosition;
  55. Master.NavigationAgent2D.TargetPosition = position;
  56. }
  57. else
  58. {
  59. _navigationUpdateTimer -= delta;
  60. }
  61.  
  62. var playerPos = Player.Current.GetCenterPosition();
  63. //枪口指向玩家
  64. Master.LookTargetPosition(playerPos);
  65.  
  66. if (_target.IsDestroyed || _target.IsTotalAmmoEmpty()) //已经被销毁, 或者弹药已经被其他角色捡走
  67. {
  68. //再去寻找其他武器
  69. SetTargetWeapon(Master.FindTargetWeapon());
  70.  
  71. if (_target == null) //也没有其他可用的武器了
  72. {
  73. ChangeState(GetNextState());
  74. }
  75. }
  76. else if (_target.Master == Master) //已经被自己拾起
  77. {
  78. ChangeState(GetNextState());
  79. }
  80. else if (_target.Master != null) //武器已经被其他角色拾起!
  81. {
  82. //再去寻找其他武器
  83. SetTargetWeapon(Master.FindTargetWeapon());
  84.  
  85. if (_target == null) //也没有其他可用的武器了
  86. {
  87. ChangeState(GetNextState());
  88. }
  89. }
  90. else
  91. {
  92. //检测目标没有超出跟随视野距离
  93. _isInTailAfterRange = Master.IsInTailAfterViewRange(playerPos);
  94. if (_isInTailAfterRange)
  95. {
  96. _tailAfterTimer = 0;
  97. }
  98. else
  99. {
  100. _tailAfterTimer += delta;
  101. }
  102.  
  103. //向武器移动
  104. if (!Master.NavigationAgent2D.IsNavigationFinished())
  105. {
  106. //计算移动
  107. var nextPos = Master.NavigationAgent2D.GetNextPathPosition();
  108. Master.AnimatedSprite.Play(AnimatorNames.Run);
  109. Master.BasisVelocity =
  110. (nextPos - Master.GlobalPosition - Master.NavigationPoint.Position).Normalized() *
  111. Master.RoleState.MoveSpeed;
  112. }
  113. else
  114. {
  115. Master.BasisVelocity = Vector2.Zero;
  116. }
  117. }
  118. }
  119.  
  120. private AiStateEnum GetNextState()
  121. {
  122. return _tailAfterTimer > 10 ? AiStateEnum.AiNormal : AiStateEnum.AiTailAfter;
  123. }
  124.  
  125. private void SetTargetWeapon(Weapon weapon)
  126. {
  127. _target = weapon;
  128. //设置目标点
  129. if (_target != null)
  130. {
  131. Master.NavigationAgent2D.TargetPosition = _target.GlobalPosition;
  132. }
  133. }
  134. public override void DebugDraw()
  135. {
  136. if (_target != null)
  137. {
  138. Master.DrawLine(Vector2.Zero, Master.ToLocal(_target.GlobalPosition), Colors.Purple);
  139.  
  140. if (_tailAfterTimer <= 0)
  141. {
  142. Master.DrawLine(Vector2.Zero, Master.ToLocal(Player.Current.GetCenterPosition()), Colors.Orange);
  143. }
  144. else if (_tailAfterTimer <= 10)
  145. {
  146. Master.DrawLine(Vector2.Zero, Master.ToLocal(Player.Current.GetCenterPosition()), Colors.Blue);
  147. }
  148. }
  149. }
  150. }