Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / activity / role / enemy / advancedState / AiLeaveForState.cs
  1.  
  2. using System;
  3. using Godot;
  4.  
  5. namespace AdvancedState;
  6.  
  7. /// <summary>
  8. /// 收到其他敌人通知, 前往发现目标的位置
  9. /// </summary>
  10. public class AiLeaveForState : StateBase<AdvancedEnemy, AIAdvancedStateEnum>
  11. {
  12. //导航目标点刷新计时器
  13. private float _navigationUpdateTimer = 0;
  14. private float _navigationInterval = 0.3f;
  15.  
  16. //目标
  17. private ActivityObject _target;
  18. //目标点
  19. private Vector2 _targetPosition;
  20.  
  21. public AiLeaveForState() : base(AIAdvancedStateEnum.AiLeaveFor)
  22. {
  23. }
  24.  
  25. public override void Enter(AIAdvancedStateEnum prev, params object[] args)
  26. {
  27. if (args.Length == 0)
  28. {
  29. throw new Exception("进入 AINormalStateEnum.AiLeaveFor 状态必须带上目标对象");
  30. }
  31.  
  32. _target = (ActivityObject)args[0];
  33. _targetPosition = _target.GetCenterPosition();
  34. Master.LookTargetPosition(_targetPosition);
  35. //先检查弹药是否打光
  36. if (Master.IsAllWeaponTotalAmmoEmpty())
  37. {
  38. //再寻找是否有可用的武器
  39. var targetWeapon = Master.FindTargetWeapon();
  40. if (targetWeapon != null)
  41. {
  42. Master.LookTarget = _target;
  43. ChangeState(AIAdvancedStateEnum.AiFindAmmo, targetWeapon);
  44. }
  45. }
  46. }
  47.  
  48. public override void Process(float delta)
  49. {
  50. //这个状态下不会有攻击事件, 所以没必要每一帧检查是否弹药耗尽
  51. //更新玩家位置
  52. if (_navigationUpdateTimer <= 0)
  53. {
  54. //每隔一段时间秒更改目标位置
  55. _navigationUpdateTimer = _navigationInterval;
  56. if (Master.AffiliationArea.RoomInfo.MarkTargetPosition.TryGetValue(_target.Id, out var pos))
  57. {
  58. _targetPosition = pos;
  59. }
  60. Master.NavigationAgent2D.TargetPosition = _targetPosition;
  61. }
  62. else
  63. {
  64. _navigationUpdateTimer -= delta;
  65. }
  66.  
  67. if (!Master.NavigationAgent2D.IsNavigationFinished())
  68. {
  69. Master.LookTargetPosition(_targetPosition);
  70. //移动
  71. Master.DoMove();
  72. }
  73. else
  74. {
  75. //站立
  76. Master.DoIdle();
  77. }
  78.  
  79. var playerPos = Player.Current.GetCenterPosition();
  80. //检测玩家是否在视野内, 如果在, 则切换到 AiTargetInView 状态
  81. if (Master.IsInTailAfterViewRange(playerPos))
  82. {
  83. if (!Master.TestViewRayCast(playerPos)) //看到玩家
  84. {
  85. //关闭射线检测
  86. Master.TestViewRayCastOver();
  87. //切换成发现目标状态
  88. Master.LookTarget = Player.Current;
  89. ChangeState(AIAdvancedStateEnum.AiFollowUp);
  90. return;
  91. }
  92. else
  93. {
  94. //关闭射线检测
  95. Master.TestViewRayCastOver();
  96. }
  97. }
  98.  
  99. //移动到目标掉了, 还没发现目标
  100. if (Master.NavigationAgent2D.IsNavigationFinished())
  101. {
  102. ChangeState(AIAdvancedStateEnum.AiNormal);
  103. }
  104. }
  105.  
  106. public override void DebugDraw()
  107. {
  108. Master.DrawLine(Vector2.Zero, Master.ToLocal(Master.NavigationAgent2D.TargetPosition), Colors.Yellow);
  109. }
  110. }