diff --git a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs index 6bce8d2..5a916fb 100644 --- a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs +++ b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs @@ -69,7 +69,7 @@ /// /// 当前物体归属的区域, 如果为 null 代表不属于任何一个区域 /// - public AffiliationArea Affiliation + public AffiliationArea AffiliationArea { get => _affiliationArea; set @@ -1033,9 +1033,9 @@ arr[i].Value?.Destroy(); } - if (Affiliation != null) + if (AffiliationArea != null) { - Affiliation.RemoveItem(this); + AffiliationArea.RemoveItem(this); } //临时处理, 4.0 有bug, 不能提前销毁模板实例, 不然关闭游戏会报错!!! diff --git a/DungeonShooting_Godot/src/framework/activity/components/StateBase.cs b/DungeonShooting_Godot/src/framework/activity/components/StateBase.cs index da0095a..c936b6f 100644 --- a/DungeonShooting_Godot/src/framework/activity/components/StateBase.cs +++ b/DungeonShooting_Godot/src/framework/activity/components/StateBase.cs @@ -77,16 +77,16 @@ /// /// 立即切换到下一个指定状态, 并且这一帧会被调用 PhysicsProcess /// - public void ChangeState(S next, params object[] args) + public void ChangeStateInstant(S next, params object[] args) { - StateController.ChangeState(next, args); + StateController.ChangeStateInstant(next, args); } /// /// 切换到下一个指定状态, 下一帧才会调用 PhysicsProcess /// - public void ChangeStateLate(S next, params object[] args) + public void ChangeState(S next, params object[] args) { - StateController.ChangeStateLate(next, args); + StateController.ChangeState(next, args); } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/framework/activity/components/StateController.cs b/DungeonShooting_Godot/src/framework/activity/components/StateController.cs index 59ab805..ca379b4 100644 --- a/DungeonShooting_Godot/src/framework/activity/components/StateController.cs +++ b/DungeonShooting_Godot/src/framework/activity/components/StateController.cs @@ -89,7 +89,7 @@ /// /// 立即切换到下一个指定状态, 并且这一帧会被调用 PhysicsProcess /// - public void ChangeState(S next, params object[] arg) + public void ChangeStateInstant(S next, params object[] arg) { _changeState(false, next, arg); } @@ -97,7 +97,7 @@ /// /// 切换到下一个指定状态, 下一帧才会调用 PhysicsProcess /// - public void ChangeStateLate(S next, params object[] arg) + public void ChangeState(S next, params object[] arg) { _changeState(true, next, arg); } diff --git a/DungeonShooting_Godot/src/framework/map/AffiliationArea.cs b/DungeonShooting_Godot/src/framework/map/AffiliationArea.cs index 081378c..6b0ae6d 100644 --- a/DungeonShooting_Godot/src/framework/map/AffiliationArea.cs +++ b/DungeonShooting_Godot/src/framework/map/AffiliationArea.cs @@ -62,16 +62,16 @@ /// public void InsertItem(ActivityObject activityObject) { - if (activityObject.Affiliation == this) + if (activityObject.AffiliationArea == this) { return; } - if (activityObject.Affiliation != null) + if (activityObject.AffiliationArea != null) { _includeItems.Remove(activityObject); } - activityObject.Affiliation = this; + activityObject.AffiliationArea = this; _includeItems.Add(activityObject); //如果是玩家 @@ -86,11 +86,11 @@ /// public void RemoveItem(ActivityObject activityObject) { - if (activityObject.Affiliation == null) + if (activityObject.AffiliationArea == null) { return; } - activityObject.Affiliation = null; + activityObject.AffiliationArea = null; _includeItems.Remove(activityObject); } @@ -135,6 +135,23 @@ } return list.ToArray(); } + + /// + /// 检查是否有符合条件的对象 + /// + /// 操作函数, 返回是否满足要求 + public bool ExistIncludeItem(Func handler) + { + foreach (var activityObject in _includeItems) + { + if (handler(activityObject)) + { + return true; + } + } + + return false; + } private void OnBodyEntered(Node2D body) { diff --git a/DungeonShooting_Godot/src/framework/map/RoomInfo.cs b/DungeonShooting_Godot/src/framework/map/RoomInfo.cs index 5758a36..c086079 100644 --- a/DungeonShooting_Godot/src/framework/map/RoomInfo.cs +++ b/DungeonShooting_Godot/src/framework/map/RoomInfo.cs @@ -204,7 +204,7 @@ /// public void OnClearRoom() { - if (_currWaveIndex >= ActivityMarks.Count) //所有 mark 全部走完了 + if (_currWaveIndex >= ActivityMarks.Count) //所有 mark 都走完了 { IsSeclusion = false; _currActivityMarks.Clear(); diff --git a/DungeonShooting_Godot/src/game/role/Role.cs b/DungeonShooting_Godot/src/game/role/Role.cs index e0d2113..a887416 100644 --- a/DungeonShooting_Godot/src/game/role/Role.cs +++ b/DungeonShooting_Godot/src/game/role/Role.cs @@ -323,13 +323,13 @@ //身上的武器的所属区域也得跟着变 Holster.ForEach((weapon, i) => { - if (Affiliation != null) + if (AffiliationArea != null) { - Affiliation.InsertItem(weapon); + AffiliationArea.InsertItem(weapon); } - else if (weapon.Affiliation != null) + else if (weapon.AffiliationArea != null) { - weapon.Affiliation.RemoveItem(weapon); + weapon.AffiliationArea.RemoveItem(weapon); } }); } diff --git a/DungeonShooting_Godot/src/game/role/enemy/Enemy.cs b/DungeonShooting_Godot/src/game/role/enemy/Enemy.cs index ca1a00a..9d02d1f 100644 --- a/DungeonShooting_Godot/src/game/role/enemy/Enemy.cs +++ b/DungeonShooting_Godot/src/game/role/enemy/Enemy.cs @@ -91,7 +91,7 @@ StateController.Register(new AiFindAmmoState()); //默认状态 - StateController.ChangeState(AiStateEnum.AiNormal); + StateController.ChangeStateInstant(AiStateEnum.AiNormal); } public override void _EnterTree() @@ -162,7 +162,7 @@ var state = StateController.CurrState; if (state == AiStateEnum.AiNormal || state == AiStateEnum.AiProbe || state == AiStateEnum.AiLeaveFor) { - StateController.ChangeStateLate(AiStateEnum.AiTailAfter); + StateController.ChangeState(AiStateEnum.AiTailAfter); } } @@ -174,7 +174,7 @@ foreach (var unclaimedWeapon in World.Weapon_UnclaimedWeapons) { //判断是否能拾起武器, 条件: 相同的房间 - if (unclaimedWeapon.Affiliation == Affiliation) + if (unclaimedWeapon.AffiliationArea == AffiliationArea) { if (!unclaimedWeapon.IsTotalAmmoEmpty()) { @@ -214,7 +214,7 @@ foreach (var weapon in World.Weapon_UnclaimedWeapons) { //判断是否能拾起武器, 条件: 相同的房间, 或者当前房间目前没有战斗, 或者不在战斗房间 - if (weapon.Affiliation == Affiliation) + if (weapon.AffiliationArea == AffiliationArea) { //还有弹药 if (!weapon.IsTotalAmmoEmpty()) @@ -272,7 +272,7 @@ if (currState == AiStateEnum.AiNormal || currState == AiStateEnum.AiProbe) { //判断是否在同一个房间内 - return World.Enemy_FindTargetAffiliationSet.Contains(Affiliation); + return World.Enemy_FindTargetAffiliationSet.Contains(AffiliationArea); } return false; diff --git a/DungeonShooting_Godot/src/game/role/enemy/state/AiFindAmmoState.cs b/DungeonShooting_Godot/src/game/role/enemy/state/AiFindAmmoState.cs index bc00378..9cfb3c6 100644 --- a/DungeonShooting_Godot/src/game/role/enemy/state/AiFindAmmoState.cs +++ b/DungeonShooting_Godot/src/game/role/enemy/state/AiFindAmmoState.cs @@ -25,7 +25,7 @@ if (args.Length == 0) { GD.PrintErr("进入 AiStateEnum.AiFindAmmo 状态必须要把目标武器当成参数传过来"); - ChangeStateLate(prev); + ChangeState(prev); return; } @@ -42,7 +42,7 @@ { if (!Master.IsAllWeaponTotalAmmoEmpty()) //已经有弹药了 { - ChangeStateLate(GetNextState()); + ChangeState(GetNextState()); return; } @@ -70,12 +70,12 @@ if (_target == null) //也没有其他可用的武器了 { - ChangeStateLate(GetNextState()); + ChangeState(GetNextState()); } } else if (_target.Master == Master) //已经被自己拾起 { - ChangeStateLate(GetNextState()); + ChangeState(GetNextState()); } else if (_target.Master != null) //武器已经被其他角色拾起! { @@ -84,7 +84,7 @@ if (_target == null) //也没有其他可用的武器了 { - ChangeStateLate(GetNextState()); + ChangeState(GetNextState()); } } else diff --git a/DungeonShooting_Godot/src/game/role/enemy/state/AiFollowUpState.cs b/DungeonShooting_Godot/src/game/role/enemy/state/AiFollowUpState.cs index ee828ad..725ddcb 100644 --- a/DungeonShooting_Godot/src/game/role/enemy/state/AiFollowUpState.cs +++ b/DungeonShooting_Godot/src/game/role/enemy/state/AiFollowUpState.cs @@ -35,13 +35,13 @@ var targetWeapon = Master.FindTargetWeapon(); if (targetWeapon != null) { - ChangeStateLate(AiStateEnum.AiFindAmmo, targetWeapon); + ChangeState(AiStateEnum.AiFindAmmo, targetWeapon); return; } else { //切换到随机移动状态 - ChangeStateLate(AiStateEnum.AiSurround); + ChangeState(AiStateEnum.AiSurround); } } @@ -108,13 +108,13 @@ //距离够近, 可以切换到环绕模式 if (Master.GlobalPosition.DistanceSquaredTo(playerPos) <= Mathf.Pow(weapon.Attribute.MinDistance, 2) * 0.7f) { - ChangeStateLate(AiStateEnum.AiSurround); + ChangeState(AiStateEnum.AiSurround); } } } else { - ChangeStateLate(AiStateEnum.AiTailAfter); + ChangeState(AiStateEnum.AiTailAfter); } } diff --git a/DungeonShooting_Godot/src/game/role/enemy/state/AiLeaveForState.cs b/DungeonShooting_Godot/src/game/role/enemy/state/AiLeaveForState.cs index 96e90b5..8185484 100644 --- a/DungeonShooting_Godot/src/game/role/enemy/state/AiLeaveForState.cs +++ b/DungeonShooting_Godot/src/game/role/enemy/state/AiLeaveForState.cs @@ -18,11 +18,11 @@ { if (Master.World.Enemy_IsFindTarget) { - Master.NavigationAgent2D.TargetPosition = Master.World.EnemyFindTargetPosition; + Master.NavigationAgent2D.TargetPosition = Master.World.Enemy_FindTargetPosition; } else { - ChangeStateLate(prev); + ChangeState(prev); return; } @@ -33,7 +33,7 @@ var targetWeapon = Master.FindTargetWeapon(); if (targetWeapon != null) { - ChangeStateLate(AiStateEnum.AiFindAmmo, targetWeapon); + ChangeState(AiStateEnum.AiFindAmmo, targetWeapon); } } } @@ -47,7 +47,7 @@ { //每隔一段时间秒更改目标位置 _navigationUpdateTimer = _navigationInterval; - Master.NavigationAgent2D.TargetPosition = Master.World.EnemyFindTargetPosition; + Master.NavigationAgent2D.TargetPosition = Master.World.Enemy_FindTargetPosition; } else { @@ -58,7 +58,7 @@ { //计算移动 var nextPos = Master.NavigationAgent2D.GetNextPathPosition(); - Master.LookTargetPosition(Master.World.EnemyFindTargetPosition); + Master.LookTargetPosition(Master.World.Enemy_FindTargetPosition); Master.AnimatedSprite.Play(AnimatorNames.Run); Master.BasisVelocity = (nextPos - Master.GlobalPosition - Master.NavigationPoint.Position).Normalized() * Master.MoveSpeed; @@ -77,7 +77,7 @@ //关闭射线检测 Master.TestViewRayCastOver(); //切换成发现目标状态 - ChangeStateLate(AiStateEnum.AiFollowUp); + ChangeState(AiStateEnum.AiFollowUp); return; } else @@ -90,7 +90,7 @@ //移动到目标掉了, 还没发现目标 if (Master.NavigationAgent2D.IsNavigationFinished()) { - ChangeStateLate(AiStateEnum.AiNormal); + ChangeState(AiStateEnum.AiNormal); } } diff --git a/DungeonShooting_Godot/src/game/role/enemy/state/AiNormalState.cs b/DungeonShooting_Godot/src/game/role/enemy/state/AiNormalState.cs index 0ebfd40..299abf0 100644 --- a/DungeonShooting_Godot/src/game/role/enemy/state/AiNormalState.cs +++ b/DungeonShooting_Godot/src/game/role/enemy/state/AiNormalState.cs @@ -49,14 +49,14 @@ //其他敌人发现玩家 if (Master.CanChangeLeaveFor()) { - ChangeStateLate(AiStateEnum.AiLeaveFor); + ChangeState(AiStateEnum.AiLeaveFor); return; } if (_isFindPlayer) //已经找到玩家了 { //现临时处理, 直接切换状态 - ChangeStateLate(AiStateEnum.AiTailAfter); + ChangeState(AiStateEnum.AiTailAfter); } else //没有找到玩家 { diff --git a/DungeonShooting_Godot/src/game/role/enemy/state/AiProbeState.cs b/DungeonShooting_Godot/src/game/role/enemy/state/AiProbeState.cs index ddbaeb5..1015095 100644 --- a/DungeonShooting_Godot/src/game/role/enemy/state/AiProbeState.cs +++ b/DungeonShooting_Godot/src/game/role/enemy/state/AiProbeState.cs @@ -13,7 +13,7 @@ //其他敌人发现玩家 if (Master.CanChangeLeaveFor()) { - ChangeStateLate(AiStateEnum.AiLeaveFor); + ChangeState(AiStateEnum.AiLeaveFor); return; } } diff --git a/DungeonShooting_Godot/src/game/role/enemy/state/AiSurroundState.cs b/DungeonShooting_Godot/src/game/role/enemy/state/AiSurroundState.cs index 64a42f6..29ce5a7 100644 --- a/DungeonShooting_Godot/src/game/role/enemy/state/AiSurroundState.cs +++ b/DungeonShooting_Godot/src/game/role/enemy/state/AiSurroundState.cs @@ -47,7 +47,7 @@ var targetWeapon = Master.FindTargetWeapon(); if (targetWeapon != null) { - ChangeStateLate(AiStateEnum.AiFindAmmo, targetWeapon); + ChangeState(AiStateEnum.AiFindAmmo, targetWeapon); return; } } @@ -142,7 +142,7 @@ var position = Master.GlobalPosition; if (position.DistanceSquaredTo(playerPos) > Mathf.Pow(Master.GetWeaponRange(0.7f), 2)) //玩家离开正常射击范围 { - ChangeStateLate(AiStateEnum.AiFollowUp); + ChangeState(AiStateEnum.AiFollowUp); } else { @@ -154,7 +154,7 @@ } else //目标离开视野 { - ChangeStateLate(AiStateEnum.AiTailAfter); + ChangeState(AiStateEnum.AiTailAfter); } } diff --git a/DungeonShooting_Godot/src/game/role/enemy/state/AiTailAfterState.cs b/DungeonShooting_Godot/src/game/role/enemy/state/AiTailAfterState.cs index 769f06f..87d018e 100644 --- a/DungeonShooting_Godot/src/game/role/enemy/state/AiTailAfterState.cs +++ b/DungeonShooting_Godot/src/game/role/enemy/state/AiTailAfterState.cs @@ -35,7 +35,7 @@ var targetWeapon = Master.FindTargetWeapon(); if (targetWeapon != null) { - ChangeStateLate(AiStateEnum.AiFindAmmo, targetWeapon); + ChangeState(AiStateEnum.AiFindAmmo, targetWeapon); } } } @@ -81,7 +81,7 @@ //关闭射线检测 Master.TestViewRayCastOver(); //切换成发现目标状态 - ChangeStateLate(AiStateEnum.AiFollowUp); + ChangeState(AiStateEnum.AiFollowUp); return; } else @@ -101,7 +101,7 @@ { if (_viewTimer > 10) //10秒 { - ChangeStateLate(AiStateEnum.AiNormal); + ChangeState(AiStateEnum.AiNormal); } else { diff --git a/DungeonShooting_Godot/src/game/room/DungeonManager.cs b/DungeonShooting_Godot/src/game/room/DungeonManager.cs index 6c99030..43875a9 100644 --- a/DungeonShooting_Godot/src/game/room/DungeonManager.cs +++ b/DungeonShooting_Godot/src/game/room/DungeonManager.cs @@ -18,12 +18,12 @@ /// /// 当前玩家所在的房间 /// - public RoomInfo ActiveRoom => Player.Current?.Affiliation?.RoomInfo; + public RoomInfo ActiveRoom => Player.Current?.AffiliationArea?.RoomInfo; /// /// 当前玩家所在的区域 /// - public AffiliationArea ActiveAffiliation => Player.Current?.Affiliation; + public AffiliationArea ActiveAffiliationArea => Player.Current?.AffiliationArea; /// /// 是否在地牢里 @@ -294,6 +294,22 @@ { var room = (RoomInfo)o; room.BeReady(); + //如果关门了, 那么房间外的敌人就会丢失目标 + if (room.IsSeclusion) + { + var playerAffiliationArea = Player.Current.AffiliationArea; + foreach (var enemy in _world.Enemy_InstanceList) + { + //不与玩家处于同一个房间 + if (enemy.AffiliationArea != playerAffiliationArea) + { + if (enemy.StateController.CurrState != AiStateEnum.AiNormal) + { + enemy.StateController.ChangeState(AiStateEnum.AiNormal); + } + } + } + } } /// @@ -315,12 +331,12 @@ { if (activeRoom.IsCurrWaveOver()) //所有标记执行完成 { - //存活敌人数量 - var count = ActiveAffiliation.FindIncludeItemsCount( + //是否有存活的敌人 + var flag = ActiveAffiliationArea.ExistIncludeItem( activityObject => activityObject.CollisionWithMask(PhysicsLayer.Enemy) ); - GD.Print("当前房间存活数量: " + count); - if (count == 0) + //GD.Print("当前房间存活数量: " + count); + if (!flag) { activeRoom.OnClearRoom(); } @@ -345,10 +361,10 @@ if (!_world.Enemy_IsFindTarget) { _world.Enemy_IsFindTarget = true; - _world.EnemyFindTargetPosition = Player.Current.GetCenterPosition(); - _world.Enemy_FindTargetAffiliationSet.Add(Player.Current.Affiliation); + _world.Enemy_FindTargetPosition = Player.Current.GetCenterPosition(); + _world.Enemy_FindTargetAffiliationSet.Add(Player.Current.AffiliationArea); } - _world.Enemy_FindTargetAffiliationSet.Add(enemy.Affiliation); + _world.Enemy_FindTargetAffiliationSet.Add(enemy.AffiliationArea); } } } diff --git a/DungeonShooting_Godot/src/game/room/World.cs b/DungeonShooting_Godot/src/game/room/World.cs index 52fa884..cb6810d 100644 --- a/DungeonShooting_Godot/src/game/room/World.cs +++ b/DungeonShooting_Godot/src/game/room/World.cs @@ -67,7 +67,7 @@ /// /// 公共属性, 敌人找到的目标的位置, 如果目标在视野内, 则一直更新 /// - public Vector2 EnemyFindTargetPosition { get; set; } + public Vector2 Enemy_FindTargetPosition { get; set; } private bool _pause = false;