diff --git a/DungeonShooting_Godot/prefab/role/Player.tscn b/DungeonShooting_Godot/prefab/role/Player.tscn index 7154560..5786938 100644 --- a/DungeonShooting_Godot/prefab/role/Player.tscn +++ b/DungeonShooting_Godot/prefab/role/Player.tscn @@ -24,4 +24,4 @@ [node name="AnimatedSprite" parent="." index="2"] material = SubResource( 2 ) -frame = 1 +frame = 2 diff --git a/DungeonShooting_Godot/scene/Main.tscn b/DungeonShooting_Godot/scene/Main.tscn index aff7b6d..35a4274 100644 --- a/DungeonShooting_Godot/scene/Main.tscn +++ b/DungeonShooting_Godot/scene/Main.tscn @@ -24,6 +24,7 @@ [node name="Main" type="Node2D"] script = ExtResource( 3 ) +Debug = true CursorPack = ExtResource( 4 ) RoomPath = NodePath("ViewCanvas/ViewportContainer/Viewport/Room") ViewportPath = NodePath("ViewCanvas/ViewportContainer/Viewport") diff --git a/DungeonShooting_Godot/src/game/role/enemy/state/AIAttackState.cs b/DungeonShooting_Godot/src/game/role/enemy/state/AIAttackState.cs index ffc2b6e..ba2241e 100644 --- a/DungeonShooting_Godot/src/game/role/enemy/state/AIAttackState.cs +++ b/DungeonShooting_Godot/src/game/role/enemy/state/AIAttackState.cs @@ -6,23 +6,77 @@ /// public class AIAttackState : StateBase { + + /// + /// 是否在视野内 + /// + public bool IsInView; + + //导航目标点刷新计时器 + private float _navigationUpdateTimer = 0; + private float _navigationInterval = 0.3f; + public AIAttackState() : base(AIStateEnum.AIAttack) { } public override void Enter(AIStateEnum prev, params object[] args) { - + _navigationUpdateTimer = 0; + IsInView = true; } public override void PhysicsProcess(float delta) { + var masterPos = Master.GlobalPosition; + var playerPos = GameApplication.Instance.Room.Player.GlobalPosition; + //更新玩家位置 + if (_navigationUpdateTimer <= 0) + { + //每隔一段时间秒更改目标位置 + _navigationUpdateTimer = _navigationInterval; + if (Master.NavigationAgent2D.GetTargetLocation() != playerPos) + { + Master.NavigationAgent2D.SetTargetLocation(playerPos); + } + } + else + { + _navigationUpdateTimer -= delta; + } + + //计算移动 + var nextPos = Master.NavigationAgent2D.GetNextLocation(); + Master.LookTargetPosition(playerPos); + Master.AnimatedSprite.Animation = AnimatorNames.Run; + Master.Velocity = (nextPos - Master.GlobalPosition - Master.NavigationPoint.Position).Normalized() * Master.MoveSpeed; + Master.CalcMove(delta); + + //检测玩家是否在视野内 + if (masterPos.DistanceSquaredTo(playerPos) <= Master.TailAfterViewRange * Master.TailAfterViewRange) + { + IsInView = !Master.TestViewRayCast(playerPos); + Master.TestViewRayCastOver(); + } + else + { + IsInView = false; + } + + if (IsInView) + { + Master.EnemyAttack(); + } + else + { + ChangeStateLate(AIStateEnum.AITailAfter); + } } public override void DebugDraw() { var playerPos = GameApplication.Instance.Room.Player.GlobalPosition; - Master.DrawLine(Vector2.Zero, Master.ToLocal(playerPos), Colors.Red); + Master.DrawLine(new Vector2(0, -8), Master.ToLocal(playerPos), Colors.Red); } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/role/enemy/state/AiNormalState.cs b/DungeonShooting_Godot/src/game/role/enemy/state/AiNormalState.cs index 8dbf8e4..426f362 100644 --- a/DungeonShooting_Godot/src/game/role/enemy/state/AiNormalState.cs +++ b/DungeonShooting_Godot/src/game/role/enemy/state/AiNormalState.cs @@ -120,6 +120,6 @@ public override void DebugDraw() { - Master.DrawLine(Vector2.Zero, Master.ToLocal(_nextPos), Colors.Green); + Master.DrawLine(new Vector2(0, -8), Master.ToLocal(_nextPos), Colors.Green); } } diff --git a/DungeonShooting_Godot/src/game/role/enemy/state/AiTailAfterState.cs b/DungeonShooting_Godot/src/game/role/enemy/state/AiTailAfterState.cs index c088acf..c2331a8 100644 --- a/DungeonShooting_Godot/src/game/role/enemy/state/AiTailAfterState.cs +++ b/DungeonShooting_Godot/src/game/role/enemy/state/AiTailAfterState.cs @@ -10,12 +10,7 @@ /// 目标是否在视野半径内 /// public bool IsInViewRange; - - /// - /// 是否在视野内 - /// - public bool IsInView; - + //导航目标点刷新计时器 private float _navigationUpdateTimer = 0; private float _navigationInterval = 0.3f; @@ -30,7 +25,6 @@ public override void Enter(AIStateEnum prev, params object[] args) { IsInViewRange = true; - IsInView = true; _navigationUpdateTimer = 0; _viewTimer = 0; } @@ -62,35 +56,28 @@ Master.Velocity = (nextPos - Master.GlobalPosition - Master.NavigationPoint.Position).Normalized() * Master.MoveSpeed; Master.CalcMove(delta); - //检测玩家是否在视野内, 此时视野可穿墙, 直接检测距离即可 - + //是否看到玩家' + //检测玩家是否在视野内 if (masterPos.DistanceSquaredTo(playerPos) <= Master.TailAfterViewRange * Master.TailAfterViewRange) { - IsInView = !Master.TestViewRayCast(playerPos); - if (IsInView) + if (!Master.TestViewRayCast(playerPos)) { - IsInViewRange = true; + Master.TestViewRayCastOver(); + //切换成攻击状态 + ChangeStateLate(AIStateEnum.AIAttack); + return; } else { - IsInViewRange = masterPos.DistanceSquaredTo(playerPos) <= Master.ViewRange * Master.ViewRange; + Master.TestViewRayCastOver(); } } - else - { - IsInViewRange = masterPos.DistanceSquaredTo(playerPos) <= Master.ViewRange * Master.ViewRange; - IsInView = false; - } - + + //检测玩家是否在视野内, 此时视野可穿墙, 直接检测距离即可 + IsInViewRange = masterPos.DistanceSquaredTo(playerPos) <= Master.ViewRange * Master.ViewRange; if (IsInViewRange) { _viewTimer = 0; - - if (IsInView) - { - //攻击 - Master.EnemyAttack(); - } } else //超出视野 { @@ -108,17 +95,13 @@ public override void DebugDraw() { var playerPos = GameApplication.Instance.Room.Player.GlobalPosition; - if (IsInView) + if (IsInViewRange) { - Master.DrawLine(Vector2.Zero, Master.ToLocal(playerPos), Colors.Red); - } - else if (IsInViewRange) - { - Master.DrawLine(Vector2.Zero, Master.ToLocal(playerPos), Colors.Orange); + Master.DrawLine(new Vector2(0, -8), Master.ToLocal(playerPos), Colors.Orange); } else { - Master.DrawLine(Vector2.Zero, Master.ToLocal(playerPos), Colors.Blue); + Master.DrawLine(new Vector2(0, -8), Master.ToLocal(playerPos), Colors.Blue); } } } \ No newline at end of file