增加了注释
This commit is contained in:
parent
db529f1bd1
commit
9a91544519
69
.cursorrules
69
.cursorrules
@ -1,69 +0,0 @@
|
|||||||
|
|
||||||
# C 开发规则
|
|
||||||
|
|
||||||
您是一名C#开发专家。
|
|
||||||
|
|
||||||
## 代码风格和结构
|
|
||||||
- 编写简洁、符合习惯的 C# 代码,并提供准确的示例。
|
|
||||||
- 根据需要使用面向对象和函数式编程模式。
|
|
||||||
- 优先使用 LINQ 和 lambda 表达式进行集合操作。
|
|
||||||
- 使用描述性变量和方法名称(例如,'IsUserSignedIn', 'CalculateTotal')。
|
|
||||||
|
|
||||||
## 命名约定
|
|
||||||
- 类名、方法名和公共成员使用 PascalCase。
|
|
||||||
- 局部变量和私有字段使用 camelCase。
|
|
||||||
- 常量使用 UPPERCASE。
|
|
||||||
- 接口名称以 "I" 开头(例如,'IUserService')。
|
|
||||||
|
|
||||||
## C# 使用
|
|
||||||
- 在适当的情况下使用 C# 10+ 特性(例如,记录类型、模式匹配、空合并赋值)。
|
|
||||||
- 有效使用 Entity Framework Core 进行数据库操作。
|
|
||||||
- 使用依赖注入实现松耦合和可测试性。
|
|
||||||
- 类的构造函数使用主构造函数,成员变量使用属性初始化。
|
|
||||||
|
|
||||||
## 语法和格式
|
|
||||||
- 遵循 C# 编码约定(https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions)
|
|
||||||
- 使用 C# 的表达式语法(例如,空条件运算符、字符串插值)
|
|
||||||
- 当类型明显时,使用 'var' 进行隐式类型声明。
|
|
||||||
|
|
||||||
## 错误处理和验证
|
|
||||||
- 对于异常情况使用异常,而不是控制流。
|
|
||||||
- 使用内置的 .NET 日志记录或第三方日志记录器实现适当的错误日志记录。
|
|
||||||
- 使用数据注解或 Fluent Validation 进行模型验证。
|
|
||||||
- 实现全局异常处理的中间件。
|
|
||||||
- 返回适当的 HTTP 状态码和一致的错误响应。
|
|
||||||
|
|
||||||
## API 设计
|
|
||||||
- 遵循 RESTful API 设计原则。
|
|
||||||
- 在控制器中使用属性路由。
|
|
||||||
- 为您的 API 实现版本控制。
|
|
||||||
- 使用操作过滤器处理跨切关注点。
|
|
||||||
|
|
||||||
## 性能优化
|
|
||||||
- 对于 I/O 密集型操作,使用 async/await 进行异步编程。
|
|
||||||
- 使用 IMemoryCache 或分布式缓存实现缓存策略。
|
|
||||||
- 使用高效的 LINQ 查询,避免 N+1 查询问题。
|
|
||||||
- 对于大型数据集实现分页。
|
|
||||||
|
|
||||||
## 关键约定
|
|
||||||
- 使用依赖注入实现松耦合和可测试性。
|
|
||||||
- 根据复杂性实现仓储模式或直接使用 Entity Framework Core。
|
|
||||||
- 如有需要,使用 AutoMapper 进行对象到对象的映射。
|
|
||||||
- 使用 IHostedService 或 BackgroundService 实现后台任务。
|
|
||||||
|
|
||||||
## 测试
|
|
||||||
- 使用 xUnit、NUnit 或 MSTest 编写单元测试。
|
|
||||||
- 使用 Moq 或 NSubstitute 模拟依赖项。
|
|
||||||
- 为 API 端点实现集成测试。
|
|
||||||
|
|
||||||
## 安全性
|
|
||||||
- 使用身份验证和授权中间件。
|
|
||||||
- 实现 JWT 身份验证以进行无状态 API 身份验证。
|
|
||||||
- 使用 HTTPS 并强制 SSL。
|
|
||||||
- 实现适当的 CORS 策略。
|
|
||||||
|
|
||||||
## API 文档
|
|
||||||
- 使用 Swagger/OpenAPI 进行 API 文档(根据安装的 Swashbuckle.AspNetCore 包)。
|
|
||||||
- 为控制器和模型提供 XML 注释,以增强 Swagger 文档。
|
|
||||||
|
|
||||||
遵循官方 Microsoft 文档,以获取路由、控制器、模型和其他 API 组件的最佳实践。
|
|
||||||
29
Design.md
29
Design.md
@ -119,3 +119,32 @@ public class FireMissileCommand : ICommand
|
|||||||
- 实现观察者模式,处理告警通知。
|
- 实现观察者模式,处理告警通知。
|
||||||
- 使用命令模式封装关键操作。
|
- 使用命令模式封装关键操作。
|
||||||
- 进行单元测试和集成测试,确保系统的正确性和稳定性。
|
- 进行单元测试和集成测试,确保系统的正确性和稳定性。
|
||||||
|
|
||||||
|
## 数据库访问架构
|
||||||
|
|
||||||
|
在Unity3D环境中,考虑到兼容性和易用性,我推荐使用第二种方法:值对象模式。这种方式有以下几个优点:
|
||||||
|
|
||||||
|
1. 分离关注点:数据库实体(MissileConfigEntity)和游戏中使用的配置对象(MissileConfig)是分开的,这样可以避免 ORM 相关的属性和特性污染游戏逻辑。
|
||||||
|
2. 灵活性:可以轻松地在数据库实体和游戏配置对象之间进行转换,而不影响现有的游戏逻辑。
|
||||||
|
3. 序列化友好:Unity 经常需要序列化对象,使用纯粹的 C# 对象(如 MissileConfig)更容易进行序列化和反序列化。
|
||||||
|
4. 兼容性好:这种方法不依赖于特定的 ORM 框架,如果将来需要更换数据库或 ORM 系统,影响会较小。
|
||||||
|
|
||||||
|
数据访问层使用了 Dapper(一个轻量级的 ORM),它在 Unity 中使用较为简单。
|
||||||
|
|
||||||
|
数据库设计
|
||||||
|
|
||||||
|
### 1. 导弹数据库设计
|
||||||
|
|
||||||
|
导弹数据库设计需要考虑导弹的属性、状态、行为等。
|
||||||
|
|
||||||
|
#### 1.1 导弹属性
|
||||||
|
|
||||||
|
导弹属性包括导弹的初始位置、初始速度、最大速度、目标索引、最大飞行时间、最大飞行距离、飞行阶段配置、推力加速度、最大发动机燃烧时间、最大加速度、距离参数、比例导引系数、类型等。
|
||||||
|
|
||||||
|
#### 1.2 导弹状态
|
||||||
|
|
||||||
|
导弹状态包括导弹的当前位置、当前速度、当前加速度、当前飞行阶段、当前目标索引、当前最大速度、当前最大加速度、当前最大飞行距离、当前最大飞行时间、当前比例导引系数等。
|
||||||
|
|
||||||
|
#### 1.3 导弹行为
|
||||||
|
|
||||||
|
导弹行为包括导弹的飞行行为、攻击行为、躲避行为、跟踪行为、锁定行为、发射行为、爆炸行为等。
|
||||||
|
|||||||
116
Models/Common.cs
116
Models/Common.cs
@ -2,54 +2,105 @@ using System;
|
|||||||
|
|
||||||
namespace ActiveProtect.Models
|
namespace ActiveProtect.Models
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 表示三维空间中的向量
|
||||||
|
/// </summary>
|
||||||
public class Vector3D(double x, double y, double z)
|
public class Vector3D(double x, double y, double z)
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// X 坐标
|
||||||
|
/// </summary>
|
||||||
public double X { get; set; } = x;
|
public double X { get; set; } = x;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Y 坐标
|
||||||
|
/// </summary>
|
||||||
public double Y { get; set; } = y;
|
public double Y { get; set; } = y;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Z 坐标
|
||||||
|
/// </summary>
|
||||||
public double Z { get; set; } = z;
|
public double Z { get; set; } = z;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算两个向量之间的距离
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="v1">第一个向量</param>
|
||||||
|
/// <param name="v2">第二个向量</param>
|
||||||
|
/// <returns>两个向量之间的距离</returns>
|
||||||
public static double Distance(Vector3D v1, Vector3D v2)
|
public static double Distance(Vector3D v1, Vector3D v2)
|
||||||
{
|
{
|
||||||
return Math.Sqrt(Math.Pow(v1.X - v2.X, 2) + Math.Pow(v1.Y - v2.Y, 2) + Math.Pow(v1.Z - v2.Z, 2));
|
return Math.Sqrt(Math.Pow(v1.X - v2.X, 2) + Math.Pow(v1.Y - v2.Y, 2) + Math.Pow(v1.Z - v2.Z, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 零向量
|
||||||
|
/// </summary>
|
||||||
public static Vector3D Zero => new(0, 0, 0);
|
public static Vector3D Zero => new(0, 0, 0);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将向量转换为字符串表示
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>向量的字符串表示</returns>
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return $"({X:F2}, {Y:F2}, {Z:F2})";
|
return $"({X:F2}, {Y:F2}, {Z:F2})";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 向量减法运算符重载
|
||||||
|
/// </summary>
|
||||||
public static Vector3D operator -(Vector3D a, Vector3D b)
|
public static Vector3D operator -(Vector3D a, Vector3D b)
|
||||||
{
|
{
|
||||||
return new Vector3D(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
|
return new Vector3D(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 向量加法运算符重载
|
||||||
|
/// </summary>
|
||||||
public static Vector3D operator +(Vector3D a, Vector3D b)
|
public static Vector3D operator +(Vector3D a, Vector3D b)
|
||||||
{
|
{
|
||||||
return new Vector3D(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
|
return new Vector3D(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 向量与标量乘法运算符重载
|
||||||
|
/// </summary>
|
||||||
public static Vector3D operator *(Vector3D a, double scalar)
|
public static Vector3D operator *(Vector3D a, double scalar)
|
||||||
{
|
{
|
||||||
return new Vector3D(a.X * scalar, a.Y * scalar, a.Z * scalar);
|
return new Vector3D(a.X * scalar, a.Y * scalar, a.Z * scalar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 向量与标量除法运算符重载
|
||||||
|
/// </summary>
|
||||||
public static Vector3D operator /(Vector3D a, double scalar)
|
public static Vector3D operator /(Vector3D a, double scalar)
|
||||||
{
|
{
|
||||||
return new Vector3D(a.X / scalar, a.Y / scalar, a.Z / scalar);
|
return new Vector3D(a.X / scalar, a.Y / scalar, a.Z / scalar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算向量的模长
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>向量的模长</returns>
|
||||||
public double Magnitude()
|
public double Magnitude()
|
||||||
{
|
{
|
||||||
return Math.Sqrt(X * X + Y * Y + Z * Z);
|
return Math.Sqrt(X * X + Y * Y + Z * Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算向量模长的平方
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>向量模长的平方</returns>
|
||||||
public double MagnitudeSquared()
|
public double MagnitudeSquared()
|
||||||
{
|
{
|
||||||
return X * X + Y * Y + Z * Z;
|
return X * X + Y * Y + Z * Z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 向量归一化
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>归一化后的向量</returns>
|
||||||
public Vector3D Normalize()
|
public Vector3D Normalize()
|
||||||
{
|
{
|
||||||
double mag = Magnitude();
|
double mag = Magnitude();
|
||||||
@ -60,6 +111,12 @@ namespace ActiveProtect.Models
|
|||||||
return new Vector3D(0, 0, 0);
|
return new Vector3D(0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算两个向量的叉积
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="a">第一个向量</param>
|
||||||
|
/// <param name="b">第二个向量</param>
|
||||||
|
/// <returns>叉积结果</returns>
|
||||||
public static Vector3D CrossProduct(Vector3D a, Vector3D b)
|
public static Vector3D CrossProduct(Vector3D a, Vector3D b)
|
||||||
{
|
{
|
||||||
return new Vector3D(
|
return new Vector3D(
|
||||||
@ -69,23 +126,60 @@ namespace ActiveProtect.Models
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算两个向量的点积
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="a">第一个向量</param>
|
||||||
|
/// <param name="b">第二个向量</param>
|
||||||
|
/// <returns>点积结果</returns>
|
||||||
public static double DotProduct(Vector3D a, Vector3D b)
|
public static double DotProduct(Vector3D a, Vector3D b)
|
||||||
{
|
{
|
||||||
return a.X * b.X + a.Y * b.Y + a.Z * b.Z;
|
return a.X * b.X + a.Y * b.Y + a.Z * b.Z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 向量取反
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="a">输入向量</param>
|
||||||
|
/// <returns>取反后的向量</returns>
|
||||||
|
public static Vector3D Negate(Vector3D a)
|
||||||
|
{
|
||||||
|
return new Vector3D(-a.X, -a.Y, -a.Z);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 表示三维空间中的方向
|
||||||
|
/// </summary>
|
||||||
public struct Orientation(double yaw, double pitch, double roll)
|
public struct Orientation(double yaw, double pitch, double roll)
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 偏航角(绕Y轴旋转)
|
||||||
|
/// </summary>
|
||||||
public double Yaw { get; set; } = yaw;
|
public double Yaw { get; set; } = yaw;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 俯仰角(绕X轴旋转)
|
||||||
|
/// </summary>
|
||||||
public double Pitch { get; set; } = pitch;
|
public double Pitch { get; set; } = pitch;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 滚转角(绕Z轴旋转)
|
||||||
|
/// </summary>
|
||||||
public double Roll { get; set; } = roll;
|
public double Roll { get; set; } = roll;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将方向转换为字符串表示
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>方向的字符串表示</returns>
|
||||||
public override readonly string ToString()
|
public override readonly string ToString()
|
||||||
{
|
{
|
||||||
return $"(Yaw: {Yaw:F2}, Pitch: {Pitch:F2}, Roll: {Roll:F2})";
|
return $"(Yaw: {Yaw:F2}, Pitch: {Pitch:F2}, Roll: {Roll:F2})";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将角度归一化到 [-π, π] 范围内
|
||||||
|
/// </summary>
|
||||||
public void Normalize()
|
public void Normalize()
|
||||||
{
|
{
|
||||||
Yaw = NormalizeAngle(Yaw);
|
Yaw = NormalizeAngle(Yaw);
|
||||||
@ -93,6 +187,11 @@ namespace ActiveProtect.Models
|
|||||||
Roll = NormalizeAngle(Roll);
|
Roll = NormalizeAngle(Roll);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将单个角度归一化到 [-π, π] 范围内
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="angle">输入角度</param>
|
||||||
|
/// <returns>归一化后的角度</returns>
|
||||||
private static double NormalizeAngle(double angle)
|
private static double NormalizeAngle(double angle)
|
||||||
{
|
{
|
||||||
while (angle > Math.PI) angle -= 2 * Math.PI;
|
while (angle > Math.PI) angle -= 2 * Math.PI;
|
||||||
@ -100,6 +199,11 @@ namespace ActiveProtect.Models
|
|||||||
return angle;
|
return angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据给定的方向向量创建方向
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="direction">方向向量</param>
|
||||||
|
/// <returns>对应的方向</returns>
|
||||||
public static Orientation LookAt(Vector3D direction)
|
public static Orientation LookAt(Vector3D direction)
|
||||||
{
|
{
|
||||||
double yaw = Math.Atan2(direction.Z, direction.X);
|
double yaw = Math.Atan2(direction.Z, direction.X);
|
||||||
@ -107,6 +211,10 @@ namespace ActiveProtect.Models
|
|||||||
return new Orientation(yaw, pitch, 0);
|
return new Orientation(yaw, pitch, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将方向转换为单位向量
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>对应的单位向量</returns>
|
||||||
public readonly Vector3D ToVector()
|
public readonly Vector3D ToVector()
|
||||||
{
|
{
|
||||||
double cosYaw = Math.Cos(Yaw);
|
double cosYaw = Math.Cos(Yaw);
|
||||||
@ -121,6 +229,11 @@ namespace ActiveProtect.Models
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从向量创建方向
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vector">输入向量</param>
|
||||||
|
/// <returns>对应的方向</returns>
|
||||||
public static Orientation FromVector(Vector3D vector)
|
public static Orientation FromVector(Vector3D vector)
|
||||||
{
|
{
|
||||||
Vector3D normalized = vector.Normalize();
|
Vector3D normalized = vector.Normalize();
|
||||||
@ -137,7 +250,4 @@ namespace ActiveProtect.Models
|
|||||||
return new Orientation(yaw, pitch, 0);
|
return new Orientation(yaw, pitch, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,11 +2,29 @@ using ActiveProtect.SimulationEnvironment;
|
|||||||
|
|
||||||
namespace ActiveProtect.Models
|
namespace ActiveProtect.Models
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 定义可被激光照射的实体接口
|
||||||
|
/// </summary>
|
||||||
public interface ILaserIlluminatable
|
public interface ILaserIlluminatable
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取实体是否正在被激光照射
|
||||||
|
/// </summary>
|
||||||
bool IsIlluminated { get; }
|
bool IsIlluminated { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 开始激光照射
|
||||||
|
/// </summary>
|
||||||
void Illuminate();
|
void Illuminate();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 停止激光照射
|
||||||
|
/// </summary>
|
||||||
void StopIllumination();
|
void StopIllumination();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取实体的位置
|
||||||
|
/// </summary>
|
||||||
Vector3D Position { get; }
|
Vector3D Position { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3,15 +3,49 @@ using System;
|
|||||||
|
|
||||||
namespace ActiveProtect.Models
|
namespace ActiveProtect.Models
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 激光指示器类,用于对目标进行激光照射
|
||||||
|
/// </summary>
|
||||||
public class LaserDesignator : SimulationElement
|
public class LaserDesignator : SimulationElement
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 目标ID
|
||||||
|
/// </summary>
|
||||||
public string TargetId { get; private set; }
|
public string TargetId { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 导弹ID
|
||||||
|
/// </summary>
|
||||||
public string MissileId { get; private set; }
|
public string MissileId { get; private set; }
|
||||||
public double JammingThreshold { get; private set; } = 0.0; // 调整干扰阈值
|
|
||||||
|
/// <summary>
|
||||||
|
/// 干扰阈值(分贝)
|
||||||
|
/// </summary>
|
||||||
|
public double JammingThreshold { get; private set; } = 0.0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否被干扰
|
||||||
|
/// </summary>
|
||||||
public bool IsJammed { get; private set; } = false;
|
public bool IsJammed { get; private set; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最大照射范围(米)
|
||||||
|
/// </summary>
|
||||||
public double MaxIlluminationRange { get; private set; }
|
public double MaxIlluminationRange { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否正在照射
|
||||||
|
/// </summary>
|
||||||
private bool IsIlluminating { get; set; } = false;
|
private bool IsIlluminating { get; set; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造函数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">激光指示器ID</param>
|
||||||
|
/// <param name="targetId">目标ID</param>
|
||||||
|
/// <param name="missileId">导弹ID</param>
|
||||||
|
/// <param name="config">激光指示器配置</param>
|
||||||
|
/// <param name="simulationManager">仿真管理器</param>
|
||||||
public LaserDesignator(string id, string targetId, string missileId, LaserDesignatorConfig config, ISimulationManager simulationManager)
|
public LaserDesignator(string id, string targetId, string missileId, LaserDesignatorConfig config, ISimulationManager simulationManager)
|
||||||
: base(id, config.InitialPosition, new Orientation(), simulationManager)
|
: base(id, config.InitialPosition, new Orientation(), simulationManager)
|
||||||
{
|
{
|
||||||
@ -23,6 +57,10 @@ namespace ActiveProtect.Models
|
|||||||
SimulationManager.SubscribeToEvent<EntityDeactivatedEvent>(OnEntityDeactivatedEvent);
|
SimulationManager.SubscribeToEvent<EntityDeactivatedEvent>(OnEntityDeactivatedEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新激光指示器状态
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="deltaTime">时间步长</param>
|
||||||
public override void Update(double deltaTime)
|
public override void Update(double deltaTime)
|
||||||
{
|
{
|
||||||
if (IsActive && !IsJammed)
|
if (IsActive && !IsJammed)
|
||||||
@ -35,6 +73,9 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新照射状态
|
||||||
|
/// </summary>
|
||||||
private void UpdateIllumination()
|
private void UpdateIllumination()
|
||||||
{
|
{
|
||||||
if (SimulationManager.GetEntityById(TargetId) is ILaserIlluminatable target)
|
if (SimulationManager.GetEntityById(TargetId) is ILaserIlluminatable target)
|
||||||
@ -67,6 +108,10 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 开始照射目标
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="target">目标</param>
|
||||||
private void StartIllumination(ILaserIlluminatable target)
|
private void StartIllumination(ILaserIlluminatable target)
|
||||||
{
|
{
|
||||||
target.Illuminate();
|
target.Illuminate();
|
||||||
@ -75,6 +120,9 @@ namespace ActiveProtect.Models
|
|||||||
PublishIlluminationEvent();
|
PublishIlluminationEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 停止照射目标
|
||||||
|
/// </summary>
|
||||||
private void StopIllumination()
|
private void StopIllumination()
|
||||||
{
|
{
|
||||||
if (SimulationManager.GetEntityById(TargetId) is ILaserIlluminatable target)
|
if (SimulationManager.GetEntityById(TargetId) is ILaserIlluminatable target)
|
||||||
@ -86,6 +134,10 @@ namespace ActiveProtect.Models
|
|||||||
PublishIlluminationStopEvent();
|
PublishIlluminationStopEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 处理激光干扰事件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="evt">激光干扰事件</param>
|
||||||
private void OnLaserJamming(LaserJammingEvent evt)
|
private void OnLaserJamming(LaserJammingEvent evt)
|
||||||
{
|
{
|
||||||
if (evt.TargetId == TargetId)
|
if (evt.TargetId == TargetId)
|
||||||
@ -119,6 +171,9 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 激活激光指示器
|
||||||
|
/// </summary>
|
||||||
public void ActivateLaser()
|
public void ActivateLaser()
|
||||||
{
|
{
|
||||||
IsActive = true;
|
IsActive = true;
|
||||||
@ -127,6 +182,9 @@ namespace ActiveProtect.Models
|
|||||||
UpdateIllumination();
|
UpdateIllumination();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 停用激光指示器
|
||||||
|
/// </summary>
|
||||||
public void DeactivateLaser()
|
public void DeactivateLaser()
|
||||||
{
|
{
|
||||||
if (IsActive)
|
if (IsActive)
|
||||||
@ -137,6 +195,9 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发布激光照射事件
|
||||||
|
/// </summary>
|
||||||
private void PublishIlluminationEvent()
|
private void PublishIlluminationEvent()
|
||||||
{
|
{
|
||||||
PublishEvent(new LaserIlluminationEvent
|
PublishEvent(new LaserIlluminationEvent
|
||||||
@ -145,6 +206,9 @@ namespace ActiveProtect.Models
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发布激光照射停止事件
|
||||||
|
/// </summary>
|
||||||
private void PublishIlluminationStopEvent()
|
private void PublishIlluminationStopEvent()
|
||||||
{
|
{
|
||||||
PublishEvent(new LaserIlluminationStopEvent
|
PublishEvent(new LaserIlluminationStopEvent
|
||||||
@ -153,6 +217,10 @@ namespace ActiveProtect.Models
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 处理实体停用事件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="evt">实体停用事件</param>
|
||||||
private void OnEntityDeactivatedEvent(EntityDeactivatedEvent evt)
|
private void OnEntityDeactivatedEvent(EntityDeactivatedEvent evt)
|
||||||
{
|
{
|
||||||
if (evt.DeactivatedEntityId == TargetId || evt.DeactivatedEntityId == MissileId)
|
if (evt.DeactivatedEntityId == TargetId || evt.DeactivatedEntityId == MissileId)
|
||||||
@ -162,6 +230,10 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取激光指示器状态信息
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>状态信息字符串</returns>
|
||||||
public override string GetStatus()
|
public override string GetStatus()
|
||||||
{
|
{
|
||||||
return $"激光目标指示器 {Id}:\n" +
|
return $"激光目标指示器 {Id}:\n" +
|
||||||
|
|||||||
@ -3,17 +3,60 @@ using ActiveProtect.SimulationEnvironment;
|
|||||||
|
|
||||||
namespace ActiveProtect.Models
|
namespace ActiveProtect.Models
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 激光干扰器类,用于对抗激光制导武器
|
||||||
|
/// </summary>
|
||||||
public class LaserJammer : SimulationElement
|
public class LaserJammer : SimulationElement
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 是否正在进行干扰
|
||||||
|
/// </summary>
|
||||||
public bool IsJamming { get; private set; }
|
public bool IsJamming { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前干扰功率(瓦特)
|
||||||
|
/// </summary>
|
||||||
public double JammingPower { get; private set; }
|
public double JammingPower { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前冷却时间(秒)
|
||||||
|
/// </summary>
|
||||||
private double jammingCooldown = 0;
|
private double jammingCooldown = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最大冷却时间(秒)
|
||||||
|
/// </summary>
|
||||||
private readonly double maxJammingCooldown;
|
private readonly double maxJammingCooldown;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最大干扰功率(瓦特)
|
||||||
|
/// </summary>
|
||||||
private readonly double maxJammingPower;
|
private readonly double maxJammingPower;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始干扰功率(瓦特)
|
||||||
|
/// </summary>
|
||||||
private readonly double initialJammingPower;
|
private readonly double initialJammingPower;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 功率增加速率(瓦特/秒)
|
||||||
|
/// </summary>
|
||||||
private readonly double powerIncreaseRate;
|
private readonly double powerIncreaseRate;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 被监视实体的ID
|
||||||
|
/// </summary>
|
||||||
public string MonitoredEntityId { get; private set; }
|
public string MonitoredEntityId { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造函数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">激光干扰器ID</param>
|
||||||
|
/// <param name="position">初始位置</param>
|
||||||
|
/// <param name="orientation">初始朝向</param>
|
||||||
|
/// <param name="simulationManager">仿真管理器</param>
|
||||||
|
/// <param name="monitoredEntityId">被监视实体的ID</param>
|
||||||
|
/// <param name="config">激光干扰器配置</param>
|
||||||
public LaserJammer(string id, Vector3D position, Orientation orientation, ISimulationManager simulationManager, string monitoredEntityId, LaserJammerConfig config)
|
public LaserJammer(string id, Vector3D position, Orientation orientation, ISimulationManager simulationManager, string monitoredEntityId, LaserJammerConfig config)
|
||||||
: base(id, position, orientation, simulationManager)
|
: base(id, position, orientation, simulationManager)
|
||||||
{
|
{
|
||||||
@ -28,6 +71,10 @@ namespace ActiveProtect.Models
|
|||||||
SimulationManager.SubscribeToEvent<LaserWarnerAlarmStopEvent>(OnLaserWarnerAlarmStopEvent);
|
SimulationManager.SubscribeToEvent<LaserWarnerAlarmStopEvent>(OnLaserWarnerAlarmStopEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新激光干扰器状态
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="deltaTime">时间步长</param>
|
||||||
public override void Update(double deltaTime)
|
public override void Update(double deltaTime)
|
||||||
{
|
{
|
||||||
if (!IsActive) return;
|
if (!IsActive) return;
|
||||||
@ -61,6 +108,10 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 处理激光告警器警报事件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="evt">激光告警器警报事件</param>
|
||||||
private void OnLaserWarnerAlarmEvent(LaserWarnerAlarmEvent evt)
|
private void OnLaserWarnerAlarmEvent(LaserWarnerAlarmEvent evt)
|
||||||
{
|
{
|
||||||
if (evt.TargetId == MonitoredEntityId)
|
if (evt.TargetId == MonitoredEntityId)
|
||||||
@ -69,6 +120,10 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 处理激光告警器警报停止事件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="evt">激光告警器警报停止事件</param>
|
||||||
private void OnLaserWarnerAlarmStopEvent(LaserWarnerAlarmStopEvent evt)
|
private void OnLaserWarnerAlarmStopEvent(LaserWarnerAlarmStopEvent evt)
|
||||||
{
|
{
|
||||||
if (evt.TargetId == MonitoredEntityId)
|
if (evt.TargetId == MonitoredEntityId)
|
||||||
@ -77,6 +132,9 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 开始干扰
|
||||||
|
/// </summary>
|
||||||
private void StartJamming()
|
private void StartJamming()
|
||||||
{
|
{
|
||||||
if (!IsJamming)
|
if (!IsJamming)
|
||||||
@ -88,6 +146,9 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 停止干扰
|
||||||
|
/// </summary>
|
||||||
private void StopJamming()
|
private void StopJamming()
|
||||||
{
|
{
|
||||||
if (IsJamming)
|
if (IsJamming)
|
||||||
@ -99,6 +160,10 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取激光干扰器状态信息
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>状态信息字符串</returns>
|
||||||
public override string GetStatus()
|
public override string GetStatus()
|
||||||
{
|
{
|
||||||
return $"激光干扰器 {Id}:\n" +
|
return $"激光干扰器 {Id}:\n" +
|
||||||
@ -108,6 +173,9 @@ namespace ActiveProtect.Models
|
|||||||
$" 冷却时间: {jammingCooldown:F2}/{maxJammingCooldown:F2}";
|
$" 冷却时间: {jammingCooldown:F2}/{maxJammingCooldown:F2}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 停用激光干扰器
|
||||||
|
/// </summary>
|
||||||
protected override void Deactivate()
|
protected override void Deactivate()
|
||||||
{
|
{
|
||||||
base.Deactivate();
|
base.Deactivate();
|
||||||
|
|||||||
@ -3,10 +3,22 @@ using System;
|
|||||||
|
|
||||||
namespace ActiveProtect.Models
|
namespace ActiveProtect.Models
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 激光半主动制导导弹类,继承自基础导弹类
|
||||||
|
/// </summary>
|
||||||
public class LaserSemiActiveGuidedMissile : Missile
|
public class LaserSemiActiveGuidedMissile : Missile
|
||||||
{
|
{
|
||||||
private const double LaserLockDistance = 1500; // 锁定距离,单位:米
|
/// <summary>
|
||||||
|
/// 激光锁定距离(米)
|
||||||
|
/// </summary>
|
||||||
|
private const double LaserLockDistance = 1500;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造函数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">导弹ID</param>
|
||||||
|
/// <param name="missileConfig">导弹配置</param>
|
||||||
|
/// <param name="simulationManager">仿真管理器</param>
|
||||||
public LaserSemiActiveGuidedMissile(
|
public LaserSemiActiveGuidedMissile(
|
||||||
string id,
|
string id,
|
||||||
MissileConfig missileConfig,
|
MissileConfig missileConfig,
|
||||||
@ -18,6 +30,9 @@ namespace ActiveProtect.Models
|
|||||||
simulationManager.SubscribeToEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
|
simulationManager.SubscribeToEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新导弹的制导状态
|
||||||
|
/// </summary>
|
||||||
protected override void UpdateGuidanceStatus()
|
protected override void UpdateGuidanceStatus()
|
||||||
{
|
{
|
||||||
bool previousHasGuidance = HasGuidance;
|
bool previousHasGuidance = HasGuidance;
|
||||||
@ -53,6 +68,10 @@ namespace ActiveProtect.Models
|
|||||||
base.UpdateGuidanceStatus();
|
base.UpdateGuidanceStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 处理激光照射事件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="evt">激光照射事件</param>
|
||||||
private void OnLaserIllumination(LaserIlluminationEvent evt)
|
private void OnLaserIllumination(LaserIlluminationEvent evt)
|
||||||
{
|
{
|
||||||
if (evt.TargetId == TargetId)
|
if (evt.TargetId == TargetId)
|
||||||
@ -62,6 +81,10 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 处理激光照射停止事件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="evt">激光照射停止事件</param>
|
||||||
private void OnLaserIlluminationStop(LaserIlluminationStopEvent evt)
|
private void OnLaserIlluminationStop(LaserIlluminationStopEvent evt)
|
||||||
{
|
{
|
||||||
if (evt.TargetId == TargetId)
|
if (evt.TargetId == TargetId)
|
||||||
@ -71,6 +94,10 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取导弹状态信息
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>状态信息字符串</returns>
|
||||||
public override string GetStatus()
|
public override string GetStatus()
|
||||||
{
|
{
|
||||||
string baseStatus = base.GetStatus().Replace("导弹", "激光半主动制导导弹");
|
string baseStatus = base.GetStatus().Replace("导弹", "激光半主动制导导弹");
|
||||||
@ -78,6 +105,9 @@ namespace ActiveProtect.Models
|
|||||||
return baseStatus + additionalStatus;
|
return baseStatus + additionalStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 停用导弹
|
||||||
|
/// </summary>
|
||||||
protected override void Deactivate()
|
protected override void Deactivate()
|
||||||
{
|
{
|
||||||
base.Deactivate();
|
base.Deactivate();
|
||||||
|
|||||||
@ -3,13 +3,40 @@ using System;
|
|||||||
|
|
||||||
namespace ActiveProtect.Models
|
namespace ActiveProtect.Models
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 激光告警器类,用于检测激光照射并发出警报
|
||||||
|
/// </summary>
|
||||||
public class LaserWarner : SimulationElement
|
public class LaserWarner : SimulationElement
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 是否正在发出警报
|
||||||
|
/// </summary>
|
||||||
public bool IsAlarming { get; private set; }
|
public bool IsAlarming { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 警报持续时间(秒)
|
||||||
|
/// </summary>
|
||||||
private readonly double alarmDuration;
|
private readonly double alarmDuration;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前警报计时器
|
||||||
|
/// </summary>
|
||||||
private double alarmTimer = 0;
|
private double alarmTimer = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 被监视实体的ID
|
||||||
|
/// </summary>
|
||||||
public string MonitoredEntityId { get; private set; }
|
public string MonitoredEntityId { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造函数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">激光告警器ID</param>
|
||||||
|
/// <param name="position">初始位置</param>
|
||||||
|
/// <param name="orientation">初始朝向</param>
|
||||||
|
/// <param name="simulationManager">仿真管理器</param>
|
||||||
|
/// <param name="monitoredEntityId">被监视实体的ID</param>
|
||||||
|
/// <param name="config">激光告警器配置</param>
|
||||||
public LaserWarner(string id, Vector3D position, Orientation orientation, ISimulationManager simulationManager, string monitoredEntityId, LaserWarnerConfig config)
|
public LaserWarner(string id, Vector3D position, Orientation orientation, ISimulationManager simulationManager, string monitoredEntityId, LaserWarnerConfig config)
|
||||||
: base(id, position, orientation, simulationManager)
|
: base(id, position, orientation, simulationManager)
|
||||||
{
|
{
|
||||||
@ -20,6 +47,10 @@ namespace ActiveProtect.Models
|
|||||||
SimulationManager.SubscribeToEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
|
SimulationManager.SubscribeToEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新激光告警器状态
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="deltaTime">时间步长</param>
|
||||||
public override void Update(double deltaTime)
|
public override void Update(double deltaTime)
|
||||||
{
|
{
|
||||||
if (!IsActive) return;
|
if (!IsActive) return;
|
||||||
@ -41,6 +72,10 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 处理激光照射事件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="evt">激光照射事件</param>
|
||||||
private void OnLaserIllumination(LaserIlluminationEvent evt)
|
private void OnLaserIllumination(LaserIlluminationEvent evt)
|
||||||
{
|
{
|
||||||
if (evt.TargetId == MonitoredEntityId)
|
if (evt.TargetId == MonitoredEntityId)
|
||||||
@ -49,6 +84,10 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 处理激光照射停止事件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="evt">激光照射停止事件</param>
|
||||||
private void OnLaserIlluminationStop(LaserIlluminationStopEvent evt)
|
private void OnLaserIlluminationStop(LaserIlluminationStopEvent evt)
|
||||||
{
|
{
|
||||||
if (evt.TargetId == MonitoredEntityId)
|
if (evt.TargetId == MonitoredEntityId)
|
||||||
@ -57,6 +96,9 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 触发警报
|
||||||
|
/// </summary>
|
||||||
public void TriggerAlarm()
|
public void TriggerAlarm()
|
||||||
{
|
{
|
||||||
if (!IsAlarming)
|
if (!IsAlarming)
|
||||||
@ -68,6 +110,9 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 停止警报
|
||||||
|
/// </summary>
|
||||||
public void StopAlarm()
|
public void StopAlarm()
|
||||||
{
|
{
|
||||||
if (IsAlarming)
|
if (IsAlarming)
|
||||||
@ -79,6 +124,10 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取激光告警器状态信息
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>状态信息字符串</returns>
|
||||||
public override string GetStatus()
|
public override string GetStatus()
|
||||||
{
|
{
|
||||||
return $"激光告警器 {Id}:\n" +
|
return $"激光告警器 {Id}:\n" +
|
||||||
@ -87,6 +136,9 @@ namespace ActiveProtect.Models
|
|||||||
$" 警报持续时间: {(IsAlarming ? alarmTimer : 0):F2}/{alarmDuration:F2}";
|
$" 警报持续时间: {(IsAlarming ? alarmTimer : 0):F2}/{alarmDuration:F2}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 停用激光告警器
|
||||||
|
/// </summary>
|
||||||
protected override void Deactivate()
|
protected override void Deactivate()
|
||||||
{
|
{
|
||||||
base.Deactivate();
|
base.Deactivate();
|
||||||
|
|||||||
@ -12,44 +12,142 @@ namespace ActiveProtect.Models
|
|||||||
/// 导弹类型
|
/// 导弹类型
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public MissileType Type { get; protected set; }
|
public MissileType Type { get; protected set; }
|
||||||
public double Speed { get; protected set; }
|
|
||||||
public double MaxSpeed { get; protected set; }
|
|
||||||
public string TargetId { get; protected set; }
|
|
||||||
public double MaxFlightTime { get; protected set; }
|
|
||||||
public double MaxFlightDistance { get; protected set; }
|
|
||||||
public double FlightTime { get; protected set; }
|
|
||||||
public double FlightDistance { get; protected set; }
|
|
||||||
public double DistanceToTarget { get; protected set; }
|
|
||||||
public MissileDistanceParams DistanceParams { get; protected set; }
|
|
||||||
public FlightStageConfig StageConfig { get; protected set; }
|
|
||||||
public FlightStage CurrentStage { get; protected set; }
|
|
||||||
protected Vector3D Velocity;
|
|
||||||
private Vector3D LastTargetPosition;
|
|
||||||
private const double N = 3; // 比例导引系数
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前速度(米/秒)
|
||||||
|
/// </summary>
|
||||||
|
public double Speed { get; protected set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最大速度(米/秒)
|
||||||
|
/// </summary>
|
||||||
|
public double MaxSpeed { get; protected set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 目标ID
|
||||||
|
/// </summary>
|
||||||
|
public string TargetId { get; protected set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最大飞行时间(秒)
|
||||||
|
/// </summary>
|
||||||
|
public double MaxFlightTime { get; protected set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最大飞行距离(米)
|
||||||
|
/// </summary>
|
||||||
|
public double MaxFlightDistance { get; protected set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前飞行时间(秒)
|
||||||
|
/// </summary>
|
||||||
|
public double FlightTime { get; protected set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前飞行距离(米)
|
||||||
|
/// </summary>
|
||||||
|
public double FlightDistance { get; protected set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 与目标的距离(米)
|
||||||
|
/// </summary>
|
||||||
|
public double DistanceToTarget { get; protected set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 导弹距离参数
|
||||||
|
/// </summary>
|
||||||
|
public MissileDistanceParams DistanceParams { get; protected set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 飞行阶段配置
|
||||||
|
/// </summary>
|
||||||
|
public FlightStageConfig StageConfig { get; protected set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前飞行阶段
|
||||||
|
/// </summary>
|
||||||
|
public FlightStage CurrentStage { get; protected set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 导弹速度向量
|
||||||
|
/// </summary>
|
||||||
|
protected Vector3D Velocity;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 上一帧目标位置
|
||||||
|
/// </summary>
|
||||||
|
private Vector3D LastTargetPosition;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 比例导引系数
|
||||||
|
/// </summary>
|
||||||
|
private const double N = 3;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 推力加速度(米/秒²)
|
||||||
|
/// </summary>
|
||||||
public double ThrustAcceleration { get; protected set; }
|
public double ThrustAcceleration { get; protected set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前发动机燃烧时间(秒)
|
||||||
|
/// </summary>
|
||||||
public double EngineBurnTime { get; protected set; }
|
public double EngineBurnTime { get; protected set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最大发动机燃烧时间(秒)
|
||||||
|
/// </summary>
|
||||||
public double MaxEngineBurnTime { get; protected set; }
|
public double MaxEngineBurnTime { get; protected set; }
|
||||||
|
|
||||||
public double MaxAcceleration { get; protected set; } = 100; // m/s^2
|
/// <summary>
|
||||||
|
/// 最大加速度(米/秒²)
|
||||||
|
/// </summary>
|
||||||
|
public double MaxAcceleration { get; protected set; } = 100;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 比例导引系数
|
||||||
|
/// </summary>
|
||||||
public double ProportionalNavigationCoefficient { get; set; }
|
public double ProportionalNavigationCoefficient { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否有制导
|
||||||
|
/// </summary>
|
||||||
public bool HasGuidance { get; protected set; } = false;
|
public bool HasGuidance { get; protected set; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 失去制导的时间(秒)
|
||||||
|
/// </summary>
|
||||||
protected double LostGuidanceTime { get; set; } = 0;
|
protected double LostGuidanceTime { get; set; } = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最后已知的速度向量
|
||||||
|
/// </summary>
|
||||||
protected Vector3D LastKnownVelocity = Vector3D.Zero;
|
protected Vector3D LastKnownVelocity = Vector3D.Zero;
|
||||||
public const double LAUNCH_SPEED = 10; // 发射速度,单位:m/s
|
|
||||||
public const double LAUNCH_DURATION = 0.5; // 发射阶持续时间,单位:秒
|
/// <summary>
|
||||||
|
/// 发射速度(米/秒)
|
||||||
|
/// </summary>
|
||||||
|
public const double LAUNCH_SPEED = 10;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发射阶段持续时间(秒)
|
||||||
|
/// </summary>
|
||||||
|
public const double LAUNCH_DURATION = 0.5;
|
||||||
|
|
||||||
private IMissileStageStrategy currentStage;
|
private IMissileStageStrategy currentStage;
|
||||||
private Dictionary<FlightStage, IMissileStageStrategy> stageStrategies;
|
private Dictionary<FlightStage, IMissileStageStrategy> stageStrategies;
|
||||||
|
|
||||||
// 添加质量属性
|
/// <summary>
|
||||||
public double Mass { get; protected set; } = 100; // 默认质量为100kg,可以根据需要调整
|
/// 导弹质量(千克)
|
||||||
|
/// </summary>
|
||||||
|
public double Mass { get; protected set; } = 100;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造函数
|
||||||
|
/// </summary>
|
||||||
public Missile(string id, MissileConfig missileConfig, ISimulationManager simulationManager)
|
public Missile(string id, MissileConfig missileConfig, ISimulationManager simulationManager)
|
||||||
: base(id, missileConfig.InitialPosition, missileConfig.InitialOrientation, simulationManager)
|
: base(id, missileConfig.InitialPosition, missileConfig.InitialOrientation, simulationManager)
|
||||||
{
|
{
|
||||||
|
// 初始化导弹属性
|
||||||
Speed = missileConfig.InitialSpeed;
|
Speed = missileConfig.InitialSpeed;
|
||||||
MaxSpeed = missileConfig.MaxSpeed;
|
MaxSpeed = missileConfig.MaxSpeed;
|
||||||
MaxFlightTime = missileConfig.MaxFlightTime;
|
MaxFlightTime = missileConfig.MaxFlightTime;
|
||||||
@ -84,11 +182,14 @@ namespace ActiveProtect.Models
|
|||||||
|
|
||||||
currentStage = stageStrategies[CurrentStage];
|
currentStage = stageStrategies[CurrentStage];
|
||||||
|
|
||||||
LastTargetPosition = Position; // 初始化 LastTargetPosition
|
LastTargetPosition = Position;
|
||||||
|
|
||||||
DistanceToTarget = Vector3D.Distance(Position, SimulationManager.GetEntityById(TargetId).Position);
|
DistanceToTarget = Vector3D.Distance(Position, SimulationManager.GetEntityById(TargetId).Position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置导弹的初始飞行阶段
|
||||||
|
/// </summary>
|
||||||
private void SetInitialStage()
|
private void SetInitialStage()
|
||||||
{
|
{
|
||||||
if (StageConfig.EnableLaunch) CurrentStage = FlightStage.Launch;
|
if (StageConfig.EnableLaunch) CurrentStage = FlightStage.Launch;
|
||||||
@ -100,6 +201,9 @@ namespace ActiveProtect.Models
|
|||||||
Console.WriteLine($"导弹 {Id} 的初始阶段: {CurrentStage}");
|
Console.WriteLine($"导弹 {Id} 的初始阶段: {CurrentStage}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新导弹状态
|
||||||
|
/// </summary>
|
||||||
public override void Update(double deltaTime)
|
public override void Update(double deltaTime)
|
||||||
{
|
{
|
||||||
if (!IsActive) return;
|
if (!IsActive) return;
|
||||||
@ -129,6 +233,9 @@ namespace ActiveProtect.Models
|
|||||||
currentStage.Update(deltaTime);
|
currentStage.Update(deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 切换导弹飞行阶段
|
||||||
|
/// </summary>
|
||||||
public void ChangeStage(FlightStage newStage)
|
public void ChangeStage(FlightStage newStage)
|
||||||
{
|
{
|
||||||
if (stageStrategies.TryGetValue(newStage, out var strategy))
|
if (stageStrategies.TryGetValue(newStage, out var strategy))
|
||||||
@ -151,6 +258,9 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检查指定飞行阶段是否启用
|
||||||
|
/// </summary>
|
||||||
private bool IsStageEnabled(FlightStage stage)
|
private bool IsStageEnabled(FlightStage stage)
|
||||||
{
|
{
|
||||||
return stage switch
|
return stage switch
|
||||||
@ -164,6 +274,9 @@ namespace ActiveProtect.Models
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 尝试切换到下一个可用的飞行阶段
|
||||||
|
/// </summary>
|
||||||
private void TryChangeToNextAvailableStage(FlightStage startStage)
|
private void TryChangeToNextAvailableStage(FlightStage startStage)
|
||||||
{
|
{
|
||||||
FlightStage[] stageOrder = [FlightStage.Launch, FlightStage.Acceleration, FlightStage.Cruise, FlightStage.TerminalGuidance, FlightStage.Attack];
|
FlightStage[] stageOrder = [FlightStage.Launch, FlightStage.Acceleration, FlightStage.Cruise, FlightStage.TerminalGuidance, FlightStage.Attack];
|
||||||
@ -183,6 +296,9 @@ namespace ActiveProtect.Models
|
|||||||
SelfDestruct();
|
SelfDestruct();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算导弹的加速度
|
||||||
|
/// </summary>
|
||||||
private (Vector3D, Vector3D) CalculateDerivatives(Vector3D position, Vector3D velocity, double deltaTime)
|
private (Vector3D, Vector3D) CalculateDerivatives(Vector3D position, Vector3D velocity, double deltaTime)
|
||||||
{
|
{
|
||||||
Vector3D guidanceAcceleration = Vector3D.Zero;
|
Vector3D guidanceAcceleration = Vector3D.Zero;
|
||||||
@ -241,9 +357,11 @@ namespace ActiveProtect.Models
|
|||||||
return (velocity, totalAcceleration);
|
return (velocity, totalAcceleration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算空气阻力
|
||||||
|
/// </summary>
|
||||||
private static double CalculateDrag(double speed)
|
private static double CalculateDrag(double speed)
|
||||||
{
|
{
|
||||||
// 修改空气阻力计算
|
|
||||||
const double dragCoefficient = 0.1; // 减小阻力系数
|
const double dragCoefficient = 0.1; // 减小阻力系数
|
||||||
const double airDensity = 1.225; // 海平面空气密度,kg/m^3
|
const double airDensity = 1.225; // 海平面空气密度,kg/m^3
|
||||||
const double referenceArea = 0.01; // 减小导弹的参考面积,m^2
|
const double referenceArea = 0.01; // 减小导弹的参考面积,m^2
|
||||||
@ -251,7 +369,9 @@ namespace ActiveProtect.Models
|
|||||||
return 0.5 * dragCoefficient * airDensity * referenceArea * speed * speed;
|
return 0.5 * dragCoefficient * airDensity * referenceArea * speed * speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用 Runge-Kutta 方法更新位置和速度
|
/// <summary>
|
||||||
|
/// 使用 Runge-Kutta 方法更新位置和速度
|
||||||
|
/// </summary>
|
||||||
private (Vector3D, Vector3D) UpdatePositionAndVelocityRK4(double deltaTime)
|
private (Vector3D, Vector3D) UpdatePositionAndVelocityRK4(double deltaTime)
|
||||||
{
|
{
|
||||||
Vector3D k1, k2, k3, k4;
|
Vector3D k1, k2, k3, k4;
|
||||||
@ -274,13 +394,17 @@ namespace ActiveProtect.Models
|
|||||||
return (newPosition, newVelocity);
|
return (newPosition, newVelocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查是否命中目标
|
/// <summary>
|
||||||
|
/// 检查是否命中目标
|
||||||
|
/// </summary>
|
||||||
private bool CheckHit()
|
private bool CheckHit()
|
||||||
{
|
{
|
||||||
return DistanceToTarget <= DistanceParams.ExplosionDistance;
|
return DistanceToTarget <= DistanceParams.ExplosionDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查是否应该自毁
|
/// <summary>
|
||||||
|
/// 检查是否应该自毁
|
||||||
|
/// </summary>
|
||||||
private bool ShouldSelfDestruct()
|
private bool ShouldSelfDestruct()
|
||||||
{
|
{
|
||||||
if (FlightTime >= MaxFlightTime)
|
if (FlightTime >= MaxFlightTime)
|
||||||
@ -301,7 +425,9 @@ namespace ActiveProtect.Models
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新发动机燃烧时间
|
/// <summary>
|
||||||
|
/// 更新发动机燃烧时间
|
||||||
|
/// </summary>
|
||||||
private void UpdateEngineBurnTime(double deltaTime)
|
private void UpdateEngineBurnTime(double deltaTime)
|
||||||
{
|
{
|
||||||
if (CurrentStage == FlightStage.Acceleration && EngineBurnTime < MaxEngineBurnTime)
|
if (CurrentStage == FlightStage.Acceleration && EngineBurnTime < MaxEngineBurnTime)
|
||||||
@ -310,8 +436,9 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
// 计算比例导引加速度
|
/// 计算比例导引加速度
|
||||||
|
/// </summary>
|
||||||
private Vector3D CalculateProportionalNavigation(Vector3D position)
|
private Vector3D CalculateProportionalNavigation(Vector3D position)
|
||||||
{
|
{
|
||||||
Vector3D targetPosition = SimulationManager.GetEntityById(TargetId).Position;
|
Vector3D targetPosition = SimulationManager.GetEntityById(TargetId).Position;
|
||||||
@ -323,7 +450,9 @@ namespace ActiveProtect.Models
|
|||||||
* ProportionalNavigationCoefficient * Velocity.Magnitude();
|
* ProportionalNavigationCoefficient * Velocity.Magnitude();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 爆炸
|
/// <summary>
|
||||||
|
/// 导弹爆炸
|
||||||
|
/// </summary>
|
||||||
public void Explode()
|
public void Explode()
|
||||||
{
|
{
|
||||||
Deactivate();
|
Deactivate();
|
||||||
@ -331,7 +460,9 @@ namespace ActiveProtect.Models
|
|||||||
Console.WriteLine($"导弹 {Id} 在 {Position} 爆炸,命中目标!");
|
Console.WriteLine($"导弹 {Id} 在 {Position} 爆炸,命中目标!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 自毁
|
/// <summary>
|
||||||
|
/// 导弹自毁
|
||||||
|
/// </summary>
|
||||||
public void SelfDestruct()
|
public void SelfDestruct()
|
||||||
{
|
{
|
||||||
if (IsActive)
|
if (IsActive)
|
||||||
@ -346,14 +477,18 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置比例导引系数
|
/// <summary>
|
||||||
|
/// 设置比例导引系数
|
||||||
|
/// </summary>
|
||||||
public void SetProportionalNavigationCoefficient(double newCoefficient)
|
public void SetProportionalNavigationCoefficient(double newCoefficient)
|
||||||
{
|
{
|
||||||
ProportionalNavigationCoefficient = newCoefficient;
|
ProportionalNavigationCoefficient = newCoefficient;
|
||||||
Console.WriteLine($"导弹 {Id} 的比例导引系数已更新为 {newCoefficient}");
|
Console.WriteLine($"导弹 {Id} 的比例导引系数已更新为 {newCoefficient}");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取导弹状态
|
/// <summary>
|
||||||
|
/// 获取导弹状态
|
||||||
|
/// </summary>
|
||||||
public override string GetStatus()
|
public override string GetStatus()
|
||||||
{
|
{
|
||||||
return $"导弹 {Id}:\n" +
|
return $"导弹 {Id}:\n" +
|
||||||
@ -368,24 +503,34 @@ namespace ActiveProtect.Models
|
|||||||
$" 失去引导时间: {LostGuidanceTime:F2}";
|
$" 失去引导时间: {LostGuidanceTime:F2}";
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加新的方法来更新引导状态
|
/// <summary>
|
||||||
|
/// 更新导弹的制导状态
|
||||||
|
/// </summary>
|
||||||
protected virtual void UpdateGuidanceStatus()
|
protected virtual void UpdateGuidanceStatus()
|
||||||
{
|
{
|
||||||
// 基类中的默认实现
|
// 基类中的默认实现
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前飞行阶段的名称
|
||||||
|
/// </summary>
|
||||||
public string GetCurrentStateName()
|
public string GetCurrentStateName()
|
||||||
{
|
{
|
||||||
return currentStage.GetType().Name;
|
return currentStage.GetType().Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 导弹飞行阶段策略接口
|
||||||
|
/// </summary>
|
||||||
public interface IMissileStageStrategy
|
public interface IMissileStageStrategy
|
||||||
{
|
{
|
||||||
void Update(double deltaTime);
|
void Update(double deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发射阶段策略
|
||||||
|
/// </summary>
|
||||||
public class LaunchStageStrategy : IMissileStageStrategy
|
public class LaunchStageStrategy : IMissileStageStrategy
|
||||||
{
|
{
|
||||||
private readonly Missile missile;
|
private readonly Missile missile;
|
||||||
@ -406,6 +551,9 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 加速阶段策略
|
||||||
|
/// </summary>
|
||||||
public class AccelerationStageStrategy(Missile missile) : IMissileStageStrategy
|
public class AccelerationStageStrategy(Missile missile) : IMissileStageStrategy
|
||||||
{
|
{
|
||||||
private readonly Missile missile = missile;
|
private readonly Missile missile = missile;
|
||||||
@ -419,6 +567,9 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 巡航阶段策略
|
||||||
|
/// </summary>
|
||||||
public class CruiseStageStrategy(Missile missile) : IMissileStageStrategy
|
public class CruiseStageStrategy(Missile missile) : IMissileStageStrategy
|
||||||
{
|
{
|
||||||
private readonly Missile missile = missile;
|
private readonly Missile missile = missile;
|
||||||
@ -432,6 +583,9 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 终端制导阶段策略
|
||||||
|
/// </summary>
|
||||||
public class TerminalGuidanceStageStrategy(Missile missile) : IMissileStageStrategy
|
public class TerminalGuidanceStageStrategy(Missile missile) : IMissileStageStrategy
|
||||||
{
|
{
|
||||||
private readonly Missile missile = missile;
|
private readonly Missile missile = missile;
|
||||||
@ -445,6 +599,9 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 攻击阶段策略
|
||||||
|
/// </summary>
|
||||||
public class AttackStageStrategy(Missile missile) : IMissileStageStrategy
|
public class AttackStageStrategy(Missile missile) : IMissileStageStrategy
|
||||||
{
|
{
|
||||||
private readonly Missile missile = missile;
|
private readonly Missile missile = missile;
|
||||||
@ -458,6 +615,9 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 无制导阶段策略
|
||||||
|
/// </summary>
|
||||||
public class UnguidedStageStrategy(Missile missile) : IMissileStageStrategy
|
public class UnguidedStageStrategy(Missile missile) : IMissileStageStrategy
|
||||||
{
|
{
|
||||||
private readonly Missile missile = missile;
|
private readonly Missile missile = missile;
|
||||||
|
|||||||
@ -3,22 +3,51 @@ using System;
|
|||||||
|
|
||||||
namespace ActiveProtect.Models
|
namespace ActiveProtect.Models
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 表示仿真中的坦克
|
||||||
|
/// </summary>
|
||||||
public class Tank(string id, TankConfig tankConfig, ISimulationManager simulationManager) : SimulationElement(id, tankConfig.InitialPosition, tankConfig.InitialOrientation, simulationManager), ILaserIlluminatable
|
public class Tank(string id, TankConfig tankConfig, ISimulationManager simulationManager) : SimulationElement(id, tankConfig.InitialPosition, tankConfig.InitialOrientation, simulationManager), ILaserIlluminatable
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 当前速度(米/秒)
|
||||||
|
/// </summary>
|
||||||
public double Speed { get; set; } = tankConfig.InitialSpeed;
|
public double Speed { get; set; } = tankConfig.InitialSpeed;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最大速度(米/秒)
|
||||||
|
/// </summary>
|
||||||
public double MaxSpeed { get; private set; } = tankConfig.MaxSpeed;
|
public double MaxSpeed { get; private set; } = tankConfig.MaxSpeed;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最大装甲值
|
||||||
|
/// </summary>
|
||||||
public double MaxArmor { get; private set; } = tankConfig.MaxArmor;
|
public double MaxArmor { get; private set; } = tankConfig.MaxArmor;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前装甲值
|
||||||
|
/// </summary>
|
||||||
public double CurrentArmor { get; private set; } = tankConfig.MaxArmor;
|
public double CurrentArmor { get; private set; } = tankConfig.MaxArmor;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否被激光照射
|
||||||
|
/// </summary>
|
||||||
public bool IsIlluminated { get; private set; } = false;
|
public bool IsIlluminated { get; private set; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新坦克状态
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="deltaTime">时间步长(秒)</param>
|
||||||
public override void Update(double deltaTime)
|
public override void Update(double deltaTime)
|
||||||
{
|
{
|
||||||
if (!IsActive) return;
|
if (!IsActive) return;
|
||||||
|
|
||||||
UpdatePosition(deltaTime);
|
UpdatePosition(deltaTime);
|
||||||
// 移除发布坦克位置更新事件的代码
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新坦克位置
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="deltaTime">时间步长(秒)</param>
|
||||||
private void UpdatePosition(double deltaTime)
|
private void UpdatePosition(double deltaTime)
|
||||||
{
|
{
|
||||||
Vector3D direction = Orientation.ToVector();
|
Vector3D direction = Orientation.ToVector();
|
||||||
@ -26,6 +55,11 @@ namespace ActiveProtect.Models
|
|||||||
Position += movement;
|
Position += movement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 坦克受到伤害
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="damage">伤害值</param>
|
||||||
|
/// <param name="isMissileDamage">是否为导弹造成的伤害</param>
|
||||||
public void TakeDamage(double damage, bool isMissileDamage = false)
|
public void TakeDamage(double damage, bool isMissileDamage = false)
|
||||||
{
|
{
|
||||||
if (isMissileDamage)
|
if (isMissileDamage)
|
||||||
@ -40,6 +74,9 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 被激光照射
|
||||||
|
/// </summary>
|
||||||
public void Illuminate()
|
public void Illuminate()
|
||||||
{
|
{
|
||||||
if (!IsIlluminated)
|
if (!IsIlluminated)
|
||||||
@ -49,6 +86,9 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 停止激光照射
|
||||||
|
/// </summary>
|
||||||
public void StopIllumination()
|
public void StopIllumination()
|
||||||
{
|
{
|
||||||
if (IsIlluminated)
|
if (IsIlluminated)
|
||||||
@ -58,6 +98,10 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取坦克状态信息
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>坦克状态字符串</returns>
|
||||||
public override string GetStatus()
|
public override string GetStatus()
|
||||||
{
|
{
|
||||||
return $"坦克 {Id}:\n" +
|
return $"坦克 {Id}:\n" +
|
||||||
|
|||||||
@ -12,6 +12,7 @@ namespace ActiveProtect
|
|||||||
// 创建仿真配置
|
// 创建仿真配置
|
||||||
var config = new SimulationConfig
|
var config = new SimulationConfig
|
||||||
{
|
{
|
||||||
|
// 配置坦克
|
||||||
TankConfigs =
|
TankConfigs =
|
||||||
[
|
[
|
||||||
new() {
|
new() {
|
||||||
@ -24,10 +25,12 @@ namespace ActiveProtect
|
|||||||
HasLaserJammer = true
|
HasLaserJammer = true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
// 配置激光告警器
|
||||||
LaserWarnerConfig = new LaserWarnerConfig
|
LaserWarnerConfig = new LaserWarnerConfig
|
||||||
{
|
{
|
||||||
AlarmDuration = 5.0
|
AlarmDuration = 5.0
|
||||||
},
|
},
|
||||||
|
// 配置激光干扰器
|
||||||
LaserJammerConfig = new LaserJammerConfig
|
LaserJammerConfig = new LaserJammerConfig
|
||||||
{
|
{
|
||||||
MaxJammingCooldown = 5.0,
|
MaxJammingCooldown = 5.0,
|
||||||
@ -35,6 +38,7 @@ namespace ActiveProtect
|
|||||||
InitialJammingPower = 4000.0,
|
InitialJammingPower = 4000.0,
|
||||||
PowerIncreaseRate = 2000.0
|
PowerIncreaseRate = 2000.0
|
||||||
},
|
},
|
||||||
|
// 配置导弹
|
||||||
MissileConfigs =
|
MissileConfigs =
|
||||||
[
|
[
|
||||||
// 标准导弹配置
|
// 标准导弹配置
|
||||||
@ -110,6 +114,7 @@ namespace ActiveProtect
|
|||||||
Type = MissileType.LaserSemiActiveGuidance
|
Type = MissileType.LaserSemiActiveGuidance
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
// 配置激光指示器
|
||||||
LaserDesignatorConfigs =
|
LaserDesignatorConfigs =
|
||||||
[
|
[
|
||||||
new LaserDesignatorConfig
|
new LaserDesignatorConfig
|
||||||
|
|||||||
@ -3,15 +3,44 @@ using ActiveProtect.Models;
|
|||||||
|
|
||||||
namespace ActiveProtect.SimulationEnvironment
|
namespace ActiveProtect.SimulationEnvironment
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 仿真配置类,包含整个仿真所需的所有配置信息
|
||||||
|
/// </summary>
|
||||||
public class SimulationConfig
|
public class SimulationConfig
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 坦克配置列表
|
||||||
|
/// </summary>
|
||||||
public List<TankConfig> TankConfigs { get; set; }
|
public List<TankConfig> TankConfigs { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 导弹配置列表
|
||||||
|
/// </summary>
|
||||||
public List<MissileConfig> MissileConfigs { get; set; }
|
public List<MissileConfig> MissileConfigs { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 激光指示器配置列表
|
||||||
|
/// </summary>
|
||||||
public List<LaserDesignatorConfig> LaserDesignatorConfigs { get; set; }
|
public List<LaserDesignatorConfig> LaserDesignatorConfigs { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 激光告警器配置
|
||||||
|
/// </summary>
|
||||||
public LaserWarnerConfig LaserWarnerConfig { get; set; }
|
public LaserWarnerConfig LaserWarnerConfig { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 激光干扰器配置
|
||||||
|
/// </summary>
|
||||||
public LaserJammerConfig LaserJammerConfig { get; set; }
|
public LaserJammerConfig LaserJammerConfig { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 仿真时间步长(秒)
|
||||||
|
/// </summary>
|
||||||
public double SimulationTimeStep { get; set; }
|
public double SimulationTimeStep { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造函数,初始化默认配置
|
||||||
|
/// </summary>
|
||||||
public SimulationConfig()
|
public SimulationConfig()
|
||||||
{
|
{
|
||||||
TankConfigs = [];
|
TankConfigs = [];
|
||||||
@ -23,17 +52,49 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 坦克配置类
|
||||||
|
/// </summary>
|
||||||
public class TankConfig
|
public class TankConfig
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 初始位置
|
||||||
|
/// </summary>
|
||||||
public Vector3D InitialPosition { get; set; }
|
public Vector3D InitialPosition { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始朝向
|
||||||
|
/// </summary>
|
||||||
public Orientation InitialOrientation { get; set; }
|
public Orientation InitialOrientation { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始速度(米/秒)
|
||||||
|
/// </summary>
|
||||||
public double InitialSpeed { get; set; }
|
public double InitialSpeed { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最大速度(米/秒)
|
||||||
|
/// </summary>
|
||||||
public double MaxSpeed { get; set; }
|
public double MaxSpeed { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最大装甲值
|
||||||
|
/// </summary>
|
||||||
public double MaxArmor { get; set; }
|
public double MaxArmor { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否装备激光告警器
|
||||||
|
/// </summary>
|
||||||
public bool HasLaserWarner { get; set; }
|
public bool HasLaserWarner { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否装备激光干扰器
|
||||||
|
/// </summary>
|
||||||
public bool HasLaserJammer { get; set; }
|
public bool HasLaserJammer { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造函数,设置默认值
|
||||||
|
/// </summary>
|
||||||
public TankConfig()
|
public TankConfig()
|
||||||
{
|
{
|
||||||
InitialPosition = new Vector3D(0, 0, 0);
|
InitialPosition = new Vector3D(0, 0, 0);
|
||||||
@ -41,47 +102,126 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 导弹配置类
|
||||||
|
/// </summary>
|
||||||
public class MissileConfig
|
public class MissileConfig
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 初始位置
|
||||||
|
/// </summary>
|
||||||
public Vector3D InitialPosition { get; set; }
|
public Vector3D InitialPosition { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始朝向
|
||||||
|
/// </summary>
|
||||||
public Orientation InitialOrientation { get; set; }
|
public Orientation InitialOrientation { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始速度(米/秒)
|
||||||
|
/// </summary>
|
||||||
public double InitialSpeed { get; set; }
|
public double InitialSpeed { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最大速度(米/秒)
|
||||||
|
/// </summary>
|
||||||
public double MaxSpeed { get; set; }
|
public double MaxSpeed { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 目标索引
|
||||||
|
/// </summary>
|
||||||
public int TargetIndex { get; set; }
|
public int TargetIndex { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最大飞行时间(秒)
|
||||||
|
/// </summary>
|
||||||
public double MaxFlightTime { get; set; }
|
public double MaxFlightTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最大飞行距离(米)
|
||||||
|
/// </summary>
|
||||||
public double MaxFlightDistance { get; set; }
|
public double MaxFlightDistance { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最大加速度(米/秒²)
|
||||||
|
/// </summary>
|
||||||
public double MaxAcceleration { get; set; }
|
public double MaxAcceleration { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 比例导引系数
|
||||||
|
/// </summary>
|
||||||
public double ProportionalNavigationCoefficient { get; set; }
|
public double ProportionalNavigationCoefficient { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 飞行阶段配置
|
||||||
|
/// </summary>
|
||||||
public FlightStageConfig StageConfig { get; set; }
|
public FlightStageConfig StageConfig { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 距离参数
|
||||||
|
/// </summary>
|
||||||
public MissileDistanceParams DistanceParams { get; set; }
|
public MissileDistanceParams DistanceParams { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 推力加速度(米/秒²)
|
||||||
|
/// </summary>
|
||||||
public double ThrustAcceleration { get; set; }
|
public double ThrustAcceleration { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最大发动机燃烧时间(秒)
|
||||||
|
/// </summary>
|
||||||
public double MaxEngineBurnTime { get; set; }
|
public double MaxEngineBurnTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 导弹质量(千克)
|
||||||
|
/// </summary>
|
||||||
public double Mass { get; set; }
|
public double Mass { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 导弹类型
|
||||||
|
/// </summary>
|
||||||
public MissileType Type { get; set; }
|
public MissileType Type { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造函数,设置默认值
|
||||||
|
/// </summary>
|
||||||
public MissileConfig()
|
public MissileConfig()
|
||||||
{
|
{
|
||||||
InitialPosition = new Vector3D(0, 0, 0); // 初始位
|
InitialPosition = new Vector3D(0, 0, 0);
|
||||||
InitialOrientation = new Orientation(0, 0, 0); // 初始方向
|
InitialOrientation = new Orientation(0, 0, 0);
|
||||||
InitialSpeed = 0; // 初始速度
|
InitialSpeed = 0;
|
||||||
MaxSpeed = 0; // 最大速度
|
MaxSpeed = 0;
|
||||||
TargetIndex = 0; // 目标索引
|
TargetIndex = 0;
|
||||||
MaxFlightTime = 0; // 最大飞行时间
|
MaxFlightTime = 0;
|
||||||
MaxFlightDistance = 0; // 最大飞行距离
|
MaxFlightDistance = 0;
|
||||||
StageConfig = FlightStageConfig.StandardMissile; // 飞行阶段配置
|
StageConfig = FlightStageConfig.StandardMissile;
|
||||||
ThrustAcceleration = 0; // 推力加速度
|
ThrustAcceleration = 0;
|
||||||
MaxEngineBurnTime = 0; // 最大发动机燃烧时间
|
MaxEngineBurnTime = 0;
|
||||||
MaxAcceleration = 0; // 最大加速度
|
MaxAcceleration = 0;
|
||||||
DistanceParams = new MissileDistanceParams(0, 0, 0); // 距离参数
|
DistanceParams = new MissileDistanceParams(0, 0, 0);
|
||||||
ProportionalNavigationCoefficient = 0; // 比例导引系数
|
ProportionalNavigationCoefficient = 0;
|
||||||
Type = MissileType.StandardMissile; // 导弹类型
|
Type = MissileType.StandardMissile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 激光指示器配置类
|
||||||
|
/// </summary>
|
||||||
public class LaserDesignatorConfig
|
public class LaserDesignatorConfig
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 初始位置
|
||||||
|
/// </summary>
|
||||||
public Vector3D InitialPosition { get; set; }
|
public Vector3D InitialPosition { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最大照射范围(米)
|
||||||
|
/// </summary>
|
||||||
public double MaxIlluminationRange { get; set; }
|
public double MaxIlluminationRange { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造函数,设置默认值
|
||||||
|
/// </summary>
|
||||||
public LaserDesignatorConfig()
|
public LaserDesignatorConfig()
|
||||||
{
|
{
|
||||||
InitialPosition = new Vector3D(0, 0, 0);
|
InitialPosition = new Vector3D(0, 0, 0);
|
||||||
@ -89,6 +229,9 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 导弹类型枚举
|
||||||
|
/// </summary>
|
||||||
public enum MissileType
|
public enum MissileType
|
||||||
{
|
{
|
||||||
StandardMissile, // 标准导弹
|
StandardMissile, // 标准导弹
|
||||||
@ -99,15 +242,29 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
MillimeterWaveTerminalGuidance // 毫米波末制导
|
MillimeterWaveTerminalGuidance // 毫米波末制导
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 导弹距离参数结构
|
||||||
|
/// </summary>
|
||||||
public struct MissileDistanceParams(double terminalGuidanceDistance, double attackDistance, double explosionDistance)
|
public struct MissileDistanceParams(double terminalGuidanceDistance, double attackDistance, double explosionDistance)
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 终端制导距离(米)
|
||||||
|
/// </summary>
|
||||||
public double TerminalGuidanceDistance { get; set; } = terminalGuidanceDistance;
|
public double TerminalGuidanceDistance { get; set; } = terminalGuidanceDistance;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 攻击距离(米)
|
||||||
|
/// </summary>
|
||||||
public double AttackDistance { get; set; } = attackDistance;
|
public double AttackDistance { get; set; } = attackDistance;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 爆炸距离(米)
|
||||||
|
/// </summary>
|
||||||
public double ExplosionDistance { get; set; } = explosionDistance;
|
public double ExplosionDistance { get; set; } = explosionDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 导弹飞行的各个阶段
|
/// 导弹飞行阶段枚举
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public enum FlightStage
|
public enum FlightStage
|
||||||
{
|
{
|
||||||
@ -120,11 +277,8 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 导弹飞行阶段的配置结构
|
/// 导弹飞行阶段配置结构
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
|
||||||
/// 初始化飞行阶段配置
|
|
||||||
/// </remarks>
|
|
||||||
public struct FlightStageConfig(bool enableLaunch = true, bool enableAcceleration = true, bool enableCruise = true,
|
public struct FlightStageConfig(bool enableLaunch = true, bool enableAcceleration = true, bool enableCruise = true,
|
||||||
bool enableTerminalGuidance = true, bool enableAttack = true)
|
bool enableTerminalGuidance = true, bool enableAttack = true)
|
||||||
{
|
{
|
||||||
@ -165,23 +319,53 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
public static FlightStageConfig MillimeterWaveTerminalGuidance => new(true, true, true, true, true);
|
public static FlightStageConfig MillimeterWaveTerminalGuidance => new(true, true, true, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 激光告警器配置类
|
||||||
|
/// </summary>
|
||||||
public class LaserWarnerConfig
|
public class LaserWarnerConfig
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 警报持续时间(秒)
|
||||||
|
/// </summary>
|
||||||
public double AlarmDuration { get; set; }
|
public double AlarmDuration { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造函数,设置默认值
|
||||||
|
/// </summary>
|
||||||
public LaserWarnerConfig()
|
public LaserWarnerConfig()
|
||||||
{
|
{
|
||||||
AlarmDuration = 5.0; // 默认警报持续5秒
|
AlarmDuration = 5.0; // 默认警报持续5秒
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 激光干扰器配置类
|
||||||
|
/// </summary>
|
||||||
public class LaserJammerConfig
|
public class LaserJammerConfig
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 最大干扰冷却时间(秒)
|
||||||
|
/// </summary>
|
||||||
public double MaxJammingCooldown { get; set; }
|
public double MaxJammingCooldown { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最大干扰功率(瓦特)
|
||||||
|
/// </summary>
|
||||||
public double MaxJammingPower { get; set; }
|
public double MaxJammingPower { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始干扰功率(瓦特)
|
||||||
|
/// </summary>
|
||||||
public double InitialJammingPower { get; set; }
|
public double InitialJammingPower { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 功率增加速率(瓦特/秒)
|
||||||
|
/// </summary>
|
||||||
public double PowerIncreaseRate { get; set; }
|
public double PowerIncreaseRate { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造函数,设置默认值
|
||||||
|
/// </summary>
|
||||||
public LaserJammerConfig()
|
public LaserJammerConfig()
|
||||||
{
|
{
|
||||||
MaxJammingCooldown = 5.0;
|
MaxJammingCooldown = 5.0;
|
||||||
|
|||||||
@ -2,21 +2,55 @@ using ActiveProtect.Models;
|
|||||||
|
|
||||||
namespace ActiveProtect.SimulationEnvironment
|
namespace ActiveProtect.SimulationEnvironment
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 仿真元素的抽象基类,所有仿真中的实体都继承自此类
|
||||||
|
/// </summary>
|
||||||
public abstract class SimulationElement(string id, Vector3D position, Orientation orientation, ISimulationManager simulationManager)
|
public abstract class SimulationElement(string id, Vector3D position, Orientation orientation, ISimulationManager simulationManager)
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 仿真元素的唯一标识符
|
||||||
|
/// </summary>
|
||||||
public string Id { get; set; } = id;
|
public string Id { get; set; } = id;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 仿真元素的当前位置
|
||||||
|
/// </summary>
|
||||||
public Vector3D Position { get; set; } = position;
|
public Vector3D Position { get; set; } = position;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 仿真元素的当前朝向
|
||||||
|
/// </summary>
|
||||||
public Orientation Orientation { get; set; } = orientation;
|
public Orientation Orientation { get; set; } = orientation;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 仿真管理器的引用
|
||||||
|
/// </summary>
|
||||||
public ISimulationManager SimulationManager { get; set; } = simulationManager;
|
public ISimulationManager SimulationManager { get; set; } = simulationManager;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 仿真元素是否处于活动状态
|
||||||
|
/// </summary>
|
||||||
public bool IsActive { get; protected set; } = true;
|
public bool IsActive { get; protected set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新仿真元素的状态
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="deltaTime">时间步长</param>
|
||||||
public abstract void Update(double deltaTime);
|
public abstract void Update(double deltaTime);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取仿真元素的状态信息
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>状态信息字符串</returns>
|
||||||
public virtual string GetStatus()
|
public virtual string GetStatus()
|
||||||
{
|
{
|
||||||
return $"{GetType().Name} {Id} at {Position}, Orientation: {Orientation}, Active: {IsActive}";
|
return $"{GetType().Name} {Id} at {Position}, Orientation: {Orientation}, Active: {IsActive}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发布仿真事件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="evt">要发布的事件</param>
|
||||||
protected void PublishEvent(SimulationEvent evt)
|
protected void PublishEvent(SimulationEvent evt)
|
||||||
{
|
{
|
||||||
evt.SenderId = Id;
|
evt.SenderId = Id;
|
||||||
@ -24,12 +58,18 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
SimulationManager.PublishEvent(evt);
|
SimulationManager.PublishEvent(evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 激活仿真元素
|
||||||
|
/// </summary>
|
||||||
protected virtual void Activate()
|
protected virtual void Activate()
|
||||||
{
|
{
|
||||||
IsActive = true;
|
IsActive = true;
|
||||||
PublishEvent(new EntityActivatedEvent { ActivatedEntityId = Id });
|
PublishEvent(new EntityActivatedEvent { ActivatedEntityId = Id });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 停用仿真元素
|
||||||
|
/// </summary>
|
||||||
protected virtual void Deactivate()
|
protected virtual void Deactivate()
|
||||||
{
|
{
|
||||||
IsActive = false;
|
IsActive = false;
|
||||||
|
|||||||
@ -1,55 +1,122 @@
|
|||||||
namespace ActiveProtect.SimulationEnvironment
|
namespace ActiveProtect.SimulationEnvironment
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 仿真事件的基类
|
||||||
|
/// </summary>
|
||||||
public class SimulationEvent
|
public class SimulationEvent
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 事件发送者的ID
|
||||||
|
/// </summary>
|
||||||
public string? SenderId { get; set; }
|
public string? SenderId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 事件发生的时间戳
|
||||||
|
/// </summary>
|
||||||
public double Timestamp { get; set; }
|
public double Timestamp { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 导弹发射事件
|
||||||
|
/// </summary>
|
||||||
public class MissileFireEvent : SimulationEvent
|
public class MissileFireEvent : SimulationEvent
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 目标ID
|
||||||
|
/// </summary>
|
||||||
public string? TargetId { get; set; }
|
public string? TargetId { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 激光照射事件
|
||||||
|
/// </summary>
|
||||||
public class LaserIlluminationEvent : SimulationEvent
|
public class LaserIlluminationEvent : SimulationEvent
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 目标ID
|
||||||
|
/// </summary>
|
||||||
public string? TargetId { get; set; }
|
public string? TargetId { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 激光干扰事件
|
||||||
|
/// </summary>
|
||||||
public class LaserJammingEvent : SimulationEvent
|
public class LaserJammingEvent : SimulationEvent
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 目标ID
|
||||||
|
/// </summary>
|
||||||
public string? TargetId { get; set; }
|
public string? TargetId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 干扰功率
|
||||||
|
/// </summary>
|
||||||
public double JammingPower { get; set; }
|
public double JammingPower { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 实体销毁事件
|
||||||
|
/// </summary>
|
||||||
public class EntityDestroyedEvent : SimulationEvent
|
public class EntityDestroyedEvent : SimulationEvent
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 被销毁实体的ID
|
||||||
|
/// </summary>
|
||||||
public string? DestroyedEntityId { get; set; }
|
public string? DestroyedEntityId { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 激光照射停止事件
|
||||||
|
/// </summary>
|
||||||
public class LaserIlluminationStopEvent : SimulationEvent
|
public class LaserIlluminationStopEvent : SimulationEvent
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 目标ID
|
||||||
|
/// </summary>
|
||||||
public string? TargetId { get; set; }
|
public string? TargetId { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 激光告警器警报事件
|
||||||
|
/// </summary>
|
||||||
public class LaserWarnerAlarmEvent : SimulationEvent
|
public class LaserWarnerAlarmEvent : SimulationEvent
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 目标ID
|
||||||
|
/// </summary>
|
||||||
public string? TargetId { get; set; }
|
public string? TargetId { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 激光告警器警报停止事件
|
||||||
|
/// </summary>
|
||||||
public class LaserWarnerAlarmStopEvent : SimulationEvent
|
public class LaserWarnerAlarmStopEvent : SimulationEvent
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 目标ID
|
||||||
|
/// </summary>
|
||||||
public string? TargetId { get; set; }
|
public string? TargetId { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 实体激活事件
|
||||||
|
/// </summary>
|
||||||
public class EntityActivatedEvent : SimulationEvent
|
public class EntityActivatedEvent : SimulationEvent
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 被激活实体的ID
|
||||||
|
/// </summary>
|
||||||
public string? ActivatedEntityId { get; set; }
|
public string? ActivatedEntityId { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 实体停用事件
|
||||||
|
/// </summary>
|
||||||
public class EntityDeactivatedEvent : SimulationEvent
|
public class EntityDeactivatedEvent : SimulationEvent
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 被停用实体的ID
|
||||||
|
/// </summary>
|
||||||
public string? DeactivatedEntityId { get; set; }
|
public string? DeactivatedEntityId { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5,28 +5,79 @@ using ActiveProtect.Models;
|
|||||||
|
|
||||||
namespace ActiveProtect.SimulationEnvironment
|
namespace ActiveProtect.SimulationEnvironment
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 仿真管理器接口,定义了仿真管理器的基本功能
|
||||||
|
/// </summary>
|
||||||
public interface ISimulationManager
|
public interface ISimulationManager
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 当前仿真时间
|
||||||
|
/// </summary>
|
||||||
double CurrentTime { get; }
|
double CurrentTime { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加仿真元素
|
||||||
|
/// </summary>
|
||||||
void AddElement(SimulationElement element);
|
void AddElement(SimulationElement element);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据ID获取仿真实体
|
||||||
|
/// </summary>
|
||||||
SimulationElement GetEntityById(string id);
|
SimulationElement GetEntityById(string id);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 处理目标被击中事件
|
||||||
|
/// </summary>
|
||||||
void HandleTargetHit(string targetId, string missileId);
|
void HandleTargetHit(string targetId, string missileId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发布仿真事件
|
||||||
|
/// </summary>
|
||||||
void PublishEvent(SimulationEvent evt);
|
void PublishEvent(SimulationEvent evt);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 订阅仿真事件
|
||||||
|
/// </summary>
|
||||||
void SubscribeToEvent<T>(Action<T> handler) where T : SimulationEvent;
|
void SubscribeToEvent<T>(Action<T> handler) where T : SimulationEvent;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 取消订阅仿真事件
|
||||||
|
/// </summary>
|
||||||
void UnsubscribeFromEvent<T>(Action<T> handler) where T : SimulationEvent;
|
void UnsubscribeFromEvent<T>(Action<T> handler) where T : SimulationEvent;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 取消所有事件订阅
|
||||||
|
/// </summary>
|
||||||
void UnsubscribeAllEvents(SimulationElement element);
|
void UnsubscribeAllEvents(SimulationElement element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 仿真管理器类,负责管理整个仿真过程
|
||||||
|
/// </summary>
|
||||||
public class SimulationManager : ISimulationManager
|
public class SimulationManager : ISimulationManager
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 仿真元素列表
|
||||||
|
/// </summary>
|
||||||
public List<SimulationElement> Elements { get; private set; }
|
public List<SimulationElement> Elements { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前仿真时间
|
||||||
|
/// </summary>
|
||||||
public double CurrentTime { get; private set; }
|
public double CurrentTime { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 仿真是否结束
|
||||||
|
/// </summary>
|
||||||
public bool IsSimulationEnded { get; private set; }
|
public bool IsSimulationEnded { get; private set; }
|
||||||
|
|
||||||
private readonly SimulationConfig config;
|
private readonly SimulationConfig config;
|
||||||
private Dictionary<Type, List<Delegate>> eventHandlers = new Dictionary<Type, List<Delegate>>();
|
private Dictionary<Type, List<Delegate>> eventHandlers = new Dictionary<Type, List<Delegate>>();
|
||||||
private Dictionary<SimulationElement, List<(Type, Delegate)>> elementSubscriptions = new Dictionary<SimulationElement, List<(Type, Delegate)>>();
|
private Dictionary<SimulationElement, List<(Type, Delegate)>> elementSubscriptions = new Dictionary<SimulationElement, List<(Type, Delegate)>>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造函数
|
||||||
|
/// </summary>
|
||||||
public SimulationManager(SimulationConfig config)
|
public SimulationManager(SimulationConfig config)
|
||||||
{
|
{
|
||||||
this.config = config;
|
this.config = config;
|
||||||
@ -36,6 +87,9 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
InitializeSimulation();
|
InitializeSimulation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化仿真
|
||||||
|
/// </summary>
|
||||||
private void InitializeSimulation()
|
private void InitializeSimulation()
|
||||||
{
|
{
|
||||||
// 创建坦克
|
// 创建坦克
|
||||||
@ -74,7 +128,7 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建导弹(修改这部分)
|
// 创建导弹
|
||||||
for (int i = 0; i < config.MissileConfigs.Count; i++)
|
for (int i = 0; i < config.MissileConfigs.Count; i++)
|
||||||
{
|
{
|
||||||
var missileConfig = config.MissileConfigs[i];
|
var missileConfig = config.MissileConfigs[i];
|
||||||
@ -112,6 +166,9 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发布仿真事件
|
||||||
|
/// </summary>
|
||||||
public void PublishEvent(SimulationEvent evt)
|
public void PublishEvent(SimulationEvent evt)
|
||||||
{
|
{
|
||||||
var eventType = evt.GetType();
|
var eventType = evt.GetType();
|
||||||
@ -124,6 +181,9 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 订阅仿真事件
|
||||||
|
/// </summary>
|
||||||
public void SubscribeToEvent<T>(Action<T> handler) where T : SimulationEvent
|
public void SubscribeToEvent<T>(Action<T> handler) where T : SimulationEvent
|
||||||
{
|
{
|
||||||
var eventType = typeof(T);
|
var eventType = typeof(T);
|
||||||
@ -149,6 +209,9 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 取消订阅仿真事件
|
||||||
|
/// </summary>
|
||||||
public void UnsubscribeFromEvent<T>(Action<T> handler) where T : SimulationEvent
|
public void UnsubscribeFromEvent<T>(Action<T> handler) where T : SimulationEvent
|
||||||
{
|
{
|
||||||
var eventType = typeof(T);
|
var eventType = typeof(T);
|
||||||
@ -165,6 +228,9 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 取消所有事件订阅
|
||||||
|
/// </summary>
|
||||||
public void UnsubscribeAllEvents(SimulationElement element)
|
public void UnsubscribeAllEvents(SimulationElement element)
|
||||||
{
|
{
|
||||||
if (elementSubscriptions.ContainsKey(element))
|
if (elementSubscriptions.ContainsKey(element))
|
||||||
@ -180,6 +246,9 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新仿真状态
|
||||||
|
/// </summary>
|
||||||
public void Update()
|
public void Update()
|
||||||
{
|
{
|
||||||
if (IsSimulationEnded) return;
|
if (IsSimulationEnded) return;
|
||||||
@ -208,6 +277,9 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 打印仿真状态
|
||||||
|
/// </summary>
|
||||||
public void PrintStatus()
|
public void PrintStatus()
|
||||||
{
|
{
|
||||||
Console.WriteLine($"仿真时间: {CurrentTime:F2}");
|
Console.WriteLine($"仿真时间: {CurrentTime:F2}");
|
||||||
@ -218,6 +290,9 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 结束仿真
|
||||||
|
/// </summary>
|
||||||
private void EndSimulation()
|
private void EndSimulation()
|
||||||
{
|
{
|
||||||
IsSimulationEnded = true;
|
IsSimulationEnded = true;
|
||||||
@ -226,11 +301,17 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
Console.WriteLine($"剩余坦克数量: {Elements.Count(e => e is Tank)}");
|
Console.WriteLine($"剩余坦克数量: {Elements.Count(e => e is Tank)}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据ID获取仿真实体
|
||||||
|
/// </summary>
|
||||||
public SimulationElement GetEntityById(string id)
|
public SimulationElement GetEntityById(string id)
|
||||||
{
|
{
|
||||||
return Elements.FirstOrDefault(e => e.Id == id) ?? throw new InvalidOperationException($"Entity with id {id} not found");
|
return Elements.FirstOrDefault(e => e.Id == id) ?? throw new InvalidOperationException($"Entity with id {id} not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 处理目标被击中事件
|
||||||
|
/// </summary>
|
||||||
public void HandleTargetHit(string targetId, string missileId)
|
public void HandleTargetHit(string targetId, string missileId)
|
||||||
{
|
{
|
||||||
if (GetEntityById(targetId) is Tank tank && GetEntityById(missileId) is Missile missile)
|
if (GetEntityById(targetId) is Tank tank && GetEntityById(missileId) is Missile missile)
|
||||||
@ -246,6 +327,9 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算导弹造成的伤害
|
||||||
|
/// </summary>
|
||||||
private double CalculateMissileDamage(Missile missile)
|
private double CalculateMissileDamage(Missile missile)
|
||||||
{
|
{
|
||||||
// 这里可以根据导弹类型、速度等因素计算伤害
|
// 这里可以根据导弹类型、速度等因素计算伤害
|
||||||
@ -253,11 +337,17 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
return 50;
|
return 50;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 记录击中事件
|
||||||
|
/// </summary>
|
||||||
private static void LogHitEvent(string targetId, string missileId, double damage)
|
private static void LogHitEvent(string targetId, string missileId, double damage)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"目标 {targetId} 被导弹 {missileId} 击中,造成 {damage} 点伤害");
|
Console.WriteLine($"目标 {targetId} 被导弹 {missileId} 击中,造成 {damage} 点伤害");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加仿真元素
|
||||||
|
/// </summary>
|
||||||
public void AddElement(SimulationElement element)
|
public void AddElement(SimulationElement element)
|
||||||
{
|
{
|
||||||
Elements.Add(element);
|
Elements.Add(element);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user