diff --git a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/battle/Battle1/Preinstall.json b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/battle/Battle1/Preinstall.json index fa1a899..67fa184 100644 --- a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/battle/Battle1/Preinstall.json +++ b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/battle/Battle1/Preinstall.json @@ -1 +1 @@ -[{"Name":"test1","Weight":100,"Remark":"","WaveList":[[{"Position":{"X":-4,"Y":-6},"Size":{"X":30,"Y":26},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Face":"0","Weapon":"weapon0002","CurrAmmon":"7","ResidueAmmo":"7"},"Altitude":0,"VerticalSpeed":0}]},{"Position":{"X":38,"Y":48},"Size":{"X":31,"Y":25},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Face":"0","Weapon":"weapon0002","CurrAmmon":"7","ResidueAmmo":"7"},"Altitude":0,"VerticalSpeed":0}]}]]}] \ No newline at end of file +[{"Name":"test1","Weight":100,"Remark":"","WaveList":[[{"Position":{"X":-4,"Y":-6},"Size":{"X":30,"Y":26},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Face":"0","Weapon":"weapon0002","CurrAmmon":"7","ResidueAmmo":"7"},"Altitude":0,"VerticalSpeed":0}]},{"Position":{"X":38,"Y":48},"Size":{"X":31,"Y":25},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Face":"0","Weapon":"weapon0002","CurrAmmon":"7","ResidueAmmo":"7"},"Altitude":0,"VerticalSpeed":0}]}],[{"Position":{"X":38,"Y":-3},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Face":"0","Weapon":"weapon0007","CurrAmmon":"60","ResidueAmmo":"60"},"Altitude":0,"VerticalSpeed":0}]}],[{"Position":{"X":-9,"Y":38},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Face":"0","Weapon":"weapon0007","CurrAmmon":"60","ResidueAmmo":"60"},"Altitude":0,"VerticalSpeed":0}]}]]}] \ No newline at end of file diff --git a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start1/Preinstall.json b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start1/Preinstall.json index 2a652fa..0bb0387 100644 --- a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start1/Preinstall.json +++ b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start1/Preinstall.json @@ -1 +1 @@ -[{"Name":"test1","Weight":100,"Remark":"","WaveList":[[{"Position":{"X":8,"Y":19},"Size":{"X":0,"Y":0},"SpecialMarkType":1,"DelayTime":0,"MarkList":[]},{"Position":{"X":8,"Y":19},"Size":{"X":83,"Y":73},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0001","Weight":100,"Attr":{"CurrAmmon":"30","ResidueAmmo":"210"},"Altitude":8,"VerticalSpeed":0}]}]]}] \ No newline at end of file +[{"Name":"test1","Weight":100,"Remark":"","WaveList":[[{"Position":{"X":8,"Y":19},"Size":{"X":0,"Y":0},"SpecialMarkType":1,"DelayTime":0,"MarkList":[]},{"Position":{"X":8,"Y":19},"Size":{"X":83,"Y":73},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0001","Weight":100,"Attr":{"CurrAmmon":"30","ResidueAmmo":"210"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":8,"Y":36},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0003","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]}]]}] \ No newline at end of file diff --git a/DungeonShooting_Godot/src/framework/map/AffiliationArea.cs b/DungeonShooting_Godot/src/framework/map/AffiliationArea.cs index 78ebfd9..40c0c4a 100644 --- a/DungeonShooting_Godot/src/framework/map/AffiliationArea.cs +++ b/DungeonShooting_Godot/src/framework/map/AffiliationArea.cs @@ -6,17 +6,24 @@ /// /// 归属区域 /// -public partial class AffiliationArea : Area2D +public partial class AffiliationArea : Area2D, IDestroy { + public bool IsDestroyed { get; private set; } + /// /// 当前实例所属房间 /// public RoomInfo RoomInfo; /// - /// 当前归属区域包含的所有物体对象 + /// 当前归属区域包含的所有物体对象, 物体进入另一个区域时才会从该集合中移除 /// private readonly HashSet _includeItems = new HashSet(); + + /// + /// 已经进入 AffiliationArea 所在范围内的物体, 物体一旦离开该区域就会立刻从该集合中删除 + /// + private readonly HashSet _enterItems = new HashSet(); /// /// 玩家是否是第一次进入 @@ -55,6 +62,7 @@ CollisionMask = PhysicsLayer.Prop | PhysicsLayer.Player | PhysicsLayer.Enemy | PhysicsLayer.Shell | PhysicsLayer.Throwing; BodyEntered += OnBodyEntered; + BodyExited += OnBodyExited; } /// @@ -153,14 +161,90 @@ return false; } + /// + /// 获取进入该区域中物体的总数 + /// + public int GetEnterItemsCount() + { + return _enterItems.Count; + } + + /// + /// 统计进入该区域且符合条件的数量 + /// + /// 操作函数, 返回是否满足要求 + public int FindEnterItemsCount(Func handler) + { + var count = 0; + foreach (var activityObject in _enterItems) + { + if (!activityObject.IsDestroyed && handler(activityObject)) + { + count++; + } + } + return count; + } + + /// + /// 查询所有进入该区域且符合条件的对象并返回 + /// + /// 操作函数, 返回是否满足要求 + public ActivityObject[] FindEnterItems(Func handler) + { + var list = new List(); + foreach (var activityObject in _enterItems) + { + if (!activityObject.IsDestroyed && handler(activityObject)) + { + list.Add(activityObject); + } + } + return list.ToArray(); + } + + /// + /// 检查是否有进入该区域且符合条件的对象 + /// + /// 操作函数, 返回是否满足要求 + public bool ExistEnterItem(Func handler) + { + foreach (var activityObject in _enterItems) + { + if (!activityObject.IsDestroyed && handler(activityObject)) + { + return true; + } + } + + return false; + } + + /// + /// 返回物体是否进入了该区域 + /// + public bool IsEnter(ActivityObject activityObject) + { + return _enterItems.Contains(activityObject); + } + private void OnBodyEntered(Node2D body) { if (body is ActivityObject activityObject) { + _enterItems.Add(activityObject); //注意需要延时调用 CallDeferred(nameof(InsertItem), activityObject); } } + + private void OnBodyExited(Node2D body) + { + if (body is ActivityObject activityObject) + { + _enterItems.Remove(activityObject); + } + } //玩家进入房间 private void OnPlayerEnterRoom() @@ -172,4 +256,18 @@ } EventManager.EmitEvent(EventEnum.OnPlayerEnterRoom, RoomInfo); } + + + public void Destroy() + { + if (IsDestroyed) + { + return; + } + + IsDestroyed = true; + QueueFree(); + _includeItems.Clear(); + _enterItems.Clear(); + } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/framework/map/preinstall/RoomPreinstall.cs b/DungeonShooting_Godot/src/framework/map/preinstall/RoomPreinstall.cs index edc96e5..f26b489 100644 --- a/DungeonShooting_Godot/src/framework/map/preinstall/RoomPreinstall.cs +++ b/DungeonShooting_Godot/src/framework/map/preinstall/RoomPreinstall.cs @@ -1,6 +1,4 @@  - -using System; using System.Collections; using System.Collections.Generic; using System.Linq; @@ -195,18 +193,26 @@ } IsRunWave = true; + _currWaveIndex = 1; - if (_currWaveIndex < WaveList.Count) + //判断房间内是否已经有敌人了, 没有才能执行第1波 + var flag = RoomInfo.AffiliationArea.ExistEnterItem( + activityObject => activityObject.CollisionWithMask(PhysicsLayer.Enemy) + ); + if (!flag) { - GD.Print("执行第一波"); - _coroutineId = GameApplication.Instance.StartCoroutine(RunMark(WaveList[_currWaveIndex])); - _currWaveIndex++; + if (_currWaveIndex < WaveList.Count) + { + GD.Print($"执行第{_currWaveIndex}波"); + _coroutineId = GameApplication.Instance.StartCoroutine(RunMark(WaveList[_currWaveIndex])); + _currWaveIndex++; + } } } public void NextWave() { - GD.Print("执行下一波, 当前: " + _currWaveIndex); + GD.Print($"执行第{_currWaveIndex}波"); _coroutineId = GameApplication.Instance.StartCoroutine(RunMark(WaveList[_currWaveIndex])); _currWaveIndex++; } diff --git a/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs b/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs index 6f69973..0d80a2b 100644 --- a/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs +++ b/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs @@ -184,6 +184,8 @@ { StaticImageCanvas.Destroy(); } + + AffiliationArea.Destroy(); } /// diff --git a/DungeonShooting_Godot/src/game/room/DungeonManager.cs b/DungeonShooting_Godot/src/game/room/DungeonManager.cs index 1762c28..201fe24 100644 --- a/DungeonShooting_Godot/src/game/room/DungeonManager.cs +++ b/DungeonShooting_Godot/src/game/room/DungeonManager.cs @@ -526,8 +526,8 @@ { if (activeRoom.IsCurrWaveOver()) //所有标记执行完成 { - //是否有存活的敌人 - var flag = ActiveAffiliationArea.ExistIncludeItem( + //房间内是否有存活的敌人 + var flag = ActiveAffiliationArea.ExistEnterItem( activityObject => activityObject.CollisionWithMask(PhysicsLayer.Enemy) ); //GD.Print("当前房间存活数量: " + count);