diff --git a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/battle/Room1/Room1_preinstall.json b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/battle/Room1/Room1_preinstall.json
index 2d774c3..e2c67d6 100644
--- a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/battle/Room1/Room1_preinstall.json
+++ b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/battle/Room1/Room1_preinstall.json
@@ -1 +1 @@
-[{"Name":"test1","Weight":100,"Remark":"","WaveList":[[{"Position":{"X":-11,"Y":-85},"Size":{"X":110,"Y":27},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0001","Weight":100,"Attr":{"CurrAmmon":"30","ResidueAmmo":"210"}}]},{"Position":{"X":64,"Y":27},"Size":{"X":94,"Y":60},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0003","Weight":100,"Attr":{"CurrAmmon":"12","ResidueAmmo":"90"}},{"Id":"weapon0006","Weight":100,"Attr":{"CurrAmmon":"20","ResidueAmmo":"300"}}]}],[{"Position":{"X":-26,"Y":-13},"Size":{"X":76,"Y":10},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0007","Weight":200,"Attr":{"CurrAmmon":"60","ResidueAmmo":"300"}},{"Id":"enemy0001","Weight":50,"Attr":{"Weapon":"weapon0006","CurrAmmon":"20","ResidueAmmo":"20"}}]}]]},{"Name":"test2","Weight":200,"Remark":"","WaveList":[[{"Position":{"X":24,"Y":-46},"Size":{"X":16,"Y":94},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop5000","Weight":30,"Attr":null},{"Id":"prop0005","Weight":90,"Attr":null}]}],[{"Position":{"X":67,"Y":27},"Size":{"X":85,"Y":48},"SpecialMarkType":0,"DelayTime":1,"MarkList":[{"Id":"enemy0001","Weight":60,"Attr":{"Weapon":"weapon0001","CurrAmmon":"30","ResidueAmmo":"30"}},{"Id":"enemy0001","Weight":100,"Attr":{"Weapon":"weapon0003","CurrAmmon":"12","ResidueAmmo":"12"}}]}]]}]
\ No newline at end of file
+[{"Name":"test1","Weight":100,"Remark":"","WaveList":[[{"Position":{"X":-11,"Y":-85},"Size":{"X":110,"Y":27},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0001","Weight":100,"Attr":{"CurrAmmon":"30","ResidueAmmo":"210"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":64,"Y":27},"Size":{"X":94,"Y":60},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0003","Weight":100,"Attr":{"CurrAmmon":"12","ResidueAmmo":"90"},"Altitude":8,"VerticalSpeed":0},{"Id":"weapon0006","Weight":100,"Attr":{"CurrAmmon":"20","ResidueAmmo":"300"},"Altitude":8,"VerticalSpeed":0}]}],[{"Position":{"X":-26,"Y":-13},"Size":{"X":76,"Y":10},"SpecialMarkType":0,"DelayTime":2.5,"MarkList":[{"Id":"weapon0007","Weight":100,"Attr":{"CurrAmmon":"60","ResidueAmmo":"300"},"Altitude":8,"VerticalSpeed":0},{"Id":"enemy0001","Weight":100,"Attr":{"Weapon":"weapon0005","CurrAmmon":"10","ResidueAmmo":"10"},"Altitude":0,"VerticalSpeed":0}]},{"Position":{"X":25,"Y":-40},"Size":{"X":16,"Y":92},"SpecialMarkType":0,"DelayTime":1,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Weapon":"weapon0006","CurrAmmon":"20","ResidueAmmo":"20"},"Altitude":0,"VerticalSpeed":0}]},{"Position":{"X":82,"Y":27},"Size":{"X":64,"Y":45},"SpecialMarkType":0,"DelayTime":3.5,"MarkList":[{"Id":"weapon0007","Weight":100,"Attr":{"CurrAmmon":"60","ResidueAmmo":"300"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":97,"Y":-132},"Size":{"X":31,"Y":60},"SpecialMarkType":0,"DelayTime":5,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Weapon":null},"Altitude":0,"VerticalSpeed":0}]}],[{"Position":{"X":32,"Y":35},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Weapon":"weapon0005","CurrAmmon":"10","ResidueAmmo":"10"},"Altitude":0,"VerticalSpeed":0}]},{"Position":{"X":86,"Y":-113},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":3,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Weapon":null},"Altitude":0,"VerticalSpeed":0}]},{"Position":{"X":-56,"Y":-145},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":4,"MarkList":[{"Id":"weapon0001","Weight":100,"Attr":{"CurrAmmon":"30","ResidueAmmo":"210"},"Altitude":8,"VerticalSpeed":0}]}]]}]
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/battle/Room2/Room2_preinstall.json b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/battle/Room2/Room2_preinstall.json
index 0637a08..70a6dd1 100644
--- a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/battle/Room2/Room2_preinstall.json
+++ b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/battle/Room2/Room2_preinstall.json
@@ -1 +1 @@
-[]
\ No newline at end of file
+[{"Name":"test1","Weight":100,"Remark":"","WaveList":[[],[{"Position":{"X":39,"Y":-36},"Size":{"X":86,"Y":90},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Weapon":"weapon0005","CurrAmmon":"10","ResidueAmmo":"10"}},{"Id":"enemy0001","Weight":100,"Attr":{"Weapon":"weapon0003","CurrAmmon":"12","ResidueAmmo":"12"}}]},{"Position":{"X":-58,"Y":62},"Size":{"X":103,"Y":73},"SpecialMarkType":0,"DelayTime":3,"MarkList":[{"Id":"enemy0001","Weight":100,"Attr":{"Weapon":"weapon0006","CurrAmmon":"20","ResidueAmmo":"20"}}]}]]}]
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/battle/Room2/Room2_roomInfo.json b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/battle/Room2/Room2_roomInfo.json
index ed74cc0..1cdb937 100644
--- a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/battle/Room2/Room2_roomInfo.json
+++ b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/battle/Room2/Room2_roomInfo.json
@@ -1 +1 @@
-{"Position":{"X":-12,"Y":-8},"Size":{"X":22,"Y":17},"DoorAreaInfos":[{"Direction":3,"Start":0,"End":320},{"Direction":0,"Start":0,"End":240},{"Direction":2,"Start":0,"End":320},{"Direction":1,"Start":0,"End":240}],"GroupName":"TestGroup1","RoomType":0,"RoomName":"Room2","Weight":100,"Remark":""}
\ No newline at end of file
+{"Position":{"X":-12,"Y":-8},"Size":{"X":22,"Y":17},"DoorAreaInfos":[],"GroupName":"TestGroup1","RoomType":0,"RoomName":"Room2","Weight":100,"Remark":""}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start1/Start1_preinstall.json b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start1/Start1_preinstall.json
index 362fdb1..78ec481 100644
--- a/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start1/Start1_preinstall.json
+++ b/DungeonShooting_Godot/resource/map/tileMaps/TestGroup1/inlet/Start1/Start1_preinstall.json
@@ -1 +1 @@
-[{"Name":"test1","Weight":100,"Remark":"","WaveList":[[{"Position":{"X":137,"Y":137},"Size":{"X":0,"Y":0},"SpecialMarkType":1,"DelayTime":0,"MarkList":[]}]]}]
\ No newline at end of file
+[{"Name":"test1","Weight":100,"Remark":"","WaveList":[[{"Position":{"X":137,"Y":137},"Size":{"X":0,"Y":0},"SpecialMarkType":1,"DelayTime":0,"MarkList":[]}],[{"Position":{"X":135,"Y":114},"Size":{"X":179,"Y":90},"SpecialMarkType":0,"DelayTime":2,"MarkList":[{"Id":"weapon0001","Weight":100,"Attr":{"CurrAmmon":"30","ResidueAmmo":"210"},"Altitude":8,"VerticalSpeed":0}]}]]}]
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs
index 4bcc34f..5e747d7 100644
--- a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs
+++ b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs
@@ -1417,7 +1417,12 @@
{
ProxyCoroutineHandler.ProxyStopCoroutine(ref _coroutineList, coroutineId);
}
-
+
+ public bool IsCoroutineOver(long coroutineId)
+ {
+ return ProxyCoroutineHandler.ProxyIsCoroutineOver(ref _coroutineList, coroutineId);
+ }
+
public void StopAllCoroutine()
{
ProxyCoroutineHandler.ProxyStopAllCoroutine(ref _coroutineList);
diff --git a/DungeonShooting_Godot/src/framework/coroutine/ICoroutine.cs b/DungeonShooting_Godot/src/framework/coroutine/ICoroutine.cs
index 4f57206..d5fe772 100644
--- a/DungeonShooting_Godot/src/framework/coroutine/ICoroutine.cs
+++ b/DungeonShooting_Godot/src/framework/coroutine/ICoroutine.cs
@@ -17,6 +17,11 @@
public void StopCoroutine(long coroutineId);
///
+ /// 根据协程 id 判断该协程是否结束
+ ///
+ public bool IsCoroutineOver(long coroutineId);
+
+ ///
/// 停止所有协程
///
public void StopAllCoroutine();
diff --git a/DungeonShooting_Godot/src/framework/coroutine/ProxyCoroutineHandler.cs b/DungeonShooting_Godot/src/framework/coroutine/ProxyCoroutineHandler.cs
index 1d66289..5fd2b36 100644
--- a/DungeonShooting_Godot/src/framework/coroutine/ProxyCoroutineHandler.cs
+++ b/DungeonShooting_Godot/src/framework/coroutine/ProxyCoroutineHandler.cs
@@ -1,4 +1,5 @@
+using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
@@ -17,111 +18,118 @@
var pairs = coroutineList.ToArray();
for (var i = 0; i < pairs.Length; i++)
{
- var item = pairs[i];
- var canNext = true;
+ try
+ {
+ var item = pairs[i];
+ var canNext = true;
- if (item.WaitState == CoroutineData.WaitTypeEnum.WaitForSeconds) //等待秒数
- {
- if (!item.WaitForSeconds.NextStep(delta))
+ if (item.WaitState == CoroutineData.WaitTypeEnum.WaitForSeconds) //等待秒数
{
- canNext = false;
- }
- else
- {
- item.WaitState = CoroutineData.WaitTypeEnum.None;
- item.WaitForSeconds = null;
- }
- }
- else if (item.WaitState == CoroutineData.WaitTypeEnum.WaitForFixedProcess) //等待帧数
- {
- if (!item.WaitForFixedProcess.NextStep())
- {
- canNext = false;
- }
- else
- {
- item.WaitState = CoroutineData.WaitTypeEnum.None;
- item.WaitForFixedProcess = null;
- }
- }
- else if (item.WaitState == CoroutineData.WaitTypeEnum.WaitForTask) //等待Task
- {
- if (!item.WaitTask.IsCompleted)
- {
- canNext = false;
- }
- else
- {
- item.WaitState = CoroutineData.WaitTypeEnum.None;
- item.WaitTask = null;
- }
- }
- else if (item.WaitState == CoroutineData.WaitTypeEnum.WaitForSignalAwaiter) //等待信号
- {
- if (!item.WaitSignalAwaiter.IsCompleted)
- {
- canNext = false;
- }
- else
- {
- item.WaitState = CoroutineData.WaitTypeEnum.None;
- item.WaitSignalAwaiter = null;
- }
- }
-
- if (canNext)
- {
- if (item.Enumerator.MoveNext())
- {
- var next = item.Enumerator.Current;
- if (next is IEnumerable enumerable) //嵌套协程
+ if (!item.WaitForSeconds.NextStep(delta))
{
- if (item.EnumeratorStack == null)
- {
- item.EnumeratorStack = new Stack();
- }
-
- item.EnumeratorStack.Push(item.Enumerator);
- item.Enumerator = enumerable.GetEnumerator();
- }
- else if (next is IEnumerator enumerator) //嵌套协程
- {
- if (item.EnumeratorStack == null)
- {
- item.EnumeratorStack = new Stack();
- }
-
- item.EnumeratorStack.Push(item.Enumerator);
- item.Enumerator = enumerator;
- }
- else if (next is WaitForSeconds seconds) //等待秒数
- {
- item.WaitFor(seconds);
- }
- else if (next is WaitForFixedProcess process) //等待帧数
- {
- item.WaitFor(process);
- }
- else if (next is Task task) //Task对象
- {
- item.WaitFor(task);
- }
- else if (next is SignalAwaiter awaiter) //等待信号
- {
- item.WaitFor(awaiter);
- }
- }
- else
- {
- if (item.EnumeratorStack == null || item.EnumeratorStack.Count == 0)
- {
- ProxyStopCoroutine(ref coroutineList, item.Id);
+ canNext = false;
}
else
{
- item.Enumerator = item.EnumeratorStack.Pop();
+ item.WaitState = CoroutineData.WaitTypeEnum.None;
+ item.WaitForSeconds = null;
}
}
+ else if (item.WaitState == CoroutineData.WaitTypeEnum.WaitForFixedProcess) //等待帧数
+ {
+ if (!item.WaitForFixedProcess.NextStep())
+ {
+ canNext = false;
+ }
+ else
+ {
+ item.WaitState = CoroutineData.WaitTypeEnum.None;
+ item.WaitForFixedProcess = null;
+ }
+ }
+ else if (item.WaitState == CoroutineData.WaitTypeEnum.WaitForTask) //等待Task
+ {
+ if (!item.WaitTask.IsCompleted)
+ {
+ canNext = false;
+ }
+ else
+ {
+ item.WaitState = CoroutineData.WaitTypeEnum.None;
+ item.WaitTask = null;
+ }
+ }
+ else if (item.WaitState == CoroutineData.WaitTypeEnum.WaitForSignalAwaiter) //等待信号
+ {
+ if (!item.WaitSignalAwaiter.IsCompleted)
+ {
+ canNext = false;
+ }
+ else
+ {
+ item.WaitState = CoroutineData.WaitTypeEnum.None;
+ item.WaitSignalAwaiter = null;
+ }
+ }
+
+ if (canNext)
+ {
+ if (item.Enumerator.MoveNext())
+ {
+ var next = item.Enumerator.Current;
+ if (next is IEnumerable enumerable) //嵌套协程
+ {
+ if (item.EnumeratorStack == null)
+ {
+ item.EnumeratorStack = new Stack();
+ }
+
+ item.EnumeratorStack.Push(item.Enumerator);
+ item.Enumerator = enumerable.GetEnumerator();
+ }
+ else if (next is IEnumerator enumerator) //嵌套协程
+ {
+ if (item.EnumeratorStack == null)
+ {
+ item.EnumeratorStack = new Stack();
+ }
+
+ item.EnumeratorStack.Push(item.Enumerator);
+ item.Enumerator = enumerator;
+ }
+ else if (next is WaitForSeconds seconds) //等待秒数
+ {
+ item.WaitFor(seconds);
+ }
+ else if (next is WaitForFixedProcess process) //等待帧数
+ {
+ item.WaitFor(process);
+ }
+ else if (next is Task task) //Task对象
+ {
+ item.WaitFor(task);
+ }
+ else if (next is SignalAwaiter awaiter) //等待信号
+ {
+ item.WaitFor(awaiter);
+ }
+ }
+ else
+ {
+ if (item.EnumeratorStack == null || item.EnumeratorStack.Count == 0)
+ {
+ ProxyStopCoroutine(ref coroutineList, item.Id);
+ }
+ else
+ {
+ item.Enumerator = item.EnumeratorStack.Pop();
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ GD.PrintErr("执行协程发生异常: \n" + e);
}
}
}
@@ -159,6 +167,26 @@
}
}
}
+
+ ///
+ /// 代理协程, 根据 id 返回指定协程是否结束
+ ///
+ public static bool ProxyIsCoroutineOver(ref List coroutineList, long coroutineId)
+ {
+ if (coroutineList != null)
+ {
+ for (var i = 0; i < coroutineList.Count; i++)
+ {
+ var item = coroutineList[i];
+ if (item.Id == coroutineId)
+ {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
///
/// 代理协程, 停止所有协程
diff --git a/DungeonShooting_Godot/src/framework/map/preinstall/ActivityMark.cs b/DungeonShooting_Godot/src/framework/map/preinstall/ActivityMark.cs
index b4c72cf..5c1f35d 100644
--- a/DungeonShooting_Godot/src/framework/map/preinstall/ActivityMark.cs
+++ b/DungeonShooting_Godot/src/framework/map/preinstall/ActivityMark.cs
@@ -28,4 +28,21 @@
/// 延时时间, 单位: 秒
///
public float DelayTime { get; set; }
+
+ ///
+ /// 物体初始海拔高度
+ ///
+ public int Altitude = 8;
+
+ ///
+ /// 物体初始纵轴速度
+ ///
+ public float VerticalSpeed = 0;
+
+ ///
+ /// 物体类型
+ ///
+ public ActivityType ActivityType { get; set; }
+
+
}
\ 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 4a98867..54b2a80 100644
--- a/DungeonShooting_Godot/src/framework/map/preinstall/RoomPreinstall.cs
+++ b/DungeonShooting_Godot/src/framework/map/preinstall/RoomPreinstall.cs
@@ -1,8 +1,10 @@
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Linq;
+using Config;
using Godot;
///
@@ -32,7 +34,24 @@
///
public List> WaveList { get; } = new List>();
+ ///
+ /// 是否正在执行生成波数操作
+ ///
+ public bool IsRunWave { get; private set; }
+
+ ///
+ /// 是否执行到最后一波了
+ ///
+ public bool IsLastWave => _currWaveIndex >= WaveList.Count;
+
+ //是否运行过预处理
private bool _runPretreatment = false;
+ //当前房间是否会刷新敌人
+ private bool _hsaEnemy = false;
+ //当前波数索引
+ private int _currWaveIndex = 0;
+ //执行生成标记的协程id
+ private long _coroutineId = -1;
public RoomPreinstall(RoomInfo roomInfo, RoomPreinstallInfo roomPreinstallInfo)
{
@@ -80,6 +99,13 @@
mark.Id = markInfoItem.Id;
mark.Attr = markInfoItem.Attr;
+ mark.VerticalSpeed = markInfoItem.VerticalSpeed;
+ mark.Altitude = markInfoItem.Altitude;
+ mark.ActivityType = (ActivityType)ExcelConfig.ActivityObject_Map[markInfoItem.Id].Type;
+ if (mark.ActivityType == ActivityType.Enemy)
+ {
+ _hsaEnemy = true;
+ }
}
else if (markInfo.SpecialMarkType == SpecialMarkType.BirthPoint) //玩家出生标记
{
@@ -103,7 +129,6 @@
var offset = RoomInfo.GetOffsetPosition();
//var offset = RoomInfo.RoomSplit.RoomInfo.Position.AsVector2I();
mark.Position = RoomInfo.GetWorldPosition() + (tempPos - offset);
-
wave.Add(mark);
}
@@ -113,6 +138,155 @@
}
///
+ /// 预处理后才可以调用, 返回是否会生成敌人
+ ///
+ public bool HasEnemy()
+ {
+ return _hsaEnemy;
+ }
+
+ ///
+ /// 地牢房间加载完成
+ ///
+ public void OnReady()
+ {
+ _currWaveIndex = 0;
+ if (WaveList.Count > 0)
+ {
+ var activityMarks = WaveList[0];
+ foreach (var activityMark in activityMarks)
+ {
+ if (activityMark.MarkType == SpecialMarkType.Normal)
+ {
+ var activityObject = CreateItem(activityMark);
+ //初始化属性
+ InitAttr(activityObject, activityMark);
+ activityObject.PutDown(GetDefaultLayer(activityMark));
+ }
+ }
+ }
+
+ _currWaveIndex++;
+ }
+
+ ///
+ /// 玩家进入房间, 开始执行生成物体
+ ///
+ public void StartWave()
+ {
+ if (IsRunWave)
+ {
+ return;
+ }
+
+ IsRunWave = true;
+ _currWaveIndex = 1;
+ GD.Print("执行第一波");
+ _coroutineId = GameApplication.Instance.StartCoroutine(RunMark(WaveList[_currWaveIndex]));
+ _currWaveIndex++;
+ }
+
+ public void NextWave()
+ {
+ GD.Print("执行下一波, 当前: " + _currWaveIndex);
+ _coroutineId = GameApplication.Instance.StartCoroutine(RunMark(WaveList[_currWaveIndex]));
+ _currWaveIndex++;
+ }
+
+ //执行实例化标记物体
+ private IEnumerator RunMark(List activityMarks)
+ {
+ var timer = 0d;
+ for (var i = 0; i < activityMarks.Count;)
+ {
+ var activityMark = activityMarks[i];
+ if (timer >= activityMark.DelayTime)
+ {
+ if (activityMark.MarkType == SpecialMarkType.Normal)
+ {
+ var activityObject = CreateItem(activityMark);
+ activityObject.VerticalSpeed = activityMark.VerticalSpeed;
+ activityObject.Altitude = activityMark.Altitude;
+ //初始化属性
+ InitAttr(activityObject, activityMark);
+ //播放出生动画
+ activityObject.StartCoroutine(OnActivityObjectBirth(activityObject));
+ activityObject.PutDown(GetDefaultLayer(activityMark));
+
+ var effect1 = ResourceManager.LoadAndInstantiate(ResourcePath.prefab_effect_Effect1_tscn);
+ effect1.Position = activityObject.Position + new Vector2(0, -activityMark.Altitude);
+ effect1.AddToActivityRoot(RoomLayerEnum.YSortLayer);
+ }
+
+ i++;
+ }
+ else
+ {
+ timer += GameApplication.Instance.GetProcessDeltaTime();
+ yield return 0;
+ }
+ }
+
+ _coroutineId = -1;
+ }
+
+ //生成 ActivityObject 时调用, 用于出生时的动画效果
+ private IEnumerator OnActivityObjectBirth(ActivityObject instance)
+ {
+ var a = 1.0f;
+ instance.SetBlendColor(Colors.White);
+ //禁用自定义行为
+ instance.EnableCustomBehavior = false;
+ //禁用下坠
+ instance.EnableVerticalMotion = false;
+
+ for (var i = 0; i < 10; i++)
+ {
+ instance.SetBlendSchedule(a);
+ yield return 0;
+ }
+
+ while (a > 0)
+ {
+ instance.SetBlendSchedule(a);
+ a -= 0.05f;
+ yield return 0;
+ }
+
+ //启用自定义行为
+ instance.EnableCustomBehavior = true;
+ //启用下坠
+ instance.EnableVerticalMotion = true;
+ }
+
+ ///
+ /// 当前这一波是否执行完成
+ ///
+ public bool IsCurrWaveOver()
+ {
+ return _coroutineId < 0 || GameApplication.Instance.IsCoroutineOver(_coroutineId);
+ }
+
+ //创建物体
+ private ActivityObject CreateItem(ActivityMark activityMark)
+ {
+ var activityObject = ActivityObject.Create(activityMark.Id);
+ activityObject.Position = activityMark.Position;
+ return activityObject;
+ }
+
+ //获取物体默认所在层级
+ private RoomLayerEnum GetDefaultLayer(ActivityMark activityMark)
+ {
+ if (activityMark.ActivityType == ActivityType.Player || activityMark.ActivityType == ActivityType.Enemy)
+ {
+ return RoomLayerEnum.YSortLayer;
+ }
+
+ return RoomLayerEnum.NormalLayer;
+ }
+
+ ///
/// 获取房间内的玩家生成标记
///
public ActivityMark GetPlayerBirthMark()
@@ -135,6 +309,48 @@
}
IsDestroyed = true;
+ if (_coroutineId >= 0)
+ {
+ GameApplication.Instance.StopCoroutine(_coroutineId);
+ }
+
WaveList.Clear();
}
+
+ //初始化物体属性
+ private void InitAttr(ActivityObject activityObject, ActivityMark activityMark)
+ {
+ if (activityMark.ActivityType == ActivityType.Weapon) //武器类型
+ {
+ var weapon = (Weapon)activityObject;
+ if (activityMark.Attr.TryGetValue("CurrAmmon", out var currAmmon)) //当前弹夹弹药
+ {
+ weapon.SetCurrAmmo(int.Parse(currAmmon));
+ }
+ if (activityMark.Attr.TryGetValue("ResidueAmmo", out var residueAmmo)) //剩余弹药
+ {
+ weapon.SetResidueAmmo(int.Parse(residueAmmo));
+ }
+ }
+ else if (activityMark.ActivityType == ActivityType.Enemy) //敌人类型
+ {
+ var enemy = (Enemy)activityObject;
+ if (activityMark.Attr.TryGetValue("Weapon", out var weaponId)) //使用的武器
+ {
+ if (!string.IsNullOrEmpty(weaponId))
+ {
+ var weapon = ActivityObject.Create(weaponId);
+ enemy.PickUpWeapon(weapon);
+ if (activityMark.Attr.TryGetValue("CurrAmmon", out var currAmmon)) //当前弹夹弹药
+ {
+ weapon.SetCurrAmmo(int.Parse(currAmmon));
+ }
+ if (activityMark.Attr.TryGetValue("ResidueAmmo", out var residueAmmo)) //剩余弹药
+ {
+ weapon.SetResidueAmmo(int.Parse(residueAmmo));
+ }
+ }
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs b/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs
index 378d537..a486132 100644
--- a/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs
+++ b/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs
@@ -179,12 +179,6 @@
RoomPreinstall.Destroy();
RoomPreinstall = null;
}
-
- // foreach (var activityMark in ActivityMarks)
- // {
- // activityMark.QueueFree();
- // }
- // ActivityMarks.Clear();
if (StaticImageCanvas != null)
{
@@ -193,43 +187,44 @@
}
///
- /// 房间准备好了, 准备刷敌人, 并且关闭所有门,
+ /// 加载地牢完成
+ ///
+ public void OnReady()
+ {
+ //提前加载波
+ RoomPreinstall.OnReady();
+ }
+
+ ///
+ /// 玩家第一次进入房间, 房间准备好了, 准备刷敌人, 并且关闭所有
/// 当清完每一波刷新的敌人后即可开门
///
- public void BeReady()
+ public void OnFirstEnter()
{
- // //没有标记, 啥都不要做
- // if (ActivityMarks.Count == 0)
- // {
- // _beReady = true;
- // IsSeclusion = false;
- // return;
- // }
- // IsSeclusion = true;
- // _waveStart = false;
- //
- // if (!_beReady)
- // {
- // _beReady = true;
- // //按照 WaveNumber 排序
- // ActivityMarks.Sort((x, y) =>
- // {
- // return x.WaveNumber - y.WaveNumber;
- // });
- // }
- //
- // //不是初始房间才能关门
- // if (RoomSplit.RoomInfo.RoomType != DungeonRoomType.Inlet)
- // {
- // //关门
- // foreach (var doorInfo in Doors)
- // {
- // doorInfo.Door.CloseDoor();
- // }
- // }
- //
- // //执行第一波生成
- // NextWave();
+ if (RoomPreinstall.IsRunWave)
+ {
+ return;
+ }
+ //没有额外标记, 啥都不要做
+ if (RoomPreinstall.WaveCount <= 1)
+ {
+ IsSeclusion = false;
+ return;
+ }
+ IsSeclusion = true;
+
+ //会刷新敌人才要关门
+ if (RoomPreinstall.HasEnemy())
+ {
+ //关门
+ foreach (var doorInfo in Doors)
+ {
+ doorInfo.Door.CloseDoor();
+ }
+ }
+
+ //执行第一波生成
+ RoomPreinstall.StartWave();
}
///
@@ -237,23 +232,22 @@
///
public void OnClearRoom()
{
- // if (_currWaveIndex >= ActivityMarks.Count) //所有 mark 都走完了
- // {
- // IsSeclusion = false;
- // _currActivityMarks.Clear();
- // //开门
- // if (RoomSplit.RoomInfo.RoomType != DungeonRoomType.Inlet)
- // {
- // foreach (var doorInfo in Doors)
- // {
- // doorInfo.Door.OpenDoor();
- // }
- // }
- // }
- // else //执行下一波
- // {
- // NextWave();
- // }
+ if (RoomPreinstall.IsLastWave) //所有 mark 都走完了
+ {
+ IsSeclusion = false;
+ //开门
+ if (RoomPreinstall.HasEnemy())
+ {
+ foreach (var doorInfo in Doors)
+ {
+ doorInfo.Door.OpenDoor();
+ }
+ }
+ }
+ else //执行下一波
+ {
+ NextWave();
+ }
}
///
@@ -261,15 +255,7 @@
///
public bool IsCurrWaveOver()
{
- // for (var i = 0; i < _currActivityMarks.Count; i++)
- // {
- // if (!_currActivityMarks[i].IsOver())
- // {
- // return false;
- // }
- // }
-
- return true;
+ return RoomPreinstall.IsCurrWaveOver();
}
///
@@ -277,29 +263,6 @@
///
private void NextWave()
{
- // if (!_waveStart)
- // {
- // _waveStart = true;
- // _currWaveIndex = 0;
- // _currWaveNumber = ActivityMarks[0].WaveNumber;
- // }
- // GD.Print("执行下一波, 当前: " + _currWaveNumber);
- //
- // _currActivityMarks.Clear();
- // //根据标记生成对象
- // for (; _currWaveIndex < ActivityMarks.Count; _currWaveIndex++)
- // {
- // var mark = ActivityMarks[_currWaveIndex];
- // if (mark.WaveNumber != _currWaveNumber) //当前这波已经执行完成了
- // {
- // _currWaveNumber = mark.WaveNumber;
- // break;
- // }
- // else //生成操作
- // {
- // mark.BeReady(this);
- // _currActivityMarks.Add(mark);
- // }
- // }
+ RoomPreinstall.NextWave();
}
}
\ No newline at end of file
diff --git a/DungeonShooting_Godot/src/framework/map/serialize/MarkInfoItem.cs b/DungeonShooting_Godot/src/framework/map/serialize/MarkInfoItem.cs
index 60a46c2..6e38c93 100644
--- a/DungeonShooting_Godot/src/framework/map/serialize/MarkInfoItem.cs
+++ b/DungeonShooting_Godot/src/framework/map/serialize/MarkInfoItem.cs
@@ -24,6 +24,18 @@
///
[JsonInclude]
public Dictionary Attr;
+
+ ///
+ /// 物体初始海拔高度
+ ///
+ [JsonInclude]
+ public int Altitude;
+
+ ///
+ /// 物体初始纵轴速度
+ ///
+ [JsonInclude]
+ public float VerticalSpeed;
///
/// 所属标记类型
diff --git a/DungeonShooting_Godot/src/framework/ui/UiBase.cs b/DungeonShooting_Godot/src/framework/ui/UiBase.cs
index d0290b2..34b1c6a 100644
--- a/DungeonShooting_Godot/src/framework/ui/UiBase.cs
+++ b/DungeonShooting_Godot/src/framework/ui/UiBase.cs
@@ -351,6 +351,11 @@
ProxyCoroutineHandler.ProxyStopCoroutine(ref _coroutineList, coroutineId);
}
+ public bool IsCoroutineOver(long coroutineId)
+ {
+ return ProxyCoroutineHandler.ProxyIsCoroutineOver(ref _coroutineList, coroutineId);
+ }
+
public void StopAllCoroutine()
{
ProxyCoroutineHandler.ProxyStopAllCoroutine(ref _coroutineList);
diff --git a/DungeonShooting_Godot/src/game/GameApplication.cs b/DungeonShooting_Godot/src/game/GameApplication.cs
index 693694c..eedb29b 100644
--- a/DungeonShooting_Godot/src/game/GameApplication.cs
+++ b/DungeonShooting_Godot/src/game/GameApplication.cs
@@ -201,7 +201,12 @@
{
ProxyCoroutineHandler.ProxyStopCoroutine(ref _coroutineList, coroutineId);
}
-
+
+ public bool IsCoroutineOver(long coroutineId)
+ {
+ return ProxyCoroutineHandler.ProxyIsCoroutineOver(ref _coroutineList, coroutineId);
+ }
+
public void StopAllCoroutine()
{
ProxyCoroutineHandler.ProxyStopAllCoroutine(ref _coroutineList);
diff --git a/DungeonShooting_Godot/src/game/activity/role/Player.cs b/DungeonShooting_Godot/src/game/activity/role/Player.cs
index a34bf2b..b8b09eb 100644
--- a/DungeonShooting_Godot/src/game/activity/role/Player.cs
+++ b/DungeonShooting_Godot/src/game/activity/role/Player.cs
@@ -36,13 +36,13 @@
Shield = 0;
// debug用
- RoleState.Acceleration = 3000;
- RoleState.Friction = 3000;
- RoleState.MoveSpeed = 500;
- CollisionLayer = 0;
- CollisionMask = 0;
- GameCamera.Main.Zoom = new Vector2(.75f, 0.75f);
- //GameCamera.Main.Zoom = new Vector2(0.5f, 0.5f);
+ // RoleState.Acceleration = 3000;
+ // RoleState.Friction = 3000;
+ // RoleState.MoveSpeed = 500;
+ // CollisionLayer = 0;
+ // CollisionMask = 0;
+ // GameCamera.Main.Zoom = new Vector2(.75f, 0.75f);
+ // //GameCamera.Main.Zoom = new Vector2(0.5f, 0.5f);
}
protected override void Process(float delta)
diff --git a/DungeonShooting_Godot/src/game/room/DungeonManager.cs b/DungeonShooting_Godot/src/game/room/DungeonManager.cs
index 7f1e5a5..ab7680e 100644
--- a/DungeonShooting_Godot/src/game/room/DungeonManager.cs
+++ b/DungeonShooting_Godot/src/game/room/DungeonManager.cs
@@ -68,7 +68,7 @@
GameApplication.Instance.StartCoroutine(RunExitDungeonCoroutine(finish));
}
- public override void _PhysicsProcess(double delta)
+ public override void _Process(double delta)
{
if (IsInDungeon)
{
@@ -79,13 +79,8 @@
//检查房间内的敌人存活状况
OnCheckEnemy();
}
- }
- }
-
- public override void _Process(double delta)
- {
- if (IsInDungeon)
- {
+
+ //更新敌人视野
UpdateEnemiesView();
if (GameApplication.Instance.Debug)
{
@@ -146,6 +141,9 @@
player.Name = "Player";
player.PutDown(RoomLayerEnum.YSortLayer);
Player.SetCurrentPlayer(player);
+
+ //地牢加载即将完成
+ _dungeonGenerator.EachRoom(info => info.OnReady());
//玩家手上添加武器
//player.PickUpWeapon(ActivityObject.Create(ActivityObject.Ids.Id_weapon0001));
@@ -410,7 +408,7 @@
private void OnPlayerFirstEnterRoom(object o)
{
var room = (RoomInfo)o;
- room.BeReady();
+ room.OnFirstEnter();
//如果关门了, 那么房间外的敌人就会丢失目标
if (room.IsSeclusion)
{
diff --git a/DungeonShooting_Godot/src/game/ui/mapEditorCreateMark/MapEditorCreateMarkPanel.cs b/DungeonShooting_Godot/src/game/ui/mapEditorCreateMark/MapEditorCreateMarkPanel.cs
index 4548f98..8ae4673 100644
--- a/DungeonShooting_Godot/src/game/ui/mapEditorCreateMark/MapEditorCreateMarkPanel.cs
+++ b/DungeonShooting_Godot/src/game/ui/mapEditorCreateMark/MapEditorCreateMarkPanel.cs
@@ -180,13 +180,23 @@
EditorWindowManager.ShowSelectObject(ActivityType.None, OnSelectObject, this);
}
- //选中物体回调
+ //选中物体回调, 创建标记数据
private void OnSelectObject(ExcelConfig.ActivityObject activityObject)
{
+ //初始值
+
+ //初始高度
+ var altitude = 0;
+ if (activityObject.Type == (int)ActivityType.Weapon || activityObject.Type == (int)ActivityType.Prop)
+ {
+ altitude = 8;
+ }
+
_grid.Add(new MarkInfoItem()
{
Id = activityObject.Id,
- Weight = 100
+ Weight = 100,
+ Altitude = altitude
});
}
}
diff --git a/DungeonShooting_Godot/src/game/ui/mapEditorCreateMark/MarkObjectCell.cs b/DungeonShooting_Godot/src/game/ui/mapEditorCreateMark/MarkObjectCell.cs
index b64ec05..b9f7adb 100644
--- a/DungeonShooting_Godot/src/game/ui/mapEditorCreateMark/MarkObjectCell.cs
+++ b/DungeonShooting_Godot/src/game/ui/mapEditorCreateMark/MarkObjectCell.cs
@@ -9,8 +9,12 @@
//是否展开
private bool _isExpand = false;
private MapEditorCreateMark.ExpandPanel _expandPanel;
+ //自定义额外属性
private List _attributeBases;
private ExcelConfig.ActivityObject _activityObject;
+
+ private MapEditorCreateMark.NumberBar _altitude;
+ private MapEditorCreateMark.NumberBar _vSpeed;
public override void OnInit()
{
@@ -21,9 +25,8 @@
public override void OnSetData(MarkInfoItem data)
{
//记得判断随机对象, 后面再做
-
-
_activityObject = ExcelConfig.ActivityObject_Map[data.Id];
+ //图标
if (string.IsNullOrEmpty(_activityObject.Icon))
{
CellNode.L_VBoxContainer.L_HBoxContainer.L_Icon.Instance.Visible = false;
@@ -39,16 +42,9 @@
CellNode.L_VBoxContainer.L_HBoxContainer.L_NameLabel.Instance.Text = _activityObject.Name;
//物体类型
CellNode.L_VBoxContainer.L_HBoxContainer.L_TypeLabel.Instance.Text = NameManager.GetActivityTypeName(_activityObject.Type);
+ //权重
+ CellNode.L_VBoxContainer.L_HBoxContainer.L_WeightEdit.Instance.Value = data.Weight;
- // 包含额外属性
- if (_activityObject.Type == 5 || _activityObject.Type == 4)
- {
- if (_expandPanel == null)
- {
- CreateExpandPanel(_activityObject, data);
- }
- }
-
if (data.SpecialMarkType == SpecialMarkType.BirthPoint) //出生标记
{
CellNode.L_VBoxContainer.L_HBoxContainer.L_CenterContainer.L_DeleteButton.Instance.Visible = false;
@@ -56,8 +52,18 @@
}
else //普通标记
{
+ // 包含额外属性
+ if (_expandPanel == null)
+ {
+ CreateExpandPanel(_activityObject, data);
+ }
CellNode.L_VBoxContainer.L_HBoxContainer.L_CenterContainer.L_DeleteButton.Instance.Visible = true;
CellNode.L_VBoxContainer.L_HBoxContainer.L_WeightEdit.Instance.Visible = true;
+
+ //海拔高度
+ _altitude.L_NumInput.Instance.Value = data.Altitude;
+ //纵轴速度
+ _vSpeed.L_NumInput.Instance.Value = data.VerticalSpeed;
}
}
@@ -69,6 +75,8 @@
_attributeBases = null;
_expandPanel.QueueFree();
_expandPanel = null;
+ _altitude = null;
+ _vSpeed = null;
}
SetExpandState(false);
@@ -80,23 +88,47 @@
public MarkInfoItem GetMarkInfoItem()
{
var markInfoItem = Data;
- if (_activityObject.Type == 5 || _activityObject.Type == 4)
+
+ //额外属性
+ if (_attributeBases != null)
{
- markInfoItem.Attr = new Dictionary();
+ markInfoItem.Attr = null;
foreach (var attributeBase in _attributeBases)
{
if (attributeBase.Visible)
{
+ if (attributeBase.AttrName == "VSpeed" || attributeBase.AttrName == "Altitude") //不能是公共属性
+ {
+ continue;
+ }
+
+ if (markInfoItem.Attr == null)
+ {
+ markInfoItem.Attr = new Dictionary();
+ }
markInfoItem.Attr.Add(attributeBase.AttrName, attributeBase.GetAttributeValue());
}
}
}
+
if (Data.SpecialMarkType == SpecialMarkType.Normal)
{
+ //权重
markInfoItem.Weight = (int)CellNode.L_VBoxContainer.L_HBoxContainer.L_WeightEdit.Instance.Value;
}
+ //海拔高度
+ if (_altitude != null && _altitude.Instance.Visible)
+ {
+ markInfoItem.Altitude = (int)_altitude.L_NumInput.Instance.Value;
+ }
+ //纵轴速度
+ if (_vSpeed != null && _vSpeed.Instance.Visible)//海拔高度
+ {
+ markInfoItem.VerticalSpeed = (float)_vSpeed.L_NumInput.Instance.Value;
+ }
+
return markInfoItem;
}
@@ -144,8 +176,20 @@
_expandPanel = CellNode.UiPanel.S_ExpandPanel.Clone();
_expandPanel.Instance.Visible = _isExpand;
CellNode.L_VBoxContainer.AddChild(_expandPanel);
-
- if (activityObject.Type == 5) //武器类型
+
+ //公有类型
+ _altitude = CellNode.UiPanel.CreateNumberBar("Altitude", "初始纵轴高度:");
+ _vSpeed = CellNode.UiPanel.CreateNumberBar("VSpeed", "初始纵轴速度:");
+ _altitude.L_NumInput.Instance.MaxValue = 128;
+ _altitude.L_NumInput.Instance.MinValue = 0;
+ _altitude.L_NumInput.Instance.Step = 1;
+ _vSpeed.L_NumInput.Instance.MaxValue = 1000;
+ _vSpeed.L_NumInput.Instance.MinValue = -1000;
+ _vSpeed.L_NumInput.Instance.Step = 0.1;
+ _expandPanel.L_ExpandGrid.AddChild(_altitude);
+ _expandPanel.L_ExpandGrid.AddChild(_vSpeed);
+
+ if (activityObject.Type == (int)ActivityType.Weapon) //武器类型
{
var numberBar = CellNode.UiPanel.CreateNumberBar("CurrAmmon", "弹夹弹药量:");
var numberBar2 = CellNode.UiPanel.CreateNumberBar("ResidueAmmo", "剩余弹药量:");
@@ -185,7 +229,7 @@
}
}
}
- else if (activityObject.Type == 4) //敌人
+ else if (activityObject.Type == (int)ActivityType.Enemy) //敌人
{
var weaponBar = CellNode.UiPanel.CreateObjectBar("Weapon", "携带武器:", ActivityType.Weapon);
var numberBar2 = CellNode.UiPanel.CreateNumberBar("CurrAmmon", "弹夹弹药量:");