diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/AdvancedEnemy.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/AdvancedEnemy.cs
index d1313b9..ea5c57b 100644
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/AdvancedEnemy.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/AdvancedEnemy.cs
@@ -350,7 +350,7 @@
}
///
- /// 调用视野检测, 如果被墙壁和其它物体遮挡, 则返回被挡住视野的物体对象, 视野无阻则返回 null
+ /// 调用视野检测, 如果被墙壁和其它物体遮挡, 则返回true
///
public bool TestViewRayCast(Vector2 target)
{
diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiAttackState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiAttackState.cs
index fb4e26f..f4f690d 100644
--- a/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiAttackState.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/enemy/advancedState/AiAttackState.cs
@@ -16,6 +16,21 @@
/// 攻击状态
///
public AiAttackEnum AttackState;
+
+ //是否移动结束
+ private bool _isMoveOver;
+
+ //移动停顿计时器
+ private float _pauseTimer;
+ private bool _moveFlag;
+
+ //下一个移动点
+ private Vector2 _nextPosition;
+
+ //上一帧位置
+ private Vector2 _prevPos;
+ //卡在一个位置的时间
+ private float _lockTimer;
public AiAttackState() : base(AIAdvancedStateEnum.AiAttack)
{
@@ -42,6 +57,10 @@
AttackState = AiAttackEnum.None;
Master.LockTargetTime = 0;
PrevState = prev;
+
+ _isMoveOver = true;
+ _pauseTimer = 0;
+ _moveFlag = false;
}
public override void Exit(AIAdvancedStateEnum next)
@@ -53,18 +72,43 @@
public override void Process(float delta)
{
+ Master.LookTarget = Player.Current;
+
var weapon = Master.WeaponPack.ActiveItem;
- if (weapon == null || (weapon.GetAttackTimer() > 0 && weapon.GetContinuousCount() <= 0)) //攻击完成, 可以切换状态了
+ if (weapon == null)
{
- //这里要做换弹判断, 还有上膛判断
-
+ //攻击结束
ChangeState(PrevState);
}
+ else if (AttackState == AiAttackEnum.AttackInterval) //攻击完成
+ {
+ if (weapon.GetAttackTimer() <= 0) //攻击冷却完成
+ {
+ //这里要做换弹判断, 还有上膛判断
+ if (weapon.CurrAmmo <= 0) //换弹判断
+ {
+ if (!weapon.Reloading)
+ {
+ weapon.Reload();
+ }
+ }
+ else if (weapon.GetBeLoadedStateState() != 2) //上膛
+ {
+ if (weapon.GetBeLoadedStateState() == 0)
+ {
+ weapon.BeLoaded();
+ }
+ }
+ else
+ {
+ //攻击结束
+ ChangeState(PrevState);
+ }
+ }
+ MoveHandler(delta);
+ }
else //攻击状态
{
- //这里还要做是否在视野内的判断
-
- Master.LookTarget = Player.Current;
//触发扳机
AttackState = Master.WeaponPack.ActiveItem.AiTriggerAttackState();
@@ -99,7 +143,7 @@
}
else //正常移动
{
- Master.DoMove();
+ MoveHandler(delta);
}
}
else
@@ -134,9 +178,87 @@
}
else //正常移动
{
- Master.DoMove();
+ MoveHandler(delta);
}
}
}
}
+
+ private void MoveHandler(float delta)
+ {
+
+ if (_pauseTimer >= 0)
+ {
+ Master.AnimatedSprite.Play(AnimatorNames.Idle);
+ _pauseTimer -= delta;
+ }
+ else if (_isMoveOver) //移动已经完成
+ {
+ RunOver(Player.Current.Position);
+ _isMoveOver = false;
+ }
+ else
+ {
+ var masterPosition = Master.Position;
+ if (_lockTimer >= 1) //卡在一个点超过一秒
+ {
+ RunOver(Player.Current.Position);
+ _isMoveOver = false;
+ _lockTimer = 0;
+ }
+ else if (Master.NavigationAgent2D.IsNavigationFinished()) //到达终点
+ {
+ _pauseTimer = Utils.Random.RandomRangeFloat(0f, 0.5f);
+ _isMoveOver = true;
+ _moveFlag = false;
+ //站立
+ Master.DoIdle();
+ }
+ else if (!_moveFlag)
+ {
+ _moveFlag = true;
+ //移动
+ Master.DoMove();
+ }
+ else
+ {
+ var lastSlideCollision = Master.GetLastSlideCollision();
+ if (lastSlideCollision != null && lastSlideCollision.GetCollider() is AdvancedRole) //碰到其他角色
+ {
+ _pauseTimer = Utils.Random.RandomRangeFloat(0f, 0.3f);
+ _isMoveOver = true;
+ _moveFlag = false;
+ //站立
+ Master.DoIdle();
+ }
+ else
+ {
+ //移动
+ Master.DoMove();
+ }
+
+ if (_prevPos.DistanceSquaredTo(masterPosition) <= 1 * delta)
+ {
+ _lockTimer += delta;
+ }
+ else
+ {
+ _lockTimer = 0;
+ _prevPos = masterPosition;
+ }
+ }
+ }
+ }
+
+ private void RunOver(Vector2 targetPos)
+ {
+ var weapon = Master.WeaponPack.ActiveItem;
+ var distance = (int)(weapon == null ? 150 : (Utils.GetConfigRangeStart(weapon.Attribute.Bullet.DistanceRange) * 0.7f));
+ _nextPosition = new Vector2(
+ targetPos.X + Utils.Random.RandomRangeInt(-distance, distance),
+ targetPos.Y + Utils.Random.RandomRangeInt(-distance, distance)
+ );
+ Master.NavigationAgent2D.TargetPosition = _nextPosition;
+ }
+
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs b/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs
index 8d9fc25..9a2fd78 100644
--- a/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs
+++ b/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs
@@ -604,7 +604,7 @@
//自动上膛
if (_beLoadedState == -1)
{
- BeLoadedHandler();
+ BeLoaded();
}
}
}
@@ -733,7 +733,7 @@
else if (_attackTimer <= 0)
{
//触发上膛操作
- BeLoadedHandler();
+ BeLoaded();
}
}
}
@@ -1217,7 +1217,7 @@
///
public void Reload()
{
- if (CurrAmmo < Attribute.AmmoCapacity && ResidueAmmo > 0 && !Reloading && _beLoadedState != 1)
+ if (!Reloading && CurrAmmo < Attribute.AmmoCapacity && ResidueAmmo > 0 && _beLoadedState != 1)
{
Reloading = true;
_playReloadFinishSoundFlag = false;
@@ -1271,6 +1271,59 @@
_reloadTimer = 0;
_reloadUseTime = 0;
}
+
+ ///
+ /// 触发上膛
+ ///
+ public void BeLoaded()
+ {
+ if (_beLoadedState > 0)
+ {
+ return;
+ }
+ //上膛抛弹
+ if (!Attribute.ReloadThrowShell && !Attribute.ContinuousShoot && Attribute.BeLoadedTime > 0)
+ {
+ ThrowShellHandler(0.6f);
+ }
+
+ //开始上膛
+ OnBeginBeLoaded();
+
+ //上膛时间为0, 直接结束上膛
+ if (Attribute.BeLoadedTime <= 0)
+ {
+ //直接上膛完成
+ _beLoadedState = 2;
+ OnBeLoadedFinish();
+ return;
+ }
+
+ //上膛中
+ _beLoadedState = 1;
+ _beLoadedStateTimer = Attribute.BeLoadedTime;
+
+ //播放上膛动画
+ if (IsAutoPlaySpriteFrames)
+ {
+ if (Attribute.BeLoadedSoundDelayTime <= 0)
+ {
+ PlaySpriteAnimation(AnimatorNames.BeLoaded);
+ PlayAnimationPlayer(AnimatorNames.BeLoaded);
+ }
+ else
+ {
+ this.CallDelay(Attribute.BeLoadedSoundDelayTime, () =>
+ {
+ PlaySpriteAnimation(AnimatorNames.BeLoaded);
+ PlayAnimationPlayer(AnimatorNames.BeLoaded);
+ });
+ }
+ }
+
+ //播放上膛音效
+ PlayBeLoadedSound();
+ }
//播放换弹开始音效
private void PlayBeginReloadSound()
@@ -1346,7 +1399,7 @@
if (_attackTimer <= 0)
{
//执行自动上膛
- BeLoadedHandler();
+ BeLoaded();
}
else if (CurrAmmo > 0)
{
@@ -1421,53 +1474,6 @@
OnAloneReloadStateFinish();
}
- //上膛处理
- private void BeLoadedHandler()
- {
- //上膛抛弹
- if (!Attribute.ReloadThrowShell && !Attribute.ContinuousShoot && Attribute.BeLoadedTime > 0)
- {
- ThrowShellHandler(0.6f);
- }
-
- //开始上膛
- OnBeginBeLoaded();
-
- //上膛时间为0, 直接结束上膛
- if (Attribute.BeLoadedTime <= 0)
- {
- //直接上膛完成
- _beLoadedState = 2;
- OnBeLoadedFinish();
- return;
- }
-
- //上膛中
- _beLoadedState = 1;
- _beLoadedStateTimer = Attribute.BeLoadedTime;
-
- //播放上膛动画
- if (IsAutoPlaySpriteFrames)
- {
- if (Attribute.BeLoadedSoundDelayTime <= 0)
- {
- PlaySpriteAnimation(AnimatorNames.BeLoaded);
- PlayAnimationPlayer(AnimatorNames.BeLoaded);
- }
- else
- {
- this.CallDelay(Attribute.BeLoadedSoundDelayTime, () =>
- {
- PlaySpriteAnimation(AnimatorNames.BeLoaded);
- PlayAnimationPlayer(AnimatorNames.BeLoaded);
- });
- }
- }
-
- //播放上膛音效
- PlayBeLoadedSound();
- }
-
//抛弹逻辑
private void ThrowShellHandler(float speedScale)
{
@@ -1945,7 +1951,7 @@
flag = AiAttackEnum.AttackInterval;
if (_attackTimer <= 0)
{
- Master.Attack();
+ BeLoaded();
}
}
else if (_beLoadedState == 1) //上膛中