Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / role / enemy / state / AiNormalState.cs
  1.  
  2. using Godot;
  3.  
  4. /// <summary>
  5. /// AI 正常状态
  6. /// </summary>
  7. public class AiNormalState : StateBase<Enemy, AiStateEnum>
  8. {
  9. //是否发现玩家
  10. private bool _isFindPlayer;
  11.  
  12. //下一个运动的角度
  13. private Vector2 _nextPos;
  14.  
  15. //是否移动结束
  16. private bool _isMoveOver;
  17.  
  18. //上一次移动是否撞墙
  19. private bool _againstWall;
  20. //撞墙法线角度
  21. private float _againstWallNormalAngle;
  22.  
  23. //移动停顿计时器
  24. private float _pauseTimer;
  25. private bool _moveFlag;
  26.  
  27. public AiNormalState() : base(AiStateEnum.AiNormal)
  28. {
  29. }
  30.  
  31. public override void Enter(AiStateEnum prev, params object[] args)
  32. {
  33. _isFindPlayer = false;
  34. _isMoveOver = true;
  35. _againstWall = false;
  36. _againstWallNormalAngle = 0;
  37. _pauseTimer = 0;
  38. _moveFlag = false;
  39. }
  40.  
  41. public override void PhysicsProcess(float delta)
  42. {
  43. //其他敌人发现玩家
  44. if (Enemy.IsFindTarget)
  45. {
  46. ChangeStateLate(AiStateEnum.AiLeaveFor);
  47. return;
  48. }
  49.  
  50. if (_isFindPlayer) //已经找到玩家了
  51. {
  52. //现临时处理, 直接切换状态
  53. ChangeStateLate(AiStateEnum.AiTailAfter);
  54. }
  55. else //没有找到玩家
  56. {
  57. //检测玩家
  58. var player = GameApplication.Instance.RoomManager.Player;
  59. //玩家中心点坐标
  60. var playerPos = player.GetCenterPosition();
  61.  
  62. if (Master.IsInViewRange(playerPos) && !Master.TestViewRayCast(playerPos)) //发现玩家
  63. {
  64. //发现玩家
  65. _isFindPlayer = true;
  66. }
  67. else if (_pauseTimer >= 0)
  68. {
  69. Master.AnimatedSprite2D.Animation = AnimatorNames.Idle;
  70. _pauseTimer -= delta;
  71. }
  72. else if (_isMoveOver) //没发现玩家, 且已经移动完成
  73. {
  74. RunOver();
  75. _isMoveOver = false;
  76. }
  77. else //移动中
  78. {
  79. if (Master.NavigationAgent2D.IsNavigationFinished()) //到达终点
  80. {
  81. _pauseTimer = Utils.RandfRange(0.3f, 2f);
  82. _isMoveOver = true;
  83. _moveFlag = false;
  84. Master.BasisVelocity = Vector2.Zero;
  85. }
  86. else if (!_moveFlag)
  87. {
  88. _moveFlag = true;
  89. //计算移动
  90. var nextPos = Master.NavigationAgent2D.GetNextPathPosition();
  91. Master.AnimatedSprite2D.Animation = AnimatorNames.Run;
  92. Master.BasisVelocity = (nextPos - Master.GlobalPosition - Master.NavigationPoint.Position).Normalized() *
  93. Master.MoveSpeed;
  94. }
  95. else
  96. {
  97. var lastSlideCollision = Master.GetLastSlideCollision();
  98. if (lastSlideCollision != null && lastSlideCollision.GetCollider() is Role) //碰到其他角色
  99. {
  100. _pauseTimer = Utils.RandfRange(0.1f, 0.5f);
  101. _isMoveOver = true;
  102. _moveFlag = false;
  103. Master.BasisVelocity = Vector2.Zero;
  104. }
  105. else
  106. {
  107. //计算移动
  108. var nextPos = Master.NavigationAgent2D.GetNextPathPosition();
  109. Master.AnimatedSprite2D.Animation = AnimatorNames.Run;
  110. Master.BasisVelocity = (nextPos - Master.GlobalPosition - Master.NavigationPoint.Position).Normalized() *
  111. Master.MoveSpeed;
  112. }
  113. }
  114. }
  115.  
  116. //关闭射线检测
  117. Master.TestViewRayCastOver();
  118. }
  119. }
  120.  
  121. //移动结束
  122. private void RunOver()
  123. {
  124. float angle;
  125. if (_againstWall)
  126. {
  127. angle = Utils.RandfRange(_againstWallNormalAngle - Mathf.Pi * 0.5f,
  128. _againstWallNormalAngle + Mathf.Pi * 0.5f);
  129. }
  130. else
  131. {
  132. angle = Utils.RandfRange(0, Mathf.Pi * 2f);
  133. }
  134.  
  135. var len = Utils.RandRangeInt(30, 200);
  136. _nextPos = new Vector2(len, 0).Rotated(angle) + Master.GlobalPosition;
  137. //获取射线碰到的坐标
  138. if (Master.TestViewRayCast(_nextPos)) //碰到墙壁
  139. {
  140. _nextPos = Master.ViewRay.GetCollisionPoint();
  141. _againstWall = true;
  142. _againstWallNormalAngle = Master.ViewRay.GetCollisionNormal().Angle();
  143. }
  144. else
  145. {
  146. _againstWall = false;
  147. }
  148.  
  149. Master.NavigationAgent2D.TargetPosition = _nextPos;
  150. Master.LookTargetPosition(_nextPos);
  151. }
  152.  
  153. public override void DebugDraw()
  154. {
  155. Master.DrawLine(new Vector2(0, -8), Master.ToLocal(_nextPos), Colors.Green);
  156. }
  157. }