Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / role / enemy / state / AiSurroundState.cs
  1.  
  2. using Godot;
  3.  
  4. /// <summary>
  5. /// 距离目标足够近, 在目标附近随机移动, 并开火
  6. /// </summary>
  7. public class AiSurroundState : StateBase<Enemy, AiStateEnum>
  8. {
  9. /// <summary>
  10. /// 目标是否在视野内
  11. /// </summary>
  12. public bool IsInView = true;
  13.  
  14. //是否移动结束
  15. private bool _isMoveOver;
  16.  
  17. //移动停顿计时器
  18. private float _pauseTimer;
  19. private bool _moveFlag;
  20. //下一个移动点
  21. private Vector2 _nextPosition;
  22.  
  23. public AiSurroundState() : base(AiStateEnum.AiSurround)
  24. {
  25. }
  26.  
  27. public override void Enter(AiStateEnum prev, params object[] args)
  28. {
  29. IsInView = true;
  30. _isMoveOver = true;
  31. _pauseTimer = 0;
  32. _moveFlag = false;
  33. }
  34.  
  35. public override void PhysicsProcess(float delta)
  36. {
  37. //先检查弹药是否打光
  38. if (Master.IsAllWeaponTotalAmmoEmpty())
  39. {
  40. //再寻找是否有可用的武器
  41. if (Master.CheckUsableWeaponInUnclaimed())
  42. {
  43. //切换到寻找武器状态
  44. ChangeStateLate(AiStateEnum.AiFindAmmo);
  45. return;
  46. }
  47. }
  48. var playerPos = Player.Current.GetCenterPosition();
  49. var weapon = Master.Holster.ActiveWeapon;
  50.  
  51. //枪口指向玩家
  52. Master.LookTargetPosition(playerPos);
  53.  
  54. //检测玩家是否在视野内
  55. if (Master.IsInTailAfterViewRange(playerPos))
  56. {
  57. IsInView = !Master.TestViewRayCast(playerPos);
  58. //关闭射线检测
  59. Master.TestViewRayCastOver();
  60. }
  61. else
  62. {
  63. IsInView = false;
  64. }
  65.  
  66. if (IsInView)
  67. {
  68. if (_pauseTimer >= 0)
  69. {
  70. Master.AnimatedSprite.Animation = AnimatorNames.Idle;
  71. _pauseTimer -= delta;
  72. }
  73. else if (_isMoveOver) //移动已经完成
  74. {
  75. RunOver(playerPos);
  76. _isMoveOver = false;
  77. }
  78. else
  79. {
  80. if (Master.NavigationAgent2D.IsNavigationFinished()) //到达终点
  81. {
  82. _pauseTimer = Utils.RandfRange(0f, 0.5f);
  83. _isMoveOver = true;
  84. _moveFlag = false;
  85. Master.BasisVelocity = Vector2.Zero;
  86. }
  87. else if (!_moveFlag)
  88. {
  89. _moveFlag = true;
  90. //计算移动
  91. var nextPos = Master.NavigationAgent2D.GetNextPathPosition();
  92. Master.AnimatedSprite.Animation = AnimatorNames.Run;
  93. Master.BasisVelocity = (nextPos - Master.GlobalPosition - Master.NavigationPoint.Position).Normalized() *
  94. Master.MoveSpeed;
  95. }
  96. else
  97. {
  98. var lastSlideCollision = Master.GetLastSlideCollision();
  99. if (lastSlideCollision != null && lastSlideCollision.GetCollider() is Role) //碰到其他角色
  100. {
  101. _pauseTimer = Utils.RandfRange(0f, 0.3f);
  102. _isMoveOver = true;
  103. _moveFlag = false;
  104. Master.BasisVelocity = Vector2.Zero;
  105. }
  106. else
  107. {
  108. //计算移动
  109. var nextPos = Master.NavigationAgent2D.GetNextPathPosition();
  110. Master.AnimatedSprite.Animation = AnimatorNames.Run;
  111. Master.BasisVelocity = (nextPos - Master.GlobalPosition - Master.NavigationPoint.Position).Normalized() *
  112. Master.MoveSpeed;
  113. }
  114. }
  115.  
  116. if (weapon != null)
  117. {
  118. var position = Master.GlobalPosition;
  119. if (position.DistanceSquaredTo(playerPos) > Mathf.Pow(Master.GetWeaponRange(0.7f), 2)) //玩家离开正常射击范围
  120. {
  121. ChangeStateLate(AiStateEnum.AiFollowUp);
  122. }
  123. else
  124. {
  125. //发起攻击
  126. Master.EnemyAttack();
  127. }
  128. }
  129. }
  130. }
  131. else //目标离开视野
  132. {
  133. ChangeStateLate(AiStateEnum.AiTailAfter);
  134. }
  135. }
  136.  
  137. private void RunOver(Vector2 targetPos)
  138. {
  139. var distance = (int)(Master.Holster.ActiveWeapon.Attribute.MinDistance * 0.7f);
  140. _nextPosition = new Vector2(
  141. targetPos.X + Utils.RandRangeInt(-distance, distance),
  142. targetPos.Y + Utils.RandRangeInt(-distance, distance)
  143. );
  144. Master.NavigationAgent2D.TargetPosition = _nextPosition;
  145. }
  146.  
  147. public override void DebugDraw()
  148. {
  149. Master.DrawLine(new Vector2(0, -8), Master.ToLocal(_nextPosition), Colors.White);
  150. }
  151. }