159 lines
5.7 KiB
C#
159 lines
5.7 KiB
C#
using static SFML.Window.Mouse;
|
|
|
|
namespace Car_simulation
|
|
{
|
|
public class Car
|
|
{
|
|
public Vector2 Position = new Vector2(0, 0);
|
|
public Vector2 Velocity => new Vector2(WheelSystem.CarSpeed, 0); // Now directly from wheels
|
|
|
|
public float Speed => WheelSystem.CarSpeed;
|
|
|
|
public float Mass { get; set; } = 1500f; // kg
|
|
public int WheelCount = 4;
|
|
public int DrivenWheels = 2;
|
|
|
|
public float ThrottleInput = 0f;
|
|
public float BrakeInput = 0f;
|
|
public float ClutchInput = 1f; // 0 = engaged, 1 = disengaged
|
|
public bool ForceClutch = false;
|
|
public float SteeringInput = 0f;
|
|
|
|
// Aerodynamics
|
|
private const float AirDensity = 1.225f;
|
|
public float DragCoefficient = 0.3f;
|
|
public float FrontalArea = 2.2f; // m²
|
|
public float RollingResistanceCoefficient = 0.015f;
|
|
|
|
// Components
|
|
public Engine Engine;
|
|
public Drivetrain Drivetrain;
|
|
public WheelSystem WheelSystem;
|
|
|
|
private EngineSound _engineSound;
|
|
private bool _audioEnabled = true;
|
|
|
|
public Car()
|
|
{
|
|
Engine = new Engine();
|
|
WheelSystem = new WheelSystem();
|
|
|
|
// Set car mass in wheel system (so it's included in energy calculations)
|
|
WheelSystem.CarMass = Mass;
|
|
WheelSystem.WheelCount = WheelCount;
|
|
WheelSystem.DrivenWheels = DrivenWheels;
|
|
|
|
Drivetrain = new Drivetrain(Engine, WheelSystem);
|
|
|
|
InitializeAudio();
|
|
}
|
|
|
|
private void InitializeAudio()
|
|
{
|
|
try
|
|
{
|
|
_engineSound = new EngineSound();
|
|
_engineSound.SetEngineState(Engine.IdleRPM, 0f);
|
|
_engineSound.StartSound();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine($"Audio initialization failed: {ex.Message}");
|
|
_audioEnabled = false;
|
|
}
|
|
}
|
|
|
|
public void Update(float deltaTime)
|
|
{
|
|
Engine.Throttle = ThrottleInput;
|
|
Drivetrain.ClutchEngagement = 1f - ClutchInput;
|
|
|
|
if (ForceClutch)
|
|
Drivetrain.ClutchEngagement = 0f;
|
|
|
|
// Update engine
|
|
Engine.Update(deltaTime);
|
|
|
|
// Update drivetrain (transfers energy between engine and wheels+car)
|
|
Drivetrain.Update(deltaTime);
|
|
|
|
// Calculate and apply resistance
|
|
float resistanceForce = CalculateTotalResistanceForce();
|
|
WheelSystem.ResistanceTorque = resistanceForce * WheelSystem.Radius;
|
|
WheelSystem.ApplyResistance(deltaTime);
|
|
|
|
// Apply braking
|
|
ApplyBraking(deltaTime);
|
|
|
|
// Update position based on velocity (which comes from WheelSystem)
|
|
Position += Velocity * deltaTime;
|
|
|
|
if (_audioEnabled)
|
|
UpdateAudio();
|
|
}
|
|
|
|
private void UpdateAudio()
|
|
{
|
|
try
|
|
{
|
|
float throttle = Engine.GetActualThrottle();
|
|
_engineSound.SetEngineState(Engine.RPM, throttle);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine($"Audio update error: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
private void ApplyBraking(float deltaTime)
|
|
{
|
|
if (BrakeInput <= 0) return;
|
|
|
|
float brakeTorque = BrakeInput * 3000f;
|
|
WheelSystem.ApplyTorque(-brakeTorque, deltaTime);
|
|
}
|
|
|
|
public float CalculateTotalResistanceForce()
|
|
{
|
|
float dragForce = CalculateDragForce();
|
|
float rollingForce = CalculateRollingResistanceForce();
|
|
return dragForce + rollingForce;
|
|
}
|
|
|
|
private float CalculateDragForce()
|
|
{
|
|
float speed = Speed;
|
|
return 0.5f * AirDensity * DragCoefficient * FrontalArea * speed * speed;
|
|
}
|
|
|
|
private float CalculateRollingResistanceForce()
|
|
{
|
|
return RollingResistanceCoefficient * Mass * 9.81f;
|
|
}
|
|
|
|
public void DisplayUpdate()
|
|
{
|
|
Console.SetCursorPosition(0, 0);
|
|
Console.WriteLine($"Engine Energy: {Engine.FlywheelEnergy,7:F0} J");
|
|
Console.WriteLine($"Engine Torque: {Engine.GetTorqueOutput(),7:F0} Nm");
|
|
Console.WriteLine($"Engine RPM: {Engine.RPM,7:F0}");
|
|
Console.WriteLine($"Total Energy: {WheelSystem.TotalEnergy,7:F0} J");
|
|
Console.WriteLine($" (Wheel Rot: {WheelSystem.GetRotationalEnergy(),7:F0} J)");
|
|
Console.WriteLine($" (Car Trans: {WheelSystem.GetTranslationalEnergy(),7:F0} J)");
|
|
Console.WriteLine($"Wheel RPM: {WheelSystem.RPM,7:F0}");
|
|
Console.WriteLine($"Vehicle: {Speed * 3.6f,7:F1} km/h");
|
|
Console.WriteLine($"Throttle: {Engine.GetActualThrottle() * 100,6:F1}%");
|
|
Console.WriteLine($"Power: {Engine.CurrentPower / 1000,6:F1} kW");
|
|
Console.WriteLine($"Transmitted: {Drivetrain.TransmittedPower / 1000,6:F1} kW");
|
|
Console.WriteLine($"Brake: {BrakeInput * 100,6:F1}%");
|
|
Console.WriteLine($"Speed Diff: {Drivetrain.GetSpeedDifferenceRPM(),6:F0} RPM");
|
|
Console.WriteLine($"Clutch: {ClutchInput * 100,6:F1}% disengaged");
|
|
Console.WriteLine($"Clutch T: {Drivetrain.ClutchTorque,6:F0} Nm");
|
|
Console.WriteLine($"Clutch Slip: {Drivetrain.GetClutchSlipPercent(),6:F1}%");
|
|
Console.WriteLine($"Resistance: {CalculateTotalResistanceForce(),6:F1} N");
|
|
Console.WriteLine($"Drag: {CalculateDragForce(),6:F1} N");
|
|
Console.WriteLine($"Rolling: {CalculateRollingResistanceForce(),6:F1} N");
|
|
Console.WriteLine($"Gear: {Drivetrain.GetCurrentGearName(),3} (Ratio: {Drivetrain.GearRatio:F2}:1)");
|
|
}
|
|
}
|
|
} |