diff --git a/Environment/ISimulatinManager.cs b/Environment/ISimulatinManager.cs deleted file mode 100644 index 2daa4a3..0000000 --- a/Environment/ISimulatinManager.cs +++ /dev/null @@ -1,7 +0,0 @@ -using ActiveProtect.Models; - -public interface ISimulationManager -{ - Vector3D GetElementPosition(string elementId); - // 添加其他必要的方法 -} diff --git a/Models/ILaserIlluminatable.cs b/Models/ILaserIlluminatable.cs new file mode 100644 index 0000000..693eebb --- /dev/null +++ b/Models/ILaserIlluminatable.cs @@ -0,0 +1,13 @@ +using ActiveProtect.SimulationEnvironment; + +namespace ActiveProtect.Models +{ + public interface ILaserIlluminatable + { + bool IsIlluminated { get; } + void Illuminate(); + // 移除重复的 Illuminate 方法(如果存在) + void StopIllumination(); + Vector3D Position { get; } + } +} \ No newline at end of file diff --git a/Models/LaserDesignator.cs b/Models/LaserDesignator.cs new file mode 100644 index 0000000..dce516b --- /dev/null +++ b/Models/LaserDesignator.cs @@ -0,0 +1,56 @@ +using ActiveProtect.SimulationEnvironment; + +namespace ActiveProtect.Models +{ + public class LaserDesignator(string id, LaserDesignatorConfig laserDesignatorConfig, ISimulationManager simulationManager) : SimulationElement(id, laserDesignatorConfig.InitialPosition, new Orientation(), simulationManager) + { + public string TargetId { get; private set; } = laserDesignatorConfig.TargetId; + public bool IsActive { get; private set; } = true; + private const double MaxIlluminationRange = 1000; // 1公里,单位:米 + + public void ActivateLaser() + { + IsActive = true; + } + + public void DeactivateLaser() + { + IsActive = false; + } + + public override void Update(double deltaTime) + { + + if (IsActive) + { + IlluminateTarget(); + } + } + + private void IlluminateTarget() + { + var target = SimulationManager.GetEntityById(TargetId) as ILaserIlluminatable; + if (target != null) + { + double distanceToTarget = Vector3D.Distance(Position, target.Position); + if (distanceToTarget <= MaxIlluminationRange) + { + target.Illuminate(); + } + else + { + target.StopIllumination(); + } + } + } + + public override string GetStatus() + { + return $"激光目标指示器 {Id}:\n" + + $" 位置: {Position}\n" + + $" 目标: {TargetId}\n" + + $" 激活状态: {(IsActive ? "激活" : "未激活")}"; + } + } + +} \ No newline at end of file diff --git a/Models/LaserSemiActiveGuidedMissile.cs b/Models/LaserSemiActiveGuidedMissile.cs index 7337f64..ebed8b9 100644 --- a/Models/LaserSemiActiveGuidedMissile.cs +++ b/Models/LaserSemiActiveGuidedMissile.cs @@ -4,27 +4,18 @@ namespace ActiveProtect.Models { public class LaserSemiActiveGuidedMissile : Missile { + // 添加新的属性 + public bool IsLaserDetected { get; private set; } = false; + private const double LaserLockDistance = 1000; // 1公里,单位:米 + // 激光半主动制导导弹的特殊属性 public bool IsLaserLocked { get; private set; } = false; public LaserSemiActiveGuidedMissile( string id, - Vector3D position, - Orientation orientation, - double initialSpeed, - double maxSpeed, - string targetId, - double maxFlightTime, - double maxFlightDistance, - MissileDistanceParams distanceParams, - FlightStageConfig stageConfig, - ISimulationManager simulationManager, - double thrustAcceleration, - double maxEngineBurnTime, - double maxAcceleration, - double proportionalNavigationCoefficient) - : base(id, position, orientation, initialSpeed, maxSpeed, targetId, maxFlightTime, maxFlightDistance, - distanceParams, stageConfig, simulationManager, thrustAcceleration, maxEngineBurnTime, maxAcceleration, proportionalNavigationCoefficient) + MissileConfig missileConfig, + ISimulationManager simulationManager) + : base(id, missileConfig, simulationManager) { Type = MissileType.SemiActiveLaserGuidance; } @@ -33,20 +24,51 @@ namespace ActiveProtect.Models { base.Update(deltaTime); - // 激光半主动制导导弹的特殊更新逻辑 - UpdateLaserLock(); + // 更新激光检测和锁定逻辑 + UpdateLaserDetection(); + if (IsLaserDetected) + { + UpdateLaserLock(); + } + } + + private void UpdateLaserDetection() + { + // 检查是否有激光照射目标 + var target = SimulationManager.GetEntityById(TargetId) as ILaserIlluminatable; + if (target != null) + { + IsLaserDetected = target.IsIlluminated && DistanceToTarget <= LaserLockDistance; + } + else + { + IsLaserDetected = false; + } } private void UpdateLaserLock() { - // 这里实现激光锁定逻辑 - // 例如,根据距离和其他因素来决定是否锁定目标 - IsLaserLocked = DistanceToTarget < DistanceParams.TerminalGuidanceDistance; + // 如果检测到激光,则锁定目标 + IsLaserLocked = IsLaserDetected; + + if (IsLaserLocked) + { + // 根据激光照射的光斑进行导引 + // 这里可以添加更精确的导引逻辑 + AdjustTrajectoryBasedOnLaserGuidance(); + } + } + + private void AdjustTrajectoryBasedOnLaserGuidance() + { + // 实现基于激光导引的轨迹调整 + // 这里可以添加更复杂的导引算法 } public override string GetStatus() { return base.GetStatus().Replace("导弹", "激光半主动制导导弹") + + $"\n 激光检测: {(IsLaserDetected ? "是" : "否")}" + $"\n 激光锁定: {(IsLaserLocked ? "是" : "否")}"; } } diff --git a/Models/Missile.cs b/Models/Missile.cs index 2e87931..e6a95f0 100644 --- a/Models/Missile.cs +++ b/Models/Missile.cs @@ -79,8 +79,6 @@ namespace ActiveProtect.Models private Vector3D LastTargetPosition; private const double N = 3; // 比例导引系数 - private readonly ISimulationManager _simulationManager; - public double ThrustAcceleration { get; protected set; } public double EngineBurnTime { get; protected set; } public double MaxEngineBurnTime { get; protected set; } @@ -89,32 +87,27 @@ namespace ActiveProtect.Models public double ProportionalNavigationCoefficient { get; set; } - public Missile(string id, Vector3D position, Orientation orientation, double initialSpeed, double maxSpeed, - string targetId, double maxFlightTime, double maxFlightDistance, - MissileDistanceParams distanceParams, - FlightStageConfig stageConfig, - ISimulationManager simulationManager, - double thrustAcceleration, double maxEngineBurnTime, double maxAcceleration, - double proportionalNavigationCoefficient) - : base(id, position, orientation) + public Missile(string id, MissileConfig missileConfig, ISimulationManager simulationManager) + : base(id, missileConfig.InitialPosition, missileConfig.InitialOrientation, simulationManager) { - Speed = initialSpeed; - MaxSpeed = maxSpeed; - TargetId = targetId; - MaxFlightTime = maxFlightTime; - MaxFlightDistance = maxFlightDistance; - DistanceParams = distanceParams; - StageConfig = stageConfig; + Speed = missileConfig.InitialSpeed; + MaxSpeed = missileConfig.MaxSpeed; + MaxFlightTime = missileConfig.MaxFlightTime; + MaxFlightDistance = missileConfig.MaxFlightDistance; + DistanceParams = missileConfig.DistanceParams; + StageConfig = missileConfig.StageConfig; IsActive = true; FlightTime = 0; FlightDistance = 0; - _simulationManager = simulationManager; - ThrustAcceleration = thrustAcceleration; + SimulationManager = simulationManager; + ThrustAcceleration = missileConfig.ThrustAcceleration; EngineBurnTime = 0; - MaxEngineBurnTime = maxEngineBurnTime; - MaxAcceleration = maxAcceleration; - Vector3D horizontalDirection = new Vector3D(orientation.ToVector().X, 0, orientation.ToVector().Z).Normalize(); - Velocity = horizontalDirection * initialSpeed; + MaxEngineBurnTime = missileConfig.MaxEngineBurnTime; + MaxAcceleration = missileConfig.MaxAcceleration; + ProportionalNavigationCoefficient = missileConfig.ProportionalNavigationCoefficient; + TargetId = $"Tank_{missileConfig.TargetIndex + 1}"; + Vector3D horizontalDirection = new Vector3D(Orientation.ToVector().X, 0, Orientation.ToVector().Z).Normalize(); + Velocity = horizontalDirection * missileConfig.InitialSpeed; // 设置初始阶段 CurrentStage = StageConfig.EnableLaunch ? FlightStage.Launch : @@ -125,8 +118,7 @@ namespace ActiveProtect.Models Console.WriteLine($"导弹 {Id} 的初始阶: {CurrentStage}"); - LastTargetPosition = position; // 初始化 LastTargetPosition - ProportionalNavigationCoefficient = proportionalNavigationCoefficient; + LastTargetPosition = Position; // 初始化 LastTargetPosition } public override void Update(double deltaTime) @@ -160,7 +152,7 @@ namespace ActiveProtect.Models FlightTime += deltaTime; FlightDistance += Speed * deltaTime; - UpdateDistanceToTarget(Vector3D.Distance(Position, _simulationManager.GetElementPosition(TargetId))); + UpdateDistanceToTarget(Vector3D.Distance(Position, SimulationManager.GetElementPosition(TargetId))); // 首先检查是否命中目标 if (CheckHit()) @@ -200,7 +192,7 @@ namespace ActiveProtect.Models private (Vector3D, Vector3D) CalculateDerivatives(Vector3D position, Vector3D velocity, double deltaTime) { - Vector3D targetPosition = _simulationManager.GetElementPosition(TargetId); + Vector3D targetPosition = SimulationManager.GetElementPosition(TargetId); Vector3D LOS = targetPosition - position; Vector3D LOSRate = (targetPosition - LastTargetPosition) / deltaTime - velocity; Vector3D guidanceAcceleration = Vector3D.CrossProduct(Vector3D.CrossProduct(LOS, LOSRate), LOS).Normalize() @@ -306,10 +298,4 @@ namespace ActiveProtect.Models } } - public struct MissileDistanceParams(double terminalGuidanceDistance, double attackDistance, double explosionDistance) - { - public double TerminalGuidanceDistance { get; set; } = terminalGuidanceDistance; - public double AttackDistance { get; set; } = attackDistance; - public double ExplosionDistance { get; set; } = explosionDistance; - } } \ No newline at end of file diff --git a/Models/Tank.cs b/Models/Tank.cs index 645fa8d..809c0f9 100644 --- a/Models/Tank.cs +++ b/Models/Tank.cs @@ -2,22 +2,29 @@ using ActiveProtect.SimulationEnvironment; namespace ActiveProtect.Models { - public class Tank(string id, Vector3D position, Orientation orientation, double initialSpeed, double maxSpeed, double maxArmor) : SimulationElement(id, position, orientation) + public class Tank : SimulationElement, ILaserIlluminatable { - public double Speed { get; set; } = initialSpeed; - public bool IsActive { get; private set; } = true; - public double MaxSpeed { get; private set; } = maxSpeed; - public double MaxArmor { get; private set; } = maxArmor; - public double Armor { get; private set; } = maxArmor; - public double CurrentArmor { get; private set; } = maxArmor; + public double Speed { get; set; } = 0; + public bool IsActive { get; private set; } = false; + public double MaxSpeed { get; private set; } = 0; + public double MaxArmor { get; private set; } = 0; + public double Armor { get; private set; } = 0; + public double CurrentArmor { get; private set; } = 0; + public bool IsIlluminated { get; private set; } = false; - public override void Update(double deltaTime) + public Tank(string id, TankConfig tankConfig, ISimulationManager simulationManager) + : base(id, tankConfig.InitialPosition, tankConfig.InitialOrientation, simulationManager) { - if (!IsActive) return; - - Position.X += Speed * Math.Cos(Orientation.Yaw) * Math.Cos(Orientation.Pitch) * deltaTime; - Position.Y += Speed * Math.Sin(Orientation.Pitch) * deltaTime; - Position.Z += Speed * Math.Sin(Orientation.Yaw) * Math.Cos(Orientation.Pitch) * deltaTime; + Position = tankConfig.InitialPosition; + Orientation = tankConfig.InitialOrientation; + Speed = tankConfig.InitialSpeed; + IsActive = true; + MaxSpeed = tankConfig.MaxSpeed; + MaxArmor = tankConfig.MaxArmor; + Armor = tankConfig.MaxArmor; + CurrentArmor = tankConfig.MaxArmor; + IsIlluminated = false; + SimulationManager = simulationManager; } public void TakeDamage(double damage) @@ -30,11 +37,59 @@ namespace ActiveProtect.Models } } + public void Illuminate() + { + IsIlluminated = true; + } + + public void StopIllumination() + { + IsIlluminated = false; + } + + public override void Update(double deltaTime) + { + // 移除对基类抽象方法的调用 + // 实现坦克特定的更新逻辑 + UpdatePosition(deltaTime); + UpdateArmor(); + CheckIlluminationStatus(); + } + + private void UpdatePosition(double deltaTime) + { + // 根据速度更新坦克位置 + Vector3D direction = Orientation.ToVector(); + Vector3D movement = direction * Speed * deltaTime; + Position += movement; + } + + private void UpdateArmor() + { + // 可能的装甲恢复逻辑 + if (CurrentArmor < MaxArmor) + { + CurrentArmor = Math.Min(CurrentArmor + 10, MaxArmor); + } + } + + private void CheckIlluminationStatus() + { + // 检查激光照射状态,可能会影响坦克的其他属性 + if (IsIlluminated) + { + // 实现被激光照射时的效果 + } + } + public override string GetStatus() { - return $"坦克 {Id}:\n" + - $" 位置: X={Position.X:F2}, Y={Position.Y:F2}, Z={Position.Z:F2}\n" + - $" 装甲: {CurrentArmor:F2}"; + return base.GetStatus() + + $"\n 速度: {Speed}" + + $"\n 最大速度: {MaxSpeed}" + + $"\n 装甲: {CurrentArmor}/{MaxArmor}" + + $"\n 状态: {(IsActive ? "活动" : "已销毁")}" + + $"\n 激光照射: {(IsIlluminated ? "是" : "否")}"; } } } \ No newline at end of file diff --git a/Program.cs b/Program.cs index 8bb23e0..d72efbe 100644 --- a/Program.cs +++ b/Program.cs @@ -77,7 +77,7 @@ namespace ActiveProtect }, // 新增激光半主动制导导弹配置 new() { - InitialPosition = new Vector3D(2000, 150, 100), + InitialPosition = new Vector3D(1500, 150, 100), InitialOrientation = new Orientation(Math.PI, -0.12, 0), InitialSpeed = 700, MaxSpeed = 800, @@ -93,6 +93,14 @@ namespace ActiveProtect Type = MissileType.SemiActiveLaserGuidance } ], + LaserDesignatorConfigs = + [ + new LaserDesignatorConfig + { + InitialPosition = new Vector3D(500, 50, 100), + TargetId = "Tank_1" + } + ], SimulationTimeStep = 0.05 }; diff --git a/SimulationEnvironment/ISimulatinManager.cs b/SimulationEnvironment/ISimulatinManager.cs new file mode 100644 index 0000000..a79181a --- /dev/null +++ b/SimulationEnvironment/ISimulatinManager.cs @@ -0,0 +1,12 @@ +using ActiveProtect.Models; +using ActiveProtect.SimulationEnvironment; + +namespace ActiveProtect.SimulationEnvironment +{ + public interface ISimulationManager + { + Vector3D GetElementPosition(string elementId); + + SimulationElement GetEntityById(string id); + } +} \ No newline at end of file diff --git a/Environment/SimulationConfig.cs b/SimulationEnvironment/SimulationConfig.cs similarity index 77% rename from Environment/SimulationConfig.cs rename to SimulationEnvironment/SimulationConfig.cs index 290d687..19e7165 100644 --- a/Environment/SimulationConfig.cs +++ b/SimulationEnvironment/SimulationConfig.cs @@ -6,12 +6,14 @@ namespace ActiveProtect.SimulationEnvironment { public List TankConfigs { get; set; } public List MissileConfigs { get; set; } + public List LaserDesignatorConfigs { get; set; } public double SimulationTimeStep { get; set; } public SimulationConfig() { TankConfigs = []; MissileConfigs = []; + LaserDesignatorConfigs = []; SimulationTimeStep = 0.1; // 默认时间步长为0.1秒 } } @@ -44,15 +46,14 @@ namespace ActiveProtect.SimulationEnvironment public double ProportionalNavigationCoefficient { get; set; } public Missile.FlightStageConfig StageConfig { get; set; } public MissileDistanceParams DistanceParams { get; set; } - public MissileType Type { get; set; } - - // 新增属性 public double ThrustAcceleration { get; set; } public double MaxEngineBurnTime { get; set; } + public MissileType Type { get; set; } + public MissileConfig() { - InitialPosition = new Vector3D(0, 0, 0); // 初始位置 + InitialPosition = new Vector3D(0, 0, 0); // 初始位�� InitialOrientation = new Orientation(0, 0, 0); // 初始方向 InitialSpeed = 0; // 初始速度 MaxSpeed = 0; // 最大速度 @@ -68,4 +69,23 @@ namespace ActiveProtect.SimulationEnvironment Type = MissileType.StandardMissile; // 导弹类型 } } + + public class LaserDesignatorConfig + { + public Vector3D InitialPosition { get; set; } + public string TargetId { get; set; } + + public LaserDesignatorConfig() + { + InitialPosition = new Vector3D(0, 0, 0); + TargetId = ""; + } + } + + public struct MissileDistanceParams(double terminalGuidanceDistance, double attackDistance, double explosionDistance) + { + public double TerminalGuidanceDistance { get; set; } = terminalGuidanceDistance; + public double AttackDistance { get; set; } = attackDistance; + public double ExplosionDistance { get; set; } = explosionDistance; + } } diff --git a/Environment/SimulationElement.cs b/SimulationEnvironment/SimulationElement.cs similarity index 76% rename from Environment/SimulationElement.cs rename to SimulationEnvironment/SimulationElement.cs index f642c0b..9a3e92f 100644 --- a/Environment/SimulationElement.cs +++ b/SimulationEnvironment/SimulationElement.cs @@ -2,11 +2,12 @@ using ActiveProtect.Models; namespace ActiveProtect.SimulationEnvironment { - public abstract class SimulationElement(string id, Vector3D position, Orientation orientation) + public abstract class SimulationElement(string id, Vector3D position, Orientation orientation, ISimulationManager simulationManager) { public string Id { get; set; } = id; public Vector3D Position { get; set; } = position; public Orientation Orientation { get; set; } = orientation; + public ISimulationManager SimulationManager { get; set; } = simulationManager; public abstract void Update(double deltaTime); diff --git a/Environment/SimulationManager.cs b/SimulationEnvironment/SimulationManager.cs similarity index 55% rename from Environment/SimulationManager.cs rename to SimulationEnvironment/SimulationManager.cs index 6929662..7f1ccc8 100644 --- a/Environment/SimulationManager.cs +++ b/SimulationEnvironment/SimulationManager.cs @@ -27,14 +27,7 @@ namespace ActiveProtect.SimulationEnvironment for (int i = 0; i < config.TankConfigs.Count; i++) { var tankConfig = config.TankConfigs[i]; - Elements.Add(new Tank( - $"Tank_{i + 1}", - tankConfig.InitialPosition, - tankConfig.InitialOrientation, - tankConfig.InitialSpeed, - tankConfig.MaxSpeed, - tankConfig.MaxArmor - )); + Elements.Add(new Tank($"Tank_{i + 1}", tankConfig, this)); } // 创建导弹(修改这部分) @@ -45,41 +38,24 @@ namespace ActiveProtect.SimulationEnvironment { MissileType.SemiActiveLaserGuidance => new LaserSemiActiveGuidedMissile( $"LSGM_{i + 1}", - missileConfig.InitialPosition, - missileConfig.InitialOrientation, - missileConfig.InitialSpeed, - missileConfig.MaxSpeed, - $"Tank_{missileConfig.TargetIndex + 1}", - missileConfig.MaxFlightTime, - missileConfig.MaxFlightDistance, - missileConfig.DistanceParams, - missileConfig.StageConfig, - this, - missileConfig.ThrustAcceleration, - missileConfig.MaxEngineBurnTime, - missileConfig.MaxAcceleration, - missileConfig.ProportionalNavigationCoefficient + missileConfig, + this ), _ => new Missile( $"NM_{i + 1}", - missileConfig.InitialPosition, - missileConfig.InitialOrientation, - missileConfig.InitialSpeed, - missileConfig.MaxSpeed, - $"Tank_{missileConfig.TargetIndex + 1}", - missileConfig.MaxFlightTime, - missileConfig.MaxFlightDistance, - missileConfig.DistanceParams, - missileConfig.StageConfig, - this, - missileConfig.ThrustAcceleration, - missileConfig.MaxEngineBurnTime, - missileConfig.MaxAcceleration, - missileConfig.ProportionalNavigationCoefficient + missileConfig, + this ), }; Elements.Add(missile); } + + // 创建激光目标指示器 + for (int i = 0; i < config.LaserDesignatorConfigs.Count; i++) + { + var laserDesignatorConfig = config.LaserDesignatorConfigs[i]; + Elements.Add(new LaserDesignator($"LD_{i + 1}", laserDesignatorConfig, this)); + } } public void Update() @@ -130,5 +106,10 @@ namespace ActiveProtect.SimulationEnvironment } throw new ArgumentException($"Element with id {elementId} not found"); } + + public SimulationElement GetEntityById(string id) + { + return Elements.FirstOrDefault(e => e.Id == id) ?? throw new InvalidOperationException($"Entity with id {id} not found"); + } } } \ No newline at end of file