diff --git a/Car simulation/Car.cs b/Car simulation/Car.cs index fd8a0a6..ca4368a 100644 --- a/Car simulation/Car.cs +++ b/Car simulation/Car.cs @@ -9,7 +9,7 @@ namespace Car_simulation public float Speed => WheelSystem.CarSpeed; - public float Mass { get; set; } = 1500f; // kg + public float Mass { get; set; } = 2000f; // kg public int WheelCount = 4; public int DrivenWheels = 2; @@ -90,7 +90,7 @@ namespace Car_simulation } } - public void Update(float deltaTime) + public void Update(float deltaTime, float totalTime) { Engine.Throttle = ThrottleInput; Drivetrain.ClutchEngagement = 1f - ClutchInput; @@ -99,7 +99,7 @@ namespace Car_simulation Drivetrain.ClutchEngagement = 0f; // Update engine - Engine.Update(deltaTime); + Engine.Update(deltaTime, totalTime); // Update drivetrain (transfers energy between engine and wheels+car) Drivetrain.Update(deltaTime); diff --git a/Car simulation/Drivetrain.cs b/Car simulation/Drivetrain.cs index 49dd748..48f5965 100644 --- a/Car simulation/Drivetrain.cs +++ b/Car simulation/Drivetrain.cs @@ -22,8 +22,8 @@ public float ClutchEngagement { get; set; } = 0f; // 0 = disengaged, 1 = fully engaged // Clutch properties - public float MaxClutchTorque { get; set; } = 450f; - public float ClutchStiffness { get; set; } = 20f; // Softer spring + public float MaxClutchTorque { get; set; } = 4500f; + public float ClutchStiffness { get; set; } = 50f; // Softer spring // State public float ClutchTorque { get; private set; } diff --git a/Car simulation/Engine.cs b/Car simulation/Engine.cs index 508a35c..430c1c0 100644 --- a/Car simulation/Engine.cs +++ b/Car simulation/Engine.cs @@ -13,20 +13,24 @@ // Physical properties public float MomentOfInertia { get; set; } = 0.25f; public float IdleRPM { get; set; } = 800f; + public float RevLimit { get; set; } = 12000; public float StallSpeed { get; set; } = 200f; public float Throttle { get; set; } = 0f; public bool IsRunning => RPM > StallSpeed; + private float _cutoffUntil = 0; + private bool _cutoff = false; // Torque curve public Dictionary TorqueCurve { get; set; } = new() { { 0f, 0f }, - { 800f, 150f }, - { 2000f, 250 }, - { 4500f, 250f }, - { 6800f, 200f }, - { 7200f, 150 }, - { 7500f, 0f }, + { 800f, 200f }, + { 2000f, 300 }, + { 4500f, 300f }, + { 6800f, 300 }, + { 7200f, 350 }, + { 11000f, 600f }, + { 12500, 500f }, }; public Engine() @@ -34,6 +38,16 @@ FlywheelEnergy = GetEnergyFromRPM(IdleRPM); } + public void UpdateRevLimiter(float totalTime) + { + if (RPM > RevLimit) + { + _cutoffUntil = totalTime + 0.01f; + } + + _cutoff = (totalTime < _cutoffUntil); + } + public float CalculateFrictionLoss(float deltaTime) { float frictionTorque; @@ -55,7 +69,9 @@ public float CalculateCombustionPower(float deltaTime) { - float torque = GetTorqueOutput() * GetActualThrottle(); + float throttle = GetActualThrottle(); + if (_cutoff) throttle = 0; + float torque = GetTorqueOutput() * throttle; return torque * AngularVelocity * deltaTime; } @@ -109,8 +125,9 @@ return 0f; } - public void Update(float deltaTime) + public void Update(float deltaTime, float totalTime) { + UpdateRevLimiter(totalTime); // Combustion adds energy (if throttle > 0) float combustionEnergy = CalculateCombustionPower(deltaTime); diff --git a/Car simulation/EngineSound.cs b/Car simulation/EngineSound.cs index eace81c..71bae3b 100644 --- a/Car simulation/EngineSound.cs +++ b/Car simulation/EngineSound.cs @@ -18,11 +18,11 @@ namespace Car_simulation private bool _isPlaying = false; // Harmonic series - DIRECT RPM TO FREQUENCY - private float[] _harmonicRatios = { 1f, 2f, 4f, 6f }; - private float[] _harmonicAmplitudes = { 1f, 0.3f, 0.1f, 0.05f }; + private float[] _harmonicRatios = { 1f, 2f, 3f, 5f }; + private float[] _harmonicAmplitudes = { 0.2f, 0.5f, 0.35f, 0.2f }; private float[] _harmonicPhases = new float[4]; - // Engine configuration - for direct RPM calculation + // Engine configuration - for directa RPM calculation public int CylinderCount { get; set; } = 4; public float FiringFrequencyMultiplier => CylinderCount / 2f; // 4-stroke engines diff --git a/Car simulation/Program.cs b/Car simulation/Program.cs index 51aaa54..aed3067 100644 --- a/Car simulation/Program.cs +++ b/Car simulation/Program.cs @@ -28,6 +28,7 @@ internal class Program private Clock _clock = new Clock(); private Time _timePerUpdate = Time.FromSeconds(1.0f / 60.0f); // 60 FPS physics private Time _accumulatedTime = Time.Zero; + private float _totalTime = 0.0f; private long _updateCount = 0; private Dictionary _previousKeyStates = new Dictionary(); @@ -75,7 +76,8 @@ internal class Program while (_accumulatedTime >= _timePerUpdate) { ProcessInput(_timePerUpdate.AsSeconds()); - car.Update(_timePerUpdate.AsSeconds()); + _totalTime += _timePerUpdate.AsSeconds(); + car.Update(_timePerUpdate.AsSeconds(), _totalTime); _accumulatedTime -= _timePerUpdate; _updateCount++; } @@ -202,15 +204,15 @@ internal class Program if (line < _displayTexts.Count) _displayTexts[line++].DisplayedString = "ENERGY"; if (line < _displayTexts.Count) _displayTexts[line++].DisplayedString = $" Engine: {car.Engine.FlywheelEnergy,7:F0} J"; if (line < _displayTexts.Count) _displayTexts[line++].DisplayedString = $" Total: {car.WheelSystem.TotalEnergy,7:F0} J"; - if (line < _displayTexts.Count) _displayTexts[line++].DisplayedString = $" Wheel Rotation: {car.WheelSystem.GetRotationalEnergy(),7:F0} J"; - if (line < _displayTexts.Count) _displayTexts[line++].DisplayedString = $" Car Translation: {car.WheelSystem.GetTranslationalEnergy(),7:F0} J"; + if (line < _displayTexts.Count) _displayTexts[line++].DisplayedString = $" Wheel Rotation: {car.WheelSystem.GetRotationalEnergy() / 1000,7:F0} KJ"; + if (line < _displayTexts.Count) _displayTexts[line++].DisplayedString = $" Car Translation: {car.WheelSystem.GetTranslationalEnergy() / 1000,7:F0} KJ"; } private void DrawGauges() { _window.Draw(_tachometerBackground); - float rpmRatio = Math.Clamp(car.Engine.RPM / 8000f, 0f, 1f); + float rpmRatio = Math.Clamp(car.Engine.RPM / 13000f, 0f, 1f); float tachometerAngle = -90 + (270 * rpmRatio); _tachometerNeedle.Rotation = tachometerAngle; _window.Draw(_tachometerNeedle);