diff --git a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs index 6f5f9be..fb067a9 100644 --- a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs +++ b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs @@ -842,6 +842,66 @@ } /// + /// 根据类型获取所有相同类型的组件 + /// + public Component[] GetComponents(Type type) + { + var list = new List(); + for (int i = 0; i < _components.Count; i++) + { + var temp = _components[i]; + if (temp.Key.IsAssignableTo(type)) + { + list.Add(temp.Value); + } + } + + if (_updatingComp) + { + for (var i = 0; i < _changeComponents.Count; i++) + { + var temp = _components[i]; + if (temp.Value.GetType().IsAssignableTo(type)) + { + list.Add(temp.Value); + } + } + } + + return list.ToArray(); + } + + /// + /// 根据类型获取所有相同类型的组件 + /// + public T[] GetComponents() where T : Component + { + var list = new List(); + for (int i = 0; i < _components.Count; i++) + { + var temp = _components[i]; + if (temp.Value is T component) + { + list.Add(component); + } + } + + if (_updatingComp) + { + for (var i = 0; i < _changeComponents.Count; i++) + { + var temp = _components[i]; + if (temp.Value is T component) + { + list.Add(component); + } + } + } + + return list.ToArray(); + } + + /// /// 设置混色材质的颜色 /// public void SetBlendColor(Color color) diff --git a/DungeonShooting_Godot/src/framework/activity/Component.cs b/DungeonShooting_Godot/src/framework/activity/Component.cs index a33d5e2..be0680d 100644 --- a/DungeonShooting_Godot/src/framework/activity/Component.cs +++ b/DungeonShooting_Godot/src/framework/activity/Component.cs @@ -245,6 +245,16 @@ return Master.GetComponent(type); } + public T[] GetComponents() where T : Component, new() + { + return Master.GetComponents(); + } + + public Component[] GetComponents(Type type) + { + return Master.GetComponents(type); + } + public void RemoveComponent(Component component) { Master.RemoveComponent(component); diff --git a/DungeonShooting_Godot/src/framework/activity/components/StateController.cs b/DungeonShooting_Godot/src/framework/activity/components/StateController.cs index bb1bbd8..d33027c 100644 --- a/DungeonShooting_Godot/src/framework/activity/components/StateController.cs +++ b/DungeonShooting_Godot/src/framework/activity/components/StateController.cs @@ -5,7 +5,7 @@ /// /// 对象状态机控制器 /// -public class StateController : Component where T : ActivityObject where S : Enum +public class StateController : Component where T : ActivityObject where S : Enum { /// /// 获取当前状态 @@ -60,7 +60,7 @@ return; } - stateBase.Master = Master as T; + stateBase.Master = Master; stateBase.StateController = this; _states.Add(stateBase.State, stateBase); } diff --git a/DungeonShooting_Godot/src/framework/common/SeedRandom.cs b/DungeonShooting_Godot/src/framework/common/SeedRandom.cs index 6fd42c4..11acb6f 100644 --- a/DungeonShooting_Godot/src/framework/common/SeedRandom.cs +++ b/DungeonShooting_Godot/src/framework/common/SeedRandom.cs @@ -188,4 +188,81 @@ return RandomRangeInt(0, weightList.Length - 1); } + + /// + /// 返回指定区域内的随机坐标点, 该函数比较慢, 请谨慎调用 + /// + /// 碰撞区域数据 + /// 需要随机点的数量 + public Vector2[] GetRandomPositionInPolygon(List polygonDataList, int count) + { + var minX = int.MaxValue; + var maxX = int.MinValue; + var minY = int.MaxValue; + var maxY = int.MinValue; + + var outCount = 0; + + // 遍历多边形的顶点,找到最小和最大的x、y坐标 + foreach (var navigationPolygonData in polygonDataList) + { + if (navigationPolygonData.Type == NavigationPolygonType.Out) + { + outCount++; + } + foreach (var vertex in navigationPolygonData.GetPoints()) + { + if (vertex.X < minX) + { + minX = Mathf.CeilToInt(vertex.X); + } + else if (vertex.X > maxX) + { + maxX = Mathf.FloorToInt(vertex.X); + } + if (vertex.Y < minY) + { + minY = Mathf.CeilToInt(vertex.Y); + } + else if (vertex.Y > maxY) + { + maxY = Mathf.FloorToInt(vertex.Y); + } + } + } + + var list = new List(); + while (true) + { + var flag = outCount == 0; + var point = new Vector2(RandomRangeInt(minX, maxX), RandomRangeInt(minY, maxY)); + + foreach (var navigationPolygonData in polygonDataList) + { + if (navigationPolygonData.Type == NavigationPolygonType.Out) + { + if (!flag && Utils.IsPointInPolygon(navigationPolygonData.GetPoints(), point)) + { + flag = true; + } + } + else + { + if (flag && Utils.IsPointInPolygon(navigationPolygonData.GetPoints(), point)) + { + flag = false; + } + } + } + + if (flag) + { + list.Add(point); + if (list.Count >= count) + { + return list.ToArray(); + } + } + } + } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/framework/common/Utils.cs b/DungeonShooting_Godot/src/framework/common/Utils.cs index d139167..be06a29 100644 --- a/DungeonShooting_Godot/src/framework/common/Utils.cs +++ b/DungeonShooting_Godot/src/framework/common/Utils.cs @@ -261,4 +261,25 @@ return point; } + + /// + /// 返回一个点是否在 Polygon 内部 + /// + /// 多边形顶点 + /// 目标点 + public static bool IsPointInPolygon(Vector2[] polygon, Vector2 point) + { + var isInside = false; + for (int i = 0, j = polygon.Length - 1; i < polygon.Length; j = i++) + { + if ((polygon[i].Y > point.Y) != (polygon[j].Y > point.Y) && + point.X < (polygon[j].X - polygon[i].X) * (point.Y - polygon[i].Y) / (polygon[j].Y - polygon[i].Y) + + polygon[i].X) + { + isInside = !isInside; + } + } + + return isInside; + } } \ 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 cc9122b..9a7d44e 100644 --- a/DungeonShooting_Godot/src/framework/map/preinstall/RoomPreinstall.cs +++ b/DungeonShooting_Godot/src/framework/map/preinstall/RoomPreinstall.cs @@ -161,7 +161,8 @@ ); var offset = RoomInfo.GetOffsetPosition(); //var offset = RoomInfo.RoomSplit.RoomInfo.Position.AsVector2I(); - mark.Position = RoomInfo.GetWorldPosition() + (tempPos - offset); + //mark.Position = RoomInfo.GetWorldPosition() + tempPos - offset; + mark.Position = RoomInfo.ToGlobalPosition(tempPos); wave.Add(mark); } diff --git a/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs b/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs index 8883d1d..a249dda 100644 --- a/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs +++ b/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs @@ -225,6 +225,14 @@ } /// + /// 将房间配置中的坐标转为全局坐标, 单位: 像素 + /// + public Vector2 ToGlobalPosition(Vector2 pos) + { + return GetWorldPosition() + pos - GetOffsetPosition(); + } + + /// /// 获取房间横轴结束位置, 单位: 格 /// public int GetHorizontalEnd()