对各模型进行了重构
This commit is contained in:
parent
d9975acd3c
commit
f36f00572c
52
.cursorrules
Normal file
52
.cursorrules
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
您是 C#、Unity 和可扩展游戏开发的专家。
|
||||||
|
|
||||||
|
关键原则
|
||||||
|
- 编写清晰、技术性的响应,提供精确的 C# 和 Unity 示例。
|
||||||
|
- 尽可能使用 Unity 的内置功能和工具,以充分利用其能力。
|
||||||
|
- 优先考虑可读性和可维护性;遵循 C# 编码规范和 Unity 最佳实践。
|
||||||
|
- 使用描述性的变量和函数名称;遵循命名约定(例如,公共成员使用 PascalCase,私有成员使用 camelCase)。
|
||||||
|
- 以模块化的方式构建项目,使用 Unity 的基于组件的架构,以促进可重用性和关注点分离。
|
||||||
|
|
||||||
|
C#/Unity
|
||||||
|
- 对于附加到 GameObject 的脚本组件,使用 MonoBehaviour;对于数据容器和共享资源,优先使用 ScriptableObjects。
|
||||||
|
- 利用 Unity 的物理引擎和碰撞检测系统来实现游戏机制和交互。
|
||||||
|
- 使用 Unity 的输入系统处理跨多个平台的玩家输入。
|
||||||
|
- 利用 Unity 的 UI 系统(Canvas、UI 元素)创建用户界面。
|
||||||
|
- 严格遵循组件模式,以实现关注点的清晰分离和模块化。
|
||||||
|
- 在 Unity 的单线程环境中,使用协程处理基于时间的操作和异步任务。
|
||||||
|
|
||||||
|
错误处理和调试
|
||||||
|
- 在适当的地方使用 try-catch 块实现错误处理,特别是对于文件 I/O 和网络操作。
|
||||||
|
- 使用 Unity 的 Debug 类进行日志记录和调试(例如,Debug.Log、Debug.LogWarning、Debug.LogError)。
|
||||||
|
- 利用 Unity 的分析器和帧调试器识别和解决性能问题。
|
||||||
|
- 实现自定义错误消息和调试可视化,以改善开发体验。
|
||||||
|
- 使用 Unity 的断言系统(Debug.Assert)在开发过程中捕获逻辑错误。
|
||||||
|
|
||||||
|
依赖项
|
||||||
|
- Unity 引擎
|
||||||
|
- .NET 框架(与您的 Unity 版本兼容的版本)
|
||||||
|
- Unity 资产商店包(根据特定功能需要)
|
||||||
|
- 第三方插件(经过仔细审查以确保兼容性和性能)
|
||||||
|
|
||||||
|
Unity 特定指南
|
||||||
|
- 使用预制件(Prefabs)创建可重用的游戏对象和 UI 元素。
|
||||||
|
- 将游戏逻辑保留在脚本中;使用 Unity 编辑器进行场景组合和初始设置。
|
||||||
|
- 利用 Unity 的动画系统(Animator、动画剪辑)进行角色和对象动画。
|
||||||
|
- 应用 Unity 的内置光照和后处理效果以增强视觉效果。
|
||||||
|
- 使用 Unity 的内置测试框架进行单元测试和集成测试。
|
||||||
|
- 利用 Unity 的资源包系统进行高效的资源管理和加载。
|
||||||
|
- 使用 Unity 的标签和层系统进行对象分类和碰撞过滤。
|
||||||
|
|
||||||
|
性能优化
|
||||||
|
- 对于频繁实例化和销毁的对象,使用对象池。
|
||||||
|
- 通过批处理材质和使用精灵和 UI 元素的图集来优化绘制调用。
|
||||||
|
- 实现细节层次(LOD)系统,以提高复杂 3D 模型的渲染性能。
|
||||||
|
- 使用 Unity 的作业系统和 Burst 编译器进行 CPU 密集型操作。
|
||||||
|
- 通过使用简化的碰撞网格和调整固定时间步长来优化物理性能。
|
||||||
|
|
||||||
|
关键约定
|
||||||
|
1. 遵循 Unity 的基于组件的架构,以实现模块化和可重用的游戏元素。
|
||||||
|
2. 在开发的每个阶段优先考虑性能优化和内存管理。
|
||||||
|
3. 维护清晰和逻辑的项目结构,以增强可读性和资产管理。
|
||||||
|
|
||||||
|
请参考 Unity 文档和 C# 编程指南,以获取脚本、游戏架构和性能优化的最佳实践。
|
||||||
@ -6,54 +6,70 @@ namespace ActiveProtect.Models
|
|||||||
public class LaserDesignator : SimulationElement
|
public class LaserDesignator : SimulationElement
|
||||||
{
|
{
|
||||||
public string TargetId { get; private set; }
|
public string TargetId { get; private set; }
|
||||||
public bool IsActive { get; private set; }
|
public double JammingThreshold { get; private set; } = 0.0; // 调整干扰阈值
|
||||||
public double JammingThreshold { get; private set; } = 0.0; // 将阈值调整为 0 dB
|
|
||||||
public bool IsJammed { get; private set; } = false;
|
public bool IsJammed { get; private set; } = false;
|
||||||
public double MaxIlluminationRange { get; private set; }
|
public double MaxIlluminationRange { get; private set; }
|
||||||
|
private bool IsIlluminating { get; set; } = false;
|
||||||
|
|
||||||
public LaserDesignator(string id, LaserDesignatorConfig config, ISimulationManager simulationManager)
|
public LaserDesignator(string id, string targetId, LaserDesignatorConfig config, ISimulationManager simulationManager)
|
||||||
: base(id, config.InitialPosition, new Orientation(), simulationManager)
|
: base(id, config.InitialPosition, new Orientation(), simulationManager)
|
||||||
{
|
{
|
||||||
TargetId = config.TargetId;
|
TargetId = targetId;
|
||||||
IsActive = true;
|
IsActive = true;
|
||||||
MaxIlluminationRange = config.MaxIlluminationRange;
|
MaxIlluminationRange = config.MaxIlluminationRange;
|
||||||
simulationManager.SubscribeToEvent<LaserJammingEvent>(OnLaserJamming);
|
SimulationManager.SubscribeToEvent<LaserJammingEvent>(OnLaserJamming);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update(double deltaTime)
|
public override void Update(double deltaTime)
|
||||||
{
|
{
|
||||||
if (IsActive && !IsJammed)
|
if (IsActive && !IsJammed)
|
||||||
{
|
{
|
||||||
IlluminateTarget();
|
UpdateIllumination();
|
||||||
}
|
}
|
||||||
else
|
else if (IsIlluminating)
|
||||||
{
|
{
|
||||||
StopIllumination();
|
StopIllumination();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void IlluminateTarget()
|
private void UpdateIllumination()
|
||||||
{
|
{
|
||||||
if (SimulationManager.GetEntityById(TargetId) is ILaserIlluminatable target)
|
if (SimulationManager.GetEntityById(TargetId) is ILaserIlluminatable target)
|
||||||
{
|
{
|
||||||
double distanceToTarget = Vector3D.Distance(Position, target.Position);
|
double distanceToTarget = Vector3D.Distance(Position, target.Position);
|
||||||
if (distanceToTarget <= MaxIlluminationRange)
|
bool shouldIlluminate = distanceToTarget <= MaxIlluminationRange;
|
||||||
{
|
|
||||||
target.Illuminate();
|
|
||||||
Console.WriteLine($"激光目标指示器 {Id} 正在照射目标 {TargetId}");
|
|
||||||
|
|
||||||
// 发布LaserIlluminationEvent
|
Console.WriteLine($"激光目标指示器 {Id} 状态更新:");
|
||||||
PublishEvent(new LaserIlluminationEvent
|
Console.WriteLine($" 目标: {TargetId}");
|
||||||
{
|
Console.WriteLine($" 距离目标: {distanceToTarget:F2} m (最大照射范围: {MaxIlluminationRange} m)");
|
||||||
TargetId = TargetId
|
Console.WriteLine($" 是否应该照射: {shouldIlluminate}");
|
||||||
});
|
Console.WriteLine($" 当前照射状态: {IsIlluminating}");
|
||||||
|
|
||||||
|
if (shouldIlluminate && !IsIlluminating)
|
||||||
|
{
|
||||||
|
StartIllumination(target);
|
||||||
}
|
}
|
||||||
else
|
else if (!shouldIlluminate && IsIlluminating)
|
||||||
{
|
{
|
||||||
StopIllumination();
|
StopIllumination();
|
||||||
Console.WriteLine($"激光目标指示器 {Id} 超出照射范围,停止照射目标 {TargetId}");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine($"激光目标指示器 {Id} 无法找到目标 {TargetId}");
|
||||||
|
if (IsIlluminating)
|
||||||
|
{
|
||||||
|
StopIllumination();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StartIllumination(ILaserIlluminatable target)
|
||||||
|
{
|
||||||
|
target.Illuminate();
|
||||||
|
IsIlluminating = true;
|
||||||
|
Console.WriteLine($"激光目标指示器 {Id} 开始照射目标 {TargetId}");
|
||||||
|
PublishIlluminationEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StopIllumination()
|
private void StopIllumination()
|
||||||
@ -61,22 +77,22 @@ namespace ActiveProtect.Models
|
|||||||
if (SimulationManager.GetEntityById(TargetId) is ILaserIlluminatable target)
|
if (SimulationManager.GetEntityById(TargetId) is ILaserIlluminatable target)
|
||||||
{
|
{
|
||||||
target.StopIllumination();
|
target.StopIllumination();
|
||||||
Console.WriteLine($"激光目标指示器 {Id} 停止照射目标 {TargetId}");
|
|
||||||
PublishIlluminationStopEvent();
|
|
||||||
}
|
}
|
||||||
|
IsIlluminating = false;
|
||||||
|
Console.WriteLine($"激光目标指示器 {Id} 停止照射目标 {TargetId}");
|
||||||
|
PublishIlluminationStopEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnLaserJamming(LaserJammingEvent evt)
|
private void OnLaserJamming(LaserJammingEvent evt)
|
||||||
{
|
{
|
||||||
if (evt.TargetId == TargetId)
|
if (evt.TargetId == TargetId)
|
||||||
{
|
{
|
||||||
if (SimulationManager.GetEntityById(TargetId) is Tank target)
|
var tank = SimulationManager.GetEntityById(TargetId) as Tank;
|
||||||
|
if (tank != null)
|
||||||
{
|
{
|
||||||
double distanceToTarget = Vector3D.Distance(Position, target.Position);
|
double distanceToTarget = Vector3D.Distance(Position, tank.Position);
|
||||||
|
|
||||||
// 调整干扰效果计算方法
|
|
||||||
double jammingEffectiveness = 20 * Math.Log10(evt.JammingPower) - 20 * Math.Log10(distanceToTarget) - 20 * Math.Log10(4 * Math.PI);
|
double jammingEffectiveness = 20 * Math.Log10(evt.JammingPower) - 20 * Math.Log10(distanceToTarget) - 20 * Math.Log10(4 * Math.PI);
|
||||||
|
|
||||||
Console.WriteLine($"激光目标指示器 {Id} 收到干扰事件,干扰功率: {evt.JammingPower:F2}, 距离: {distanceToTarget:F2}, 干扰效果: {jammingEffectiveness:F2} dB, 阈值: {JammingThreshold:F2} dB");
|
Console.WriteLine($"激光目标指示器 {Id} 收到干扰事件,干扰功率: {evt.JammingPower:F2}, 距离: {distanceToTarget:F2}, 干扰效果: {jammingEffectiveness:F2} dB, 阈值: {JammingThreshold:F2} dB");
|
||||||
|
|
||||||
if (jammingEffectiveness > JammingThreshold)
|
if (jammingEffectiveness > JammingThreshold)
|
||||||
@ -85,7 +101,7 @@ namespace ActiveProtect.Models
|
|||||||
{
|
{
|
||||||
Console.WriteLine($"激光目标指示器 {Id} 被干扰,停止工作");
|
Console.WriteLine($"激光目标指示器 {Id} 被干扰,停止工作");
|
||||||
IsJammed = true;
|
IsJammed = true;
|
||||||
DeactivateLaser();
|
StopIllumination();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -94,7 +110,6 @@ namespace ActiveProtect.Models
|
|||||||
{
|
{
|
||||||
Console.WriteLine($"激光目标指示器 {Id} 干扰解除,恢复工作");
|
Console.WriteLine($"激光目标指示器 {Id} 干扰解除,恢复工作");
|
||||||
IsJammed = false;
|
IsJammed = false;
|
||||||
ActivateLaser();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -106,7 +121,7 @@ namespace ActiveProtect.Models
|
|||||||
IsActive = true;
|
IsActive = true;
|
||||||
IsJammed = false;
|
IsJammed = false;
|
||||||
Console.WriteLine($"激光目标指示器 {Id} 已激活");
|
Console.WriteLine($"激光目标指示器 {Id} 已激活");
|
||||||
IlluminateTarget(); // 立即开始照射目标
|
UpdateIllumination();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeactivateLaser()
|
public void DeactivateLaser()
|
||||||
@ -119,6 +134,14 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void PublishIlluminationEvent()
|
||||||
|
{
|
||||||
|
PublishEvent(new LaserIlluminationEvent
|
||||||
|
{
|
||||||
|
TargetId = TargetId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void PublishIlluminationStopEvent()
|
private void PublishIlluminationStopEvent()
|
||||||
{
|
{
|
||||||
PublishEvent(new LaserIlluminationStopEvent
|
PublishEvent(new LaserIlluminationStopEvent
|
||||||
@ -133,6 +156,7 @@ namespace ActiveProtect.Models
|
|||||||
$" 位置: {Position}\n" +
|
$" 位置: {Position}\n" +
|
||||||
$" 目标: {TargetId}\n" +
|
$" 目标: {TargetId}\n" +
|
||||||
$" 激活状态: {(IsActive ? "激活" : "未激活")}\n" +
|
$" 激活状态: {(IsActive ? "激活" : "未激活")}\n" +
|
||||||
|
$" 照射状态: {(IsIlluminating ? "正在照射" : "未照射")}\n" +
|
||||||
$" 干扰状态: {(IsJammed ? "被干扰" : "正常")}\n" +
|
$" 干扰状态: {(IsJammed ? "被干扰" : "正常")}\n" +
|
||||||
$" 最大照射范围: {MaxIlluminationRange}";
|
$" 最大照射范围: {MaxIlluminationRange}";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,52 +3,90 @@ using ActiveProtect.SimulationEnvironment;
|
|||||||
|
|
||||||
namespace ActiveProtect.Models
|
namespace ActiveProtect.Models
|
||||||
{
|
{
|
||||||
public class LaserJammer
|
public class LaserJammer : SimulationElement
|
||||||
{
|
{
|
||||||
private readonly Tank tank;
|
|
||||||
public bool IsJamming { get; private set; }
|
public bool IsJamming { get; private set; }
|
||||||
public double JammingPower { get; private set; }
|
public double JammingPower { get; private set; }
|
||||||
private double jammingCooldown = 0;
|
private double jammingCooldown = 0;
|
||||||
private const double MaxJammingCooldown = 5.0;
|
private readonly double maxJammingCooldown;
|
||||||
private const double MaxJammingPower = 10000.0; // 降低最大干扰功率
|
private readonly double maxJammingPower;
|
||||||
private const double InitialJammingPower = 4000.0; // 设置初始干扰功率
|
private readonly double initialJammingPower;
|
||||||
private const double PowerIncreaseRate = 2000.0; // 每秒增加的功率
|
private readonly double powerIncreaseRate;
|
||||||
|
public string MonitoredEntityId { get; private set; }
|
||||||
|
|
||||||
public LaserJammer(Tank tank)
|
public LaserJammer(string id, Vector3D position, Orientation orientation, ISimulationManager simulationManager, string monitoredEntityId, LaserJammerConfig config)
|
||||||
|
: base(id, position, orientation, simulationManager)
|
||||||
{
|
{
|
||||||
this.tank = tank;
|
MonitoredEntityId = monitoredEntityId;
|
||||||
IsJamming = false;
|
IsJamming = false;
|
||||||
JammingPower = 0;
|
JammingPower = 0;
|
||||||
tank.SimulationManager.SubscribeToEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
|
maxJammingCooldown = config.MaxJammingCooldown;
|
||||||
|
maxJammingPower = config.MaxJammingPower;
|
||||||
|
initialJammingPower = config.InitialJammingPower;
|
||||||
|
powerIncreaseRate = config.PowerIncreaseRate;
|
||||||
|
SimulationManager.SubscribeToEvent<LaserIlluminationEvent>(OnLaserIllumination);
|
||||||
|
SimulationManager.SubscribeToEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update(double deltaTime)
|
public override void Update(double deltaTime)
|
||||||
{
|
{
|
||||||
|
if (!IsActive) return;
|
||||||
|
|
||||||
|
var tank = SimulationManager.GetEntityById(MonitoredEntityId) as Tank;
|
||||||
|
if (tank != null)
|
||||||
|
{
|
||||||
|
Position = tank.Position;
|
||||||
|
Orientation = tank.Orientation;
|
||||||
|
}
|
||||||
|
|
||||||
if (IsJamming)
|
if (IsJamming)
|
||||||
{
|
{
|
||||||
// 逐渐增加干扰功率
|
JammingPower = Math.Min(JammingPower + powerIncreaseRate * deltaTime, maxJammingPower);
|
||||||
JammingPower = Math.Min(JammingPower + PowerIncreaseRate * deltaTime, MaxJammingPower);
|
|
||||||
|
|
||||||
jammingCooldown += deltaTime;
|
jammingCooldown += deltaTime;
|
||||||
if (jammingCooldown >= MaxJammingCooldown)
|
if (jammingCooldown >= maxJammingCooldown)
|
||||||
{
|
{
|
||||||
StopJamming();
|
StopJamming();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 发布干扰事件
|
||||||
|
PublishEvent(new LaserJammingEvent
|
||||||
|
{
|
||||||
|
TargetId = MonitoredEntityId,
|
||||||
|
JammingPower = JammingPower
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Console.WriteLine($"坦克 {tank.Id} 的激光干扰器正在工作,当前功率: {JammingPower:F2}");
|
Console.WriteLine($"激光干扰器 {Id} 正在工作,当前功率: {JammingPower:F2}");
|
||||||
}
|
}
|
||||||
else if (tank.LaserWarner.IsAlarming)
|
}
|
||||||
|
|
||||||
|
private void OnLaserIllumination(LaserIlluminationEvent evt)
|
||||||
|
{
|
||||||
|
if (evt.TargetId == MonitoredEntityId)
|
||||||
{
|
{
|
||||||
StartJamming();
|
StartJamming();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnLaserIlluminationStop(LaserIlluminationStopEvent evt)
|
||||||
|
{
|
||||||
|
if (evt.TargetId == MonitoredEntityId)
|
||||||
|
{
|
||||||
|
StopJamming();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void StartJamming()
|
private void StartJamming()
|
||||||
{
|
{
|
||||||
IsJamming = true;
|
if (!IsJamming)
|
||||||
JammingPower = InitialJammingPower; // 从初始功率开始
|
{
|
||||||
jammingCooldown = 0;
|
IsJamming = true;
|
||||||
Console.WriteLine($"坦克 {tank.Id} 的激光干扰器开始工作,初始功率: {JammingPower:F2}");
|
JammingPower = initialJammingPower;
|
||||||
|
jammingCooldown = 0;
|
||||||
|
Console.WriteLine($"激光干扰器 {Id} 开始工作,初始功率: {JammingPower:F2}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StopJamming()
|
private void StopJamming()
|
||||||
@ -58,17 +96,24 @@ namespace ActiveProtect.Models
|
|||||||
IsJamming = false;
|
IsJamming = false;
|
||||||
JammingPower = 0;
|
JammingPower = 0;
|
||||||
jammingCooldown = 0;
|
jammingCooldown = 0;
|
||||||
Console.WriteLine($"坦克 {tank.Id} 的激光干扰器停止工作");
|
Console.WriteLine($"激光干扰器 {Id} 停止工作");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnLaserIlluminationStop(LaserIlluminationStopEvent evt)
|
public override string GetStatus()
|
||||||
{
|
{
|
||||||
if (evt.TargetId == tank.Id)
|
return $"激光干扰器 {Id}:\n" +
|
||||||
{
|
$" 监视实体: {MonitoredEntityId}\n" +
|
||||||
Console.WriteLine($"坦克 {tank.Id} 接收到激光照射停止事件,停止干扰");
|
$" 干扰状态: {(IsJamming ? "干扰中" : "未干扰")}\n" +
|
||||||
StopJamming();
|
$" 当前功率: {JammingPower:F2}/{maxJammingPower:F2}\n" +
|
||||||
}
|
$" 冷却时间: {jammingCooldown:F2}/{maxJammingCooldown:F2}";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Deactivate()
|
||||||
|
{
|
||||||
|
base.Deactivate();
|
||||||
|
SimulationManager.UnsubscribeFromEvent<LaserIlluminationEvent>(OnLaserIllumination);
|
||||||
|
SimulationManager.UnsubscribeFromEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5,9 +5,7 @@ namespace ActiveProtect.Models
|
|||||||
{
|
{
|
||||||
public class LaserSemiActiveGuidedMissile : Missile
|
public class LaserSemiActiveGuidedMissile : Missile
|
||||||
{
|
{
|
||||||
public bool IsLaserDetected { get; private set; } = false;
|
private const double LaserLockDistance = 2000; // 1公里,单位:米
|
||||||
public bool IsLaserLocked { get; private set; } = false;
|
|
||||||
private const double LaserLockDistance = 1000; // 1公里,单位:米
|
|
||||||
|
|
||||||
public LaserSemiActiveGuidedMissile(
|
public LaserSemiActiveGuidedMissile(
|
||||||
string id,
|
string id,
|
||||||
@ -16,68 +14,67 @@ namespace ActiveProtect.Models
|
|||||||
: base(id, missileConfig, simulationManager)
|
: base(id, missileConfig, simulationManager)
|
||||||
{
|
{
|
||||||
Type = MissileType.SemiActiveLaserGuidance;
|
Type = MissileType.SemiActiveLaserGuidance;
|
||||||
|
simulationManager.SubscribeToEvent<LaserIlluminationEvent>(OnLaserIllumination);
|
||||||
|
simulationManager.SubscribeToEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update(double deltaTime)
|
public override void Update(double deltaTime)
|
||||||
{
|
{
|
||||||
base.Update(deltaTime);
|
base.Update(deltaTime);
|
||||||
UpdateLaserDetection();
|
UpdateGuidanceStatus();
|
||||||
if (IsLaserDetected)
|
}
|
||||||
|
|
||||||
|
private void UpdateGuidanceStatus()
|
||||||
|
{
|
||||||
|
if (SimulationManager.GetEntityById(TargetId) is ILaserIlluminatable target)
|
||||||
{
|
{
|
||||||
UpdateLaserLock();
|
bool isIlluminated = target.IsIlluminated;
|
||||||
IsGuidanceLost = false;
|
bool isWithinRange = DistanceToTarget <= LaserLockDistance;
|
||||||
|
HasGuidance = isIlluminated && isWithinRange;
|
||||||
|
|
||||||
|
Console.WriteLine($"激光半主动制导导弹 {Id} 状态更新:");
|
||||||
|
Console.WriteLine($" 目标 {TargetId} 是否被照射: {isIlluminated}");
|
||||||
|
Console.WriteLine($" 距离目标: {DistanceToTarget:F2} m (最大锁定距离: {LaserLockDistance} m)");
|
||||||
|
Console.WriteLine($" 是否在锁定范围内: {isWithinRange}");
|
||||||
|
Console.WriteLine($" 引导状态: {(HasGuidance ? "有效" : "无效")}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LoseGuidance();
|
HasGuidance = false;
|
||||||
|
Console.WriteLine($"激光半主动制导导弹 {Id} 无法找到目标 {TargetId}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateLaserDetection()
|
private void OnLaserIllumination(LaserIlluminationEvent evt)
|
||||||
{
|
{
|
||||||
var target = SimulationManager.GetEntityById(TargetId) as ILaserIlluminatable;
|
if (evt.TargetId == TargetId)
|
||||||
if (target != null)
|
|
||||||
{
|
{
|
||||||
IsLaserDetected = target.IsIlluminated && DistanceToTarget <= LaserLockDistance;
|
Console.WriteLine($"激光半主动制导导弹 {Id} 检测到目标 {TargetId} 被激光照射");
|
||||||
}
|
UpdateGuidanceStatus();
|
||||||
else
|
|
||||||
{
|
|
||||||
IsLaserDetected = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateLaserLock()
|
private void OnLaserIlluminationStop(LaserIlluminationStopEvent evt)
|
||||||
{
|
{
|
||||||
IsLaserLocked = IsLaserDetected;
|
if (evt.TargetId == TargetId)
|
||||||
|
|
||||||
if (IsLaserLocked)
|
|
||||||
{
|
{
|
||||||
AdjustTrajectoryBasedOnLaserGuidance();
|
Console.WriteLine($"激光半主动制导导弹 {Id} 检测到目标 {TargetId} 激光照射停止");
|
||||||
}
|
UpdateGuidanceStatus();
|
||||||
}
|
|
||||||
|
|
||||||
private void AdjustTrajectoryBasedOnLaserGuidance()
|
|
||||||
{
|
|
||||||
// 实现基于激光导引的轨迹调整
|
|
||||||
// 这里可以添加更精确的导引逻辑
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void LoseGuidance()
|
|
||||||
{
|
|
||||||
if (!IsLaserDetected)
|
|
||||||
{
|
|
||||||
base.LoseGuidance();
|
|
||||||
IsLaserLocked = false;
|
|
||||||
Console.WriteLine($"激光半主动制导导弹 {Id} 失去激光引导");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string GetStatus()
|
public override string GetStatus()
|
||||||
{
|
{
|
||||||
string baseStatus = base.GetStatus().Replace("导弹", "激光半主动制导导弹");
|
string baseStatus = base.GetStatus().Replace("导弹", "激光半主动制导导弹");
|
||||||
string additionalStatus = $"\n 激光检测: {(IsLaserDetected ? "是" : "否")}" +
|
string additionalStatus = $"\n 激光引导: {(HasGuidance ? "有效" : "无效")}";
|
||||||
$"\n 激光锁定: {(IsLaserLocked ? "是" : "否")}";
|
|
||||||
return baseStatus + additionalStatus;
|
return baseStatus + additionalStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void Deactivate()
|
||||||
|
{
|
||||||
|
base.Deactivate();
|
||||||
|
SimulationManager.UnsubscribeFromEvent<LaserIlluminationEvent>(OnLaserIllumination);
|
||||||
|
SimulationManager.UnsubscribeFromEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3,23 +3,34 @@ using System;
|
|||||||
|
|
||||||
namespace ActiveProtect.Models
|
namespace ActiveProtect.Models
|
||||||
{
|
{
|
||||||
public class LaserWarner
|
public class LaserWarner : SimulationElement
|
||||||
{
|
{
|
||||||
private readonly Tank tank;
|
|
||||||
public bool IsAlarming { get; private set; }
|
public bool IsAlarming { get; private set; }
|
||||||
private double alarmDuration = 5.0; // 警报持续5秒
|
private readonly double alarmDuration;
|
||||||
private double alarmTimer = 0;
|
private double alarmTimer = 0;
|
||||||
|
public string MonitoredEntityId { get; private set; }
|
||||||
|
|
||||||
public LaserWarner(Tank tank)
|
public LaserWarner(string id, Vector3D position, Orientation orientation, ISimulationManager simulationManager, string monitoredEntityId, LaserWarnerConfig config)
|
||||||
|
: base(id, position, orientation, simulationManager)
|
||||||
{
|
{
|
||||||
this.tank = tank;
|
MonitoredEntityId = monitoredEntityId;
|
||||||
IsAlarming = false;
|
IsAlarming = false;
|
||||||
tank.SimulationManager.SubscribeToEvent<LaserIlluminationEvent>(OnLaserIllumination);
|
alarmDuration = config.AlarmDuration;
|
||||||
tank.SimulationManager.SubscribeToEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
|
SimulationManager.SubscribeToEvent<LaserIlluminationEvent>(OnLaserIllumination);
|
||||||
|
SimulationManager.SubscribeToEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update(double deltaTime)
|
public override void Update(double deltaTime)
|
||||||
{
|
{
|
||||||
|
if (!IsActive) return;
|
||||||
|
|
||||||
|
var tank = SimulationManager.GetEntityById(MonitoredEntityId) as Tank;
|
||||||
|
if (tank != null)
|
||||||
|
{
|
||||||
|
Position = tank.Position;
|
||||||
|
Orientation = tank.Orientation;
|
||||||
|
}
|
||||||
|
|
||||||
if (IsAlarming)
|
if (IsAlarming)
|
||||||
{
|
{
|
||||||
alarmTimer += deltaTime;
|
alarmTimer += deltaTime;
|
||||||
@ -32,7 +43,7 @@ namespace ActiveProtect.Models
|
|||||||
|
|
||||||
private void OnLaserIllumination(LaserIlluminationEvent evt)
|
private void OnLaserIllumination(LaserIlluminationEvent evt)
|
||||||
{
|
{
|
||||||
if (evt.TargetId == tank.Id)
|
if (evt.TargetId == MonitoredEntityId)
|
||||||
{
|
{
|
||||||
TriggerAlarm();
|
TriggerAlarm();
|
||||||
}
|
}
|
||||||
@ -40,7 +51,7 @@ namespace ActiveProtect.Models
|
|||||||
|
|
||||||
private void OnLaserIlluminationStop(LaserIlluminationStopEvent evt)
|
private void OnLaserIlluminationStop(LaserIlluminationStopEvent evt)
|
||||||
{
|
{
|
||||||
if (evt.TargetId == tank.Id)
|
if (evt.TargetId == MonitoredEntityId)
|
||||||
{
|
{
|
||||||
StopAlarm();
|
StopAlarm();
|
||||||
}
|
}
|
||||||
@ -52,7 +63,7 @@ namespace ActiveProtect.Models
|
|||||||
{
|
{
|
||||||
IsAlarming = true;
|
IsAlarming = true;
|
||||||
alarmTimer = 0;
|
alarmTimer = 0;
|
||||||
Console.WriteLine($"坦克 {tank.Id} 的激光告警器发出警报!");
|
Console.WriteLine($"激光告警器 {Id} 发出警报!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,8 +73,23 @@ namespace ActiveProtect.Models
|
|||||||
{
|
{
|
||||||
IsAlarming = false;
|
IsAlarming = false;
|
||||||
alarmTimer = 0;
|
alarmTimer = 0;
|
||||||
Console.WriteLine($"坦克 {tank.Id} 的激光告警器停止警报");
|
Console.WriteLine($"激光告警器 {Id} 停止警报");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override string GetStatus()
|
||||||
|
{
|
||||||
|
return $"激光告警器 {Id}:\n" +
|
||||||
|
$" 监视实体: {MonitoredEntityId}\n" +
|
||||||
|
$" 警报状态: {(IsAlarming ? "警报中" : "正常")}\n" +
|
||||||
|
$" 警报持续时间: {(IsAlarming ? alarmTimer : 0):F2}/{alarmDuration:F2}";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Deactivate()
|
||||||
|
{
|
||||||
|
base.Deactivate();
|
||||||
|
SimulationManager.UnsubscribeFromEvent<LaserIlluminationEvent>(OnLaserIllumination);
|
||||||
|
SimulationManager.UnsubscribeFromEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -39,7 +39,6 @@ namespace ActiveProtect.Models
|
|||||||
public MissileDistanceParams DistanceParams { get; protected set; }
|
public MissileDistanceParams DistanceParams { get; protected set; }
|
||||||
public FlightStageConfig StageConfig { get; protected set; }
|
public FlightStageConfig StageConfig { get; protected set; }
|
||||||
public FlightStage CurrentStage { get; protected set; }
|
public FlightStage CurrentStage { get; protected set; }
|
||||||
public bool IsActive { get; protected set; }
|
|
||||||
|
|
||||||
protected Vector3D Velocity;
|
protected Vector3D Velocity;
|
||||||
private Vector3D LastTargetPosition;
|
private Vector3D LastTargetPosition;
|
||||||
@ -53,7 +52,7 @@ namespace ActiveProtect.Models
|
|||||||
|
|
||||||
public double ProportionalNavigationCoefficient { get; set; }
|
public double ProportionalNavigationCoefficient { get; set; }
|
||||||
|
|
||||||
public bool IsGuidanceLost { get; protected set; } = false;
|
public bool HasGuidance { get; protected set; } = true;
|
||||||
protected double LostGuidanceTime { get; set; } = 0;
|
protected double LostGuidanceTime { get; set; } = 0;
|
||||||
protected const double MaxLostGuidanceTime = 1.0; // 1秒后自毁
|
protected const double MaxLostGuidanceTime = 1.0; // 1秒后自毁
|
||||||
|
|
||||||
@ -90,15 +89,19 @@ namespace ActiveProtect.Models
|
|||||||
|
|
||||||
LastTargetPosition = Position; // 初始化 LastTargetPosition
|
LastTargetPosition = Position; // 初始化 LastTargetPosition
|
||||||
|
|
||||||
// 订阅相关事件
|
|
||||||
simulationManager.SubscribeToEvent<LaserIlluminationEvent>(OnLaserIllumination);
|
|
||||||
simulationManager.SubscribeToEvent<LaserIlluminationStopEvent>(OnLaserIlluminationStop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update(double deltaTime)
|
public override void Update(double deltaTime)
|
||||||
{
|
{
|
||||||
if (!IsActive) return;
|
if (!IsActive) return;
|
||||||
|
|
||||||
|
// 首先检查是否应该自毁
|
||||||
|
if (ShouldSelfDestruct())
|
||||||
|
{
|
||||||
|
SelfDestruct();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 更新发动机燃烧时间
|
// 更新发动机燃烧时间
|
||||||
UpdateEngineBurnTime(deltaTime);
|
UpdateEngineBurnTime(deltaTime);
|
||||||
|
|
||||||
@ -125,33 +128,24 @@ namespace ActiveProtect.Models
|
|||||||
Orientation = Orientation.FromVector(Velocity);
|
Orientation = Orientation.FromVector(Velocity);
|
||||||
FlightTime += deltaTime;
|
FlightTime += deltaTime;
|
||||||
FlightDistance += Speed * deltaTime;
|
FlightDistance += Speed * deltaTime;
|
||||||
|
DistanceToTarget = Vector3D.Distance(Position, SimulationManager.GetEntityById(TargetId).Position);
|
||||||
|
|
||||||
UpdateDistanceToTarget(Vector3D.Distance(Position, SimulationManager.GetEntityById(TargetId).Position));
|
// 检查是否命中目标
|
||||||
|
|
||||||
// 首先检查是否命中目标
|
|
||||||
if (CheckHit())
|
if (CheckHit())
|
||||||
{
|
{
|
||||||
Explode();
|
Explode();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 然后检查是否应该自毁
|
|
||||||
if (ShouldSelfDestruct())
|
|
||||||
{
|
|
||||||
SelfDestruct();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新飞行阶段
|
// 更新飞行阶段
|
||||||
UpdateFlightStage();
|
UpdateFlightStage();
|
||||||
|
|
||||||
if (IsGuidanceLost)
|
if (!HasGuidance)
|
||||||
{
|
{
|
||||||
HandleLostGuidance(deltaTime);
|
HandleLostGuidance(deltaTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 重置失去引导的时间
|
|
||||||
LostGuidanceTime = 0;
|
LostGuidanceTime = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,7 +163,22 @@ namespace ActiveProtect.Models
|
|||||||
|
|
||||||
private bool ShouldSelfDestruct()
|
private bool ShouldSelfDestruct()
|
||||||
{
|
{
|
||||||
return FlightTime >= MaxFlightTime || FlightDistance >= MaxFlightDistance || Position.Y <= 0;
|
if (FlightTime >= MaxFlightTime)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"导弹 {Id} 超出最大飞行时间 ({FlightTime:F2}/{MaxFlightTime:F2}),准备自毁");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (FlightDistance >= MaxFlightDistance)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"导弹 {Id} 超出最大飞行距离 ({FlightDistance:F2}/{MaxFlightDistance:F2}),准备自毁");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (Position.Y <= 0)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"导弹 {Id} 高度小于等于0 ({Position.Y:F2}),准备自毁");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateEngineBurnTime(double deltaTime)
|
private void UpdateEngineBurnTime(double deltaTime)
|
||||||
@ -248,27 +257,25 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateDistanceToTarget(double distance)
|
|
||||||
{
|
|
||||||
DistanceToTarget = distance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Explode()
|
public void Explode()
|
||||||
{
|
{
|
||||||
IsActive = false;
|
Deactivate();
|
||||||
SimulationManager.HandleTargetHit(TargetId, Id);
|
SimulationManager.HandleTargetHit(TargetId, Id);
|
||||||
Console.WriteLine($"导弹 {Id} 在 {Position} 爆炸,命中目标!");
|
Console.WriteLine($"导弹 {Id} 在 {Position} 爆炸,命中目标!");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SelfDestruct()
|
public void SelfDestruct()
|
||||||
{
|
{
|
||||||
IsActive = false;
|
if (IsActive)
|
||||||
string reason = FlightTime >= MaxFlightTime ? "超出最大飞行时间" :
|
{
|
||||||
FlightDistance >= MaxFlightDistance ? "超出最大飞行距" :
|
string reason = FlightTime >= MaxFlightTime ? "超出最大飞行时间" :
|
||||||
Position.Y <= 0 ? "高度小于等于0" :
|
FlightDistance >= MaxFlightDistance ? "超出最大飞行距离" :
|
||||||
IsGuidanceLost ? "失去引导" : "未知原因";
|
Position.Y <= 0 ? "高度小于等于0" :
|
||||||
|
!HasGuidance ? "失去引导" : "未知原因";
|
||||||
Console.WriteLine($"导弹 {Id} 自毁。原因: {reason}");
|
|
||||||
|
Console.WriteLine($"导弹 {Id} 自毁。原因: {reason}");
|
||||||
|
Deactivate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string GetStatus()
|
public override string GetStatus()
|
||||||
@ -281,7 +288,7 @@ namespace ActiveProtect.Models
|
|||||||
$" 飞行距离: {FlightDistance:F2}/{MaxFlightDistance:F2}\n" +
|
$" 飞行距离: {FlightDistance:F2}/{MaxFlightDistance:F2}\n" +
|
||||||
$" 距离目标: {DistanceToTarget:F2}\n" +
|
$" 距离目标: {DistanceToTarget:F2}\n" +
|
||||||
$" 发动机工作时间: {EngineBurnTime:F2}/{MaxEngineBurnTime:F2}\n" +
|
$" 发动机工作时间: {EngineBurnTime:F2}/{MaxEngineBurnTime:F2}\n" +
|
||||||
$" 失去引导: {(IsGuidanceLost ? "是" : "否")}\n" +
|
$" 有引导: {(HasGuidance ? "是" : "否")}\n" +
|
||||||
$" 失去引导时间: {LostGuidanceTime:F2}/{MaxLostGuidanceTime:F2}";
|
$" 失去引导时间: {LostGuidanceTime:F2}/{MaxLostGuidanceTime:F2}";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,15 +298,6 @@ namespace ActiveProtect.Models
|
|||||||
Console.WriteLine($"导弹 {Id} 的比例导引系数已更新为 {newCoefficient}");
|
Console.WriteLine($"导弹 {Id} 的比例导引系数已更新为 {newCoefficient}");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void LoseGuidance()
|
|
||||||
{
|
|
||||||
if (!IsGuidanceLost)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"导弹 {Id} 失去引导");
|
|
||||||
IsGuidanceLost = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void HandleLostGuidance(double deltaTime)
|
protected virtual void HandleLostGuidance(double deltaTime)
|
||||||
{
|
{
|
||||||
LostGuidanceTime += deltaTime;
|
LostGuidanceTime += deltaTime;
|
||||||
@ -310,33 +308,6 @@ namespace ActiveProtect.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnLaserIllumination(LaserIlluminationEvent evt)
|
|
||||||
{
|
|
||||||
if (evt.TargetId == TargetId)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"导弹 {Id} 检测到目标 {TargetId} 被激光照射");
|
|
||||||
RegainGuidance();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnLaserIlluminationStop(LaserIlluminationStopEvent evt)
|
|
||||||
{
|
|
||||||
if (evt.TargetId == TargetId)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"导弹 {Id} 检测到目标 {TargetId} 激光照射停止");
|
|
||||||
LoseGuidance();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void RegainGuidance()
|
|
||||||
{
|
|
||||||
if (IsGuidanceLost)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"导弹 {Id} 重新获得引导");
|
|
||||||
IsGuidanceLost = false;
|
|
||||||
LostGuidanceTime = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -6,13 +6,10 @@ namespace ActiveProtect.Models
|
|||||||
public class Tank : SimulationElement, ILaserIlluminatable
|
public class Tank : SimulationElement, ILaserIlluminatable
|
||||||
{
|
{
|
||||||
public double Speed { get; set; } = 0;
|
public double Speed { get; set; } = 0;
|
||||||
public bool IsActive { get; private set; } = true;
|
|
||||||
public double MaxSpeed { get; private set; }
|
public double MaxSpeed { get; private set; }
|
||||||
public double MaxArmor { get; private set; }
|
public double MaxArmor { get; private set; }
|
||||||
public double CurrentArmor { get; private set; }
|
public double CurrentArmor { get; private set; }
|
||||||
public bool IsIlluminated { get; private set; } = false;
|
public bool IsIlluminated { get; private set; } = false;
|
||||||
public LaserWarner LaserWarner { get; private set; }
|
|
||||||
public LaserJammer LaserJammer { get; private set; }
|
|
||||||
|
|
||||||
public Tank(string id, TankConfig tankConfig, ISimulationManager simulationManager)
|
public Tank(string id, TankConfig tankConfig, ISimulationManager simulationManager)
|
||||||
: base(id, tankConfig.InitialPosition, tankConfig.InitialOrientation, simulationManager)
|
: base(id, tankConfig.InitialPosition, tankConfig.InitialOrientation, simulationManager)
|
||||||
@ -21,10 +18,6 @@ namespace ActiveProtect.Models
|
|||||||
MaxSpeed = tankConfig.MaxSpeed;
|
MaxSpeed = tankConfig.MaxSpeed;
|
||||||
MaxArmor = tankConfig.MaxArmor;
|
MaxArmor = tankConfig.MaxArmor;
|
||||||
CurrentArmor = tankConfig.MaxArmor;
|
CurrentArmor = tankConfig.MaxArmor;
|
||||||
LaserWarner = new LaserWarner(this);
|
|
||||||
LaserJammer = new LaserJammer(this);
|
|
||||||
|
|
||||||
// 移除事件订阅,因为现在由LaserWarner直接处理
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update(double deltaTime)
|
public override void Update(double deltaTime)
|
||||||
@ -32,18 +25,7 @@ namespace ActiveProtect.Models
|
|||||||
if (!IsActive) return;
|
if (!IsActive) return;
|
||||||
|
|
||||||
UpdatePosition(deltaTime);
|
UpdatePosition(deltaTime);
|
||||||
LaserWarner.Update(deltaTime);
|
// 移除发布坦克位置更新事件的代码
|
||||||
LaserJammer.Update(deltaTime);
|
|
||||||
|
|
||||||
// 如果激光干扰器正在工作,发布LaserJammingEvent
|
|
||||||
if (LaserJammer.IsJamming)
|
|
||||||
{
|
|
||||||
PublishEvent(new LaserJammingEvent
|
|
||||||
{
|
|
||||||
TargetId = Id,
|
|
||||||
JammingPower = LaserJammer.JammingPower
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdatePosition(double deltaTime)
|
private void UpdatePosition(double deltaTime)
|
||||||
@ -63,23 +45,28 @@ namespace ActiveProtect.Models
|
|||||||
CurrentArmor = Math.Max(0, CurrentArmor - damage);
|
CurrentArmor = Math.Max(0, CurrentArmor - damage);
|
||||||
if (CurrentArmor <= 0)
|
if (CurrentArmor <= 0)
|
||||||
{
|
{
|
||||||
IsActive = false;
|
Deactivate();
|
||||||
PublishEvent(new EntityDestroyedEvent { DestroyedEntityId = Id });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Illuminate()
|
public void Illuminate()
|
||||||
{
|
{
|
||||||
IsIlluminated = true;
|
if (!IsIlluminated)
|
||||||
|
{
|
||||||
|
IsIlluminated = true;
|
||||||
|
Console.WriteLine($"坦克 {Id} 被激光照射");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StopIllumination()
|
public void StopIllumination()
|
||||||
{
|
{
|
||||||
IsIlluminated = false;
|
if (IsIlluminated)
|
||||||
|
{
|
||||||
|
IsIlluminated = false;
|
||||||
|
Console.WriteLine($"坦克 {Id} 激光照射停止");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 移除OnLaserIllumination和OnLaserIlluminationStop方法,因为现在由LaserWarner直接处理
|
|
||||||
|
|
||||||
public override string GetStatus()
|
public override string GetStatus()
|
||||||
{
|
{
|
||||||
return $"坦克 {Id}:\n" +
|
return $"坦克 {Id}:\n" +
|
||||||
@ -87,9 +74,7 @@ namespace ActiveProtect.Models
|
|||||||
$" 速度: {Speed:F2}/{MaxSpeed:F2}\n" +
|
$" 速度: {Speed:F2}/{MaxSpeed:F2}\n" +
|
||||||
$" 装甲: {CurrentArmor:F2}/{MaxArmor:F2}\n" +
|
$" 装甲: {CurrentArmor:F2}/{MaxArmor:F2}\n" +
|
||||||
$" 状态: {(IsActive ? "活动" : "已销毁")}\n" +
|
$" 状态: {(IsActive ? "活动" : "已销毁")}\n" +
|
||||||
$" 激光照射: {(IsIlluminated ? "是" : "否")}\n" +
|
$" 激光照射: {(IsIlluminated ? "是" : "否")}\n";
|
||||||
$" 激光报警: {(LaserWarner.IsAlarming ? "警报中" : "正常")}\n" +
|
|
||||||
$" 激光干扰: {(LaserJammer.IsJamming ? $"干扰中 (功率: {LaserJammer.JammingPower:F2})" : "未干扰")}";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
27
Program.cs
27
Program.cs
@ -19,9 +19,22 @@ namespace ActiveProtect
|
|||||||
InitialOrientation = new Orientation(0, 0, 0),
|
InitialOrientation = new Orientation(0, 0, 0),
|
||||||
InitialSpeed = 0,
|
InitialSpeed = 0,
|
||||||
MaxSpeed = 20,
|
MaxSpeed = 20,
|
||||||
MaxArmor = 100
|
MaxArmor = 100,
|
||||||
|
HasLaserWarner = true,
|
||||||
|
HasLaserJammer = true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
LaserWarnerConfig = new LaserWarnerConfig
|
||||||
|
{
|
||||||
|
AlarmDuration = 5.0
|
||||||
|
},
|
||||||
|
LaserJammerConfig = new LaserJammerConfig
|
||||||
|
{
|
||||||
|
MaxJammingCooldown = 5.0,
|
||||||
|
MaxJammingPower = 10000.0,
|
||||||
|
InitialJammingPower = 4000.0,
|
||||||
|
PowerIncreaseRate = 2000.0
|
||||||
|
},
|
||||||
MissileConfigs =
|
MissileConfigs =
|
||||||
[
|
[
|
||||||
// 标准导弹配置
|
// 标准导弹配置
|
||||||
@ -31,7 +44,7 @@ namespace ActiveProtect
|
|||||||
InitialSpeed = 10,
|
InitialSpeed = 10,
|
||||||
MaxSpeed = 400,
|
MaxSpeed = 400,
|
||||||
TargetIndex = 0,
|
TargetIndex = 0,
|
||||||
MaxFlightTime = 0,
|
MaxFlightTime = 0.5,
|
||||||
MaxFlightDistance = 5000,
|
MaxFlightDistance = 5000,
|
||||||
ThrustAcceleration = 80,
|
ThrustAcceleration = 80,
|
||||||
MaxEngineBurnTime = 5,
|
MaxEngineBurnTime = 5,
|
||||||
@ -48,7 +61,7 @@ namespace ActiveProtect
|
|||||||
InitialSpeed = 700,
|
InitialSpeed = 700,
|
||||||
MaxSpeed = 800,
|
MaxSpeed = 800,
|
||||||
TargetIndex = 0,
|
TargetIndex = 0,
|
||||||
MaxFlightTime = 0,
|
MaxFlightTime = 0.5,
|
||||||
MaxFlightDistance = 5000,
|
MaxFlightDistance = 5000,
|
||||||
ThrustAcceleration = 50,
|
ThrustAcceleration = 50,
|
||||||
MaxEngineBurnTime = 5,
|
MaxEngineBurnTime = 5,
|
||||||
@ -65,7 +78,7 @@ namespace ActiveProtect
|
|||||||
InitialSpeed = 10,
|
InitialSpeed = 10,
|
||||||
MaxSpeed = 300,
|
MaxSpeed = 300,
|
||||||
TargetIndex = 0,
|
TargetIndex = 0,
|
||||||
MaxFlightTime = 0,
|
MaxFlightTime = 0.5,
|
||||||
MaxFlightDistance = 3000,
|
MaxFlightDistance = 3000,
|
||||||
ThrustAcceleration = 50,
|
ThrustAcceleration = 50,
|
||||||
MaxEngineBurnTime = 5,
|
MaxEngineBurnTime = 5,
|
||||||
@ -82,7 +95,7 @@ namespace ActiveProtect
|
|||||||
InitialSpeed = 700,
|
InitialSpeed = 700,
|
||||||
MaxSpeed = 800,
|
MaxSpeed = 800,
|
||||||
TargetIndex = 0,
|
TargetIndex = 0,
|
||||||
MaxFlightTime = 20,
|
MaxFlightTime = 5,
|
||||||
MaxFlightDistance = 4500,
|
MaxFlightDistance = 4500,
|
||||||
ThrustAcceleration = 50,
|
ThrustAcceleration = 50,
|
||||||
MaxEngineBurnTime = 5,
|
MaxEngineBurnTime = 5,
|
||||||
@ -98,7 +111,6 @@ namespace ActiveProtect
|
|||||||
new LaserDesignatorConfig
|
new LaserDesignatorConfig
|
||||||
{
|
{
|
||||||
InitialPosition = new Vector3D(500, 150, 100),
|
InitialPosition = new Vector3D(500, 150, 100),
|
||||||
TargetId = "Tank_1",
|
|
||||||
MaxIlluminationRange = 1000
|
MaxIlluminationRange = 1000
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -109,7 +121,7 @@ namespace ActiveProtect
|
|||||||
var simulationManager = new SimulationManager(config);
|
var simulationManager = new SimulationManager(config);
|
||||||
|
|
||||||
// 运行仿真
|
// 运行仿真
|
||||||
int maxIterations = 1000; // 增加最大迭代次数
|
int maxIterations = 1000;
|
||||||
int iteration = 0;
|
int iteration = 0;
|
||||||
while (!simulationManager.IsSimulationEnded && iteration < maxIterations)
|
while (!simulationManager.IsSimulationEnded && iteration < maxIterations)
|
||||||
{
|
{
|
||||||
@ -121,6 +133,5 @@ namespace ActiveProtect
|
|||||||
|
|
||||||
Console.WriteLine("仿真结束");
|
Console.WriteLine("仿真结束");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -7,6 +7,8 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
public List<TankConfig> TankConfigs { get; set; }
|
public List<TankConfig> TankConfigs { get; set; }
|
||||||
public List<MissileConfig> MissileConfigs { get; set; }
|
public List<MissileConfig> MissileConfigs { get; set; }
|
||||||
public List<LaserDesignatorConfig> LaserDesignatorConfigs { get; set; }
|
public List<LaserDesignatorConfig> LaserDesignatorConfigs { get; set; }
|
||||||
|
public LaserWarnerConfig LaserWarnerConfig { get; set; }
|
||||||
|
public LaserJammerConfig LaserJammerConfig { get; set; }
|
||||||
public double SimulationTimeStep { get; set; }
|
public double SimulationTimeStep { get; set; }
|
||||||
|
|
||||||
public SimulationConfig()
|
public SimulationConfig()
|
||||||
@ -14,6 +16,8 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
TankConfigs = [];
|
TankConfigs = [];
|
||||||
MissileConfigs = [];
|
MissileConfigs = [];
|
||||||
LaserDesignatorConfigs = [];
|
LaserDesignatorConfigs = [];
|
||||||
|
LaserWarnerConfig = new LaserWarnerConfig();
|
||||||
|
LaserJammerConfig = new LaserJammerConfig();
|
||||||
SimulationTimeStep = 0.1; // 默认时间步长为0.1秒
|
SimulationTimeStep = 0.1; // 默认时间步长为0.1秒
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -26,6 +30,9 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
public double MaxSpeed { get; set; }
|
public double MaxSpeed { get; set; }
|
||||||
public double MaxArmor { get; set; }
|
public double MaxArmor { get; set; }
|
||||||
|
|
||||||
|
public bool HasLaserWarner { get; set; }
|
||||||
|
public bool HasLaserJammer { get; set; }
|
||||||
|
|
||||||
public TankConfig()
|
public TankConfig()
|
||||||
{
|
{
|
||||||
InitialPosition = new Vector3D(0, 0, 0);
|
InitialPosition = new Vector3D(0, 0, 0);
|
||||||
@ -53,7 +60,7 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
|
|
||||||
public MissileConfig()
|
public MissileConfig()
|
||||||
{
|
{
|
||||||
InitialPosition = new Vector3D(0, 0, 0); // 初始位<EFBFBD><EFBFBD>
|
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; // 最大速度
|
||||||
@ -73,12 +80,10 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
public class LaserDesignatorConfig
|
public class LaserDesignatorConfig
|
||||||
{
|
{
|
||||||
public Vector3D InitialPosition { get; set; }
|
public Vector3D InitialPosition { get; set; }
|
||||||
public string TargetId { get; set; }
|
|
||||||
public double MaxIlluminationRange { get; set; }
|
public double MaxIlluminationRange { get; set; }
|
||||||
public LaserDesignatorConfig()
|
public LaserDesignatorConfig()
|
||||||
{
|
{
|
||||||
InitialPosition = new Vector3D(0, 0, 0);
|
InitialPosition = new Vector3D(0, 0, 0);
|
||||||
TargetId = "";
|
|
||||||
MaxIlluminationRange = 1000;
|
MaxIlluminationRange = 1000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,4 +130,31 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static FlightStageConfig LaserSemiActiveGuidedMissile => new(enableAcceleration: false);
|
public static FlightStageConfig LaserSemiActiveGuidedMissile => new(enableAcceleration: false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LaserWarnerConfig
|
||||||
|
{
|
||||||
|
public double AlarmDuration { get; set; }
|
||||||
|
|
||||||
|
public LaserWarnerConfig()
|
||||||
|
{
|
||||||
|
AlarmDuration = 5.0; // 默认警报持续5秒
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LaserJammerConfig
|
||||||
|
{
|
||||||
|
public double MaxJammingCooldown { get; set; }
|
||||||
|
public double MaxJammingPower { get; set; }
|
||||||
|
public double InitialJammingPower { get; set; }
|
||||||
|
public double PowerIncreaseRate { get; set; }
|
||||||
|
|
||||||
|
public LaserJammerConfig()
|
||||||
|
{
|
||||||
|
MaxJammingCooldown = 5.0;
|
||||||
|
MaxJammingPower = 10000.0;
|
||||||
|
InitialJammingPower = 4000.0;
|
||||||
|
PowerIncreaseRate = 2000.0; // 每秒增加的功率
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,12 +8,13 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
public Vector3D Position { get; set; } = position;
|
public Vector3D Position { get; set; } = position;
|
||||||
public Orientation Orientation { get; set; } = orientation;
|
public Orientation Orientation { get; set; } = orientation;
|
||||||
public ISimulationManager SimulationManager { get; set; } = simulationManager;
|
public ISimulationManager SimulationManager { get; set; } = simulationManager;
|
||||||
|
public bool IsActive { get; protected set; } = true;
|
||||||
|
|
||||||
public abstract void Update(double deltaTime);
|
public abstract void Update(double deltaTime);
|
||||||
|
|
||||||
public virtual string GetStatus()
|
public virtual string GetStatus()
|
||||||
{
|
{
|
||||||
return $"{GetType().Name} {Id} at {Position}, Orientation: {Orientation}";
|
return $"{GetType().Name} {Id} at {Position}, Orientation: {Orientation}, Active: {IsActive}";
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void PublishEvent(SimulationEvent evt)
|
protected void PublishEvent(SimulationEvent evt)
|
||||||
@ -22,5 +23,17 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
evt.Timestamp = SimulationManager.CurrentTime;
|
evt.Timestamp = SimulationManager.CurrentTime;
|
||||||
SimulationManager.PublishEvent(evt);
|
SimulationManager.PublishEvent(evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual void Activate()
|
||||||
|
{
|
||||||
|
IsActive = true;
|
||||||
|
PublishEvent(new EntityActivatedEvent { ActivatedEntityId = Id });
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void Deactivate()
|
||||||
|
{
|
||||||
|
IsActive = false;
|
||||||
|
PublishEvent(new EntityDeactivatedEvent { DeactivatedEntityId = Id });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,4 +31,14 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
{
|
{
|
||||||
public string? TargetId { get; set; }
|
public string? TargetId { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class EntityActivatedEvent : SimulationEvent
|
||||||
|
{
|
||||||
|
public string? ActivatedEntityId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class EntityDeactivatedEvent : SimulationEvent
|
||||||
|
{
|
||||||
|
public string? DeactivatedEntityId { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -9,12 +9,14 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
{
|
{
|
||||||
double CurrentTime { get; }
|
double CurrentTime { get; }
|
||||||
|
|
||||||
|
void AddElement(SimulationElement element);
|
||||||
SimulationElement GetEntityById(string id);
|
SimulationElement GetEntityById(string id);
|
||||||
void HandleTargetHit(string targetId, string missileId);
|
void HandleTargetHit(string targetId, string missileId);
|
||||||
|
|
||||||
void PublishEvent(SimulationEvent evt);
|
void PublishEvent(SimulationEvent evt);
|
||||||
void SubscribeToEvent<T>(Action<T> handler) where T : SimulationEvent;
|
void SubscribeToEvent<T>(Action<T> handler) where T : SimulationEvent;
|
||||||
void UnsubscribeFromEvent<T>(Action<T> handler) where T : SimulationEvent;
|
void UnsubscribeFromEvent<T>(Action<T> handler) where T : SimulationEvent;
|
||||||
|
void UnsubscribeAllEvents(SimulationElement element);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SimulationManager : ISimulationManager
|
public class SimulationManager : ISimulationManager
|
||||||
@ -24,6 +26,7 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
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)>>();
|
||||||
|
|
||||||
public SimulationManager(SimulationConfig config)
|
public SimulationManager(SimulationConfig config)
|
||||||
{
|
{
|
||||||
@ -36,17 +39,54 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
|
|
||||||
private void InitializeSimulation()
|
private void InitializeSimulation()
|
||||||
{
|
{
|
||||||
// 创建坦克(保持不变)
|
// 创建坦克
|
||||||
for (int i = 0; i < config.TankConfigs.Count; i++)
|
for (int i = 0; i < config.TankConfigs.Count; i++)
|
||||||
{
|
{
|
||||||
var tankConfig = config.TankConfigs[i];
|
var tankConfig = config.TankConfigs[i];
|
||||||
Elements.Add(new Tank($"Tank_{i + 1}", tankConfig, this));
|
var tank = new Tank($"Tank_{i + 1}", tankConfig, this);
|
||||||
|
Elements.Add(tank);
|
||||||
|
|
||||||
|
// 为坦克创建激光告警器
|
||||||
|
if (tankConfig.HasLaserWarner)
|
||||||
|
{
|
||||||
|
var laserWarner = new LaserWarner(
|
||||||
|
$"LaserWarner_{tank.Id}",
|
||||||
|
tank.Position,
|
||||||
|
tank.Orientation,
|
||||||
|
this,
|
||||||
|
tank.Id,
|
||||||
|
config.LaserWarnerConfig
|
||||||
|
);
|
||||||
|
Elements.Add(laserWarner);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 为坦克创建激光干扰机
|
||||||
|
if (tankConfig.HasLaserJammer)
|
||||||
|
{
|
||||||
|
var laserJammer = new LaserJammer(
|
||||||
|
$"LaserJammer_{tank.Id}",
|
||||||
|
tank.Position,
|
||||||
|
tank.Orientation,
|
||||||
|
this,
|
||||||
|
tank.Id,
|
||||||
|
config.LaserJammerConfig
|
||||||
|
);
|
||||||
|
Elements.Add(laserJammer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建导弹(修改这部分)
|
// 创建导弹(修改这部分)
|
||||||
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];
|
||||||
|
|
||||||
|
// 确保 MaxFlightTime 设置合理
|
||||||
|
if (missileConfig.MaxFlightTime <= 0)
|
||||||
|
{
|
||||||
|
missileConfig.MaxFlightTime = 300; // 设置一个默认值,比如 300 秒
|
||||||
|
Console.WriteLine($"警告:导弹配置 {i} 的 MaxFlightTime 无效,已设置为默认值 300 秒");
|
||||||
|
}
|
||||||
|
|
||||||
Missile missile = missileConfig.Type switch
|
Missile missile = missileConfig.Type switch
|
||||||
{
|
{
|
||||||
MissileType.SemiActiveLaserGuidance => new LaserSemiActiveGuidedMissile(
|
MissileType.SemiActiveLaserGuidance => new LaserSemiActiveGuidedMissile(
|
||||||
@ -67,7 +107,7 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
for (int i = 0; i < config.LaserDesignatorConfigs.Count; i++)
|
for (int i = 0; i < config.LaserDesignatorConfigs.Count; i++)
|
||||||
{
|
{
|
||||||
var laserDesignatorConfig = config.LaserDesignatorConfigs[i];
|
var laserDesignatorConfig = config.LaserDesignatorConfigs[i];
|
||||||
var laserDesignator = new LaserDesignator($"LD_{i + 1}", laserDesignatorConfig, this);
|
var laserDesignator = new LaserDesignator($"LD_{i + 1}", "Tank_1", laserDesignatorConfig, this);
|
||||||
Elements.Add(laserDesignator);
|
Elements.Add(laserDesignator);
|
||||||
laserDesignator.ActivateLaser(); // 激活激光目标指示器
|
laserDesignator.ActivateLaser(); // 激活激光目标指示器
|
||||||
}
|
}
|
||||||
@ -93,6 +133,17 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
eventHandlers[eventType] = new List<Delegate>();
|
eventHandlers[eventType] = new List<Delegate>();
|
||||||
}
|
}
|
||||||
eventHandlers[eventType].Add(handler);
|
eventHandlers[eventType].Add(handler);
|
||||||
|
|
||||||
|
// 记录订阅关系
|
||||||
|
var element = Elements.FirstOrDefault(e => e.GetType().GetMethods().Any(m => m.Name == handler.Method.Name));
|
||||||
|
if (element != null)
|
||||||
|
{
|
||||||
|
if (!elementSubscriptions.ContainsKey(element))
|
||||||
|
{
|
||||||
|
elementSubscriptions[element] = new List<(Type, Delegate)>();
|
||||||
|
}
|
||||||
|
elementSubscriptions[element].Add((eventType, handler));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UnsubscribeFromEvent<T>(Action<T> handler) where T : SimulationEvent
|
public void UnsubscribeFromEvent<T>(Action<T> handler) where T : SimulationEvent
|
||||||
@ -102,6 +153,28 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
{
|
{
|
||||||
eventHandlers[eventType].Remove(handler);
|
eventHandlers[eventType].Remove(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 移除订阅关系记录
|
||||||
|
var element = Elements.FirstOrDefault(e => e.GetType().GetMethods().Any(m => m.Name == handler.Method.Name));
|
||||||
|
if (element != null && elementSubscriptions.ContainsKey(element))
|
||||||
|
{
|
||||||
|
elementSubscriptions[element].RemoveAll(s => Delegate.Equals(s.Item2, handler));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UnsubscribeAllEvents(SimulationElement element)
|
||||||
|
{
|
||||||
|
if (elementSubscriptions.ContainsKey(element))
|
||||||
|
{
|
||||||
|
foreach (var subscription in elementSubscriptions[element])
|
||||||
|
{
|
||||||
|
if (eventHandlers.ContainsKey(subscription.Item1))
|
||||||
|
{
|
||||||
|
eventHandlers[subscription.Item1].Remove(subscription.Item2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elementSubscriptions.Remove(element);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
@ -112,14 +185,21 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
|
|
||||||
foreach (var element in Elements.ToList())
|
foreach (var element in Elements.ToList())
|
||||||
{
|
{
|
||||||
element.Update(config.SimulationTimeStep);
|
if (element.IsActive)
|
||||||
|
{
|
||||||
|
element.Update(config.SimulationTimeStep);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UnsubscribeAllEvents(element);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 移除不活跃的元素
|
// 移除不活跃的元素
|
||||||
Elements.RemoveAll(e => (e is Tank tank && !tank.IsActive) || (e is Missile missile && !missile.IsActive));
|
Elements.RemoveAll(e => !e.IsActive);
|
||||||
|
|
||||||
// 检查是否所有导弹都结束飞行
|
// 检查是否所有导弹都结束飞行
|
||||||
if (!Elements.Any(e => e is Missile))
|
if (!Elements.Any(e => e is Missile && e.IsActive))
|
||||||
{
|
{
|
||||||
EndSimulation();
|
EndSimulation();
|
||||||
}
|
}
|
||||||
@ -158,19 +238,11 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
// 对坦克造成伤害
|
// 对坦克造成伤害
|
||||||
tank.TakeDamage(damage, true);
|
tank.TakeDamage(damage, true);
|
||||||
|
|
||||||
// 移除已爆炸的导弹
|
|
||||||
RemoveEntity(missileId);
|
|
||||||
|
|
||||||
// 记录击中事件
|
// 记录击中事件
|
||||||
LogHitEvent(targetId, missileId, damage);
|
LogHitEvent(targetId, missileId, damage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RemoveEntity(string missileId)
|
|
||||||
{
|
|
||||||
Elements.Remove(GetEntityById(missileId));
|
|
||||||
}
|
|
||||||
|
|
||||||
private double CalculateMissileDamage(Missile missile)
|
private double CalculateMissileDamage(Missile missile)
|
||||||
{
|
{
|
||||||
// 这里可以根据导弹类型、速度等因素计算伤害
|
// 这里可以根据导弹类型、速度等因素计算伤害
|
||||||
@ -178,9 +250,14 @@ namespace ActiveProtect.SimulationEnvironment
|
|||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
private 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} 点伤害");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddElement(SimulationElement element)
|
||||||
|
{
|
||||||
|
Elements.Add(element);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user