186 lines
6.4 KiB
C#
186 lines
6.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using ActiveProtect.Models;
|
|
|
|
namespace ActiveProtect.SimulationEnvironment
|
|
{
|
|
public interface ISimulationManager
|
|
{
|
|
double CurrentTime { get; }
|
|
|
|
SimulationElement GetEntityById(string id);
|
|
void HandleTargetHit(string targetId, string missileId);
|
|
|
|
void PublishEvent(SimulationEvent evt);
|
|
void SubscribeToEvent<T>(Action<T> handler) where T : SimulationEvent;
|
|
void UnsubscribeFromEvent<T>(Action<T> handler) where T : SimulationEvent;
|
|
}
|
|
|
|
public class SimulationManager : ISimulationManager
|
|
{
|
|
public List<SimulationElement> Elements { get; private set; }
|
|
public double CurrentTime { get; private set; }
|
|
public bool IsSimulationEnded { get; private set; }
|
|
private readonly SimulationConfig config;
|
|
private Dictionary<Type, List<Delegate>> eventHandlers = new Dictionary<Type, List<Delegate>>();
|
|
|
|
public SimulationManager(SimulationConfig config)
|
|
{
|
|
this.config = config;
|
|
Elements = [];
|
|
CurrentTime = 0;
|
|
IsSimulationEnded = false;
|
|
InitializeSimulation();
|
|
}
|
|
|
|
private void InitializeSimulation()
|
|
{
|
|
// 创建坦克(保持不变)
|
|
for (int i = 0; i < config.TankConfigs.Count; i++)
|
|
{
|
|
var tankConfig = config.TankConfigs[i];
|
|
Elements.Add(new Tank($"Tank_{i + 1}", tankConfig, this));
|
|
}
|
|
|
|
// 创建导弹(修改这部分)
|
|
for (int i = 0; i < config.MissileConfigs.Count; i++)
|
|
{
|
|
var missileConfig = config.MissileConfigs[i];
|
|
Missile missile = missileConfig.Type switch
|
|
{
|
|
MissileType.SemiActiveLaserGuidance => new LaserSemiActiveGuidedMissile(
|
|
$"LSGM_{i + 1}",
|
|
missileConfig,
|
|
this
|
|
),
|
|
_ => new Missile(
|
|
$"NM_{i + 1}",
|
|
missileConfig,
|
|
this
|
|
),
|
|
};
|
|
Elements.Add(missile);
|
|
}
|
|
|
|
// 创建激光目标指示器
|
|
for (int i = 0; i < config.LaserDesignatorConfigs.Count; i++)
|
|
{
|
|
var laserDesignatorConfig = config.LaserDesignatorConfigs[i];
|
|
var laserDesignator = new LaserDesignator($"LD_{i + 1}", laserDesignatorConfig, this);
|
|
Elements.Add(laserDesignator);
|
|
laserDesignator.ActivateLaser(); // 激活激光目标指示器
|
|
}
|
|
}
|
|
|
|
public void PublishEvent(SimulationEvent evt)
|
|
{
|
|
var eventType = evt.GetType();
|
|
if (eventHandlers.TryGetValue(eventType, out var handlers))
|
|
{
|
|
foreach (var handler in handlers)
|
|
{
|
|
handler.DynamicInvoke(evt);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void SubscribeToEvent<T>(Action<T> handler) where T : SimulationEvent
|
|
{
|
|
var eventType = typeof(T);
|
|
if (!eventHandlers.ContainsKey(eventType))
|
|
{
|
|
eventHandlers[eventType] = new List<Delegate>();
|
|
}
|
|
eventHandlers[eventType].Add(handler);
|
|
}
|
|
|
|
public void UnsubscribeFromEvent<T>(Action<T> handler) where T : SimulationEvent
|
|
{
|
|
var eventType = typeof(T);
|
|
if (eventHandlers.ContainsKey(eventType))
|
|
{
|
|
eventHandlers[eventType].Remove(handler);
|
|
}
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
if (IsSimulationEnded) return;
|
|
|
|
CurrentTime += config.SimulationTimeStep;
|
|
|
|
foreach (var element in Elements.ToList())
|
|
{
|
|
element.Update(config.SimulationTimeStep);
|
|
}
|
|
|
|
// 移除不活跃的元素
|
|
Elements.RemoveAll(e => (e is Tank tank && !tank.IsActive) || (e is Missile missile && !missile.IsActive));
|
|
|
|
// 检查是否所有导弹都结束飞行
|
|
if (!Elements.Any(e => e is Missile))
|
|
{
|
|
EndSimulation();
|
|
}
|
|
}
|
|
|
|
public void PrintStatus()
|
|
{
|
|
Console.WriteLine($"仿真时间: {CurrentTime:F2}");
|
|
foreach (var element in Elements)
|
|
{
|
|
Console.WriteLine(element.GetStatus());
|
|
}
|
|
Console.WriteLine();
|
|
}
|
|
|
|
private void EndSimulation()
|
|
{
|
|
IsSimulationEnded = true;
|
|
Console.WriteLine("仿真结束");
|
|
Console.WriteLine($"总仿真时间: {CurrentTime:F2} 秒");
|
|
Console.WriteLine($"剩余坦克数量: {Elements.Count(e => e is Tank)}");
|
|
}
|
|
|
|
public SimulationElement GetEntityById(string id)
|
|
{
|
|
return Elements.FirstOrDefault(e => e.Id == id) ?? throw new InvalidOperationException($"Entity with id {id} not found");
|
|
}
|
|
|
|
public void HandleTargetHit(string targetId, string missileId)
|
|
{
|
|
if (GetEntityById(targetId) is Tank tank && GetEntityById(missileId) is Missile missile)
|
|
{
|
|
// 计算导弹造成的伤害
|
|
double damage = CalculateMissileDamage(missile);
|
|
|
|
// 对坦克造成伤害
|
|
tank.TakeDamage(damage, true);
|
|
|
|
// 移除已爆炸的导弹
|
|
RemoveEntity(missileId);
|
|
|
|
// 记录击中事件
|
|
LogHitEvent(targetId, missileId, damage);
|
|
}
|
|
}
|
|
|
|
private void RemoveEntity(string missileId)
|
|
{
|
|
Elements.Remove(GetEntityById(missileId));
|
|
}
|
|
|
|
private double CalculateMissileDamage(Missile missile)
|
|
{
|
|
// 这里可以根据导弹类型、速度等因素计算伤害
|
|
// 现在我们简单地返回一个固定值
|
|
return 100;
|
|
}
|
|
|
|
private void LogHitEvent(string targetId, string missileId, double damage)
|
|
{
|
|
Console.WriteLine($"目标 {targetId} 被导弹 {missileId} 击中,造成 {damage} 点伤害");
|
|
}
|
|
}
|
|
} |