super powerful engine

This commit is contained in:
maxwes08
2026-01-13 10:55:18 +01:00
parent 6249499be2
commit c2bd50511e
5 changed files with 39 additions and 20 deletions

View File

@@ -9,7 +9,7 @@ namespace Car_simulation
public float Speed => WheelSystem.CarSpeed; 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 WheelCount = 4;
public int DrivenWheels = 2; 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; Engine.Throttle = ThrottleInput;
Drivetrain.ClutchEngagement = 1f - ClutchInput; Drivetrain.ClutchEngagement = 1f - ClutchInput;
@@ -99,7 +99,7 @@ namespace Car_simulation
Drivetrain.ClutchEngagement = 0f; Drivetrain.ClutchEngagement = 0f;
// Update engine // Update engine
Engine.Update(deltaTime); Engine.Update(deltaTime, totalTime);
// Update drivetrain (transfers energy between engine and wheels+car) // Update drivetrain (transfers energy between engine and wheels+car)
Drivetrain.Update(deltaTime); Drivetrain.Update(deltaTime);

View File

@@ -22,8 +22,8 @@
public float ClutchEngagement { get; set; } = 0f; // 0 = disengaged, 1 = fully engaged public float ClutchEngagement { get; set; } = 0f; // 0 = disengaged, 1 = fully engaged
// Clutch properties // Clutch properties
public float MaxClutchTorque { get; set; } = 450f; public float MaxClutchTorque { get; set; } = 4500f;
public float ClutchStiffness { get; set; } = 20f; // Softer spring public float ClutchStiffness { get; set; } = 50f; // Softer spring
// State // State
public float ClutchTorque { get; private set; } public float ClutchTorque { get; private set; }

View File

@@ -13,20 +13,24 @@
// Physical properties // Physical properties
public float MomentOfInertia { get; set; } = 0.25f; public float MomentOfInertia { get; set; } = 0.25f;
public float IdleRPM { get; set; } = 800f; public float IdleRPM { get; set; } = 800f;
public float RevLimit { get; set; } = 12000;
public float StallSpeed { get; set; } = 200f; public float StallSpeed { get; set; } = 200f;
public float Throttle { get; set; } = 0f; public float Throttle { get; set; } = 0f;
public bool IsRunning => RPM > StallSpeed; public bool IsRunning => RPM > StallSpeed;
private float _cutoffUntil = 0;
private bool _cutoff = false;
// Torque curve // Torque curve
public Dictionary<float, float> TorqueCurve { get; set; } = new() public Dictionary<float, float> TorqueCurve { get; set; } = new()
{ {
{ 0f, 0f }, { 0f, 0f },
{ 800f, 150f }, { 800f, 200f },
{ 2000f, 250 }, { 2000f, 300 },
{ 4500f, 250f }, { 4500f, 300f },
{ 6800f, 200f }, { 6800f, 300 },
{ 7200f, 150 }, { 7200f, 350 },
{ 7500f, 0f }, { 11000f, 600f },
{ 12500, 500f },
}; };
public Engine() public Engine()
@@ -34,6 +38,16 @@
FlywheelEnergy = GetEnergyFromRPM(IdleRPM); FlywheelEnergy = GetEnergyFromRPM(IdleRPM);
} }
public void UpdateRevLimiter(float totalTime)
{
if (RPM > RevLimit)
{
_cutoffUntil = totalTime + 0.01f;
}
_cutoff = (totalTime < _cutoffUntil);
}
public float CalculateFrictionLoss(float deltaTime) public float CalculateFrictionLoss(float deltaTime)
{ {
float frictionTorque; float frictionTorque;
@@ -55,7 +69,9 @@
public float CalculateCombustionPower(float deltaTime) public float CalculateCombustionPower(float deltaTime)
{ {
float torque = GetTorqueOutput() * GetActualThrottle(); float throttle = GetActualThrottle();
if (_cutoff) throttle = 0;
float torque = GetTorqueOutput() * throttle;
return torque * AngularVelocity * deltaTime; return torque * AngularVelocity * deltaTime;
} }
@@ -109,8 +125,9 @@
return 0f; return 0f;
} }
public void Update(float deltaTime) public void Update(float deltaTime, float totalTime)
{ {
UpdateRevLimiter(totalTime);
// Combustion adds energy (if throttle > 0) // Combustion adds energy (if throttle > 0)
float combustionEnergy = CalculateCombustionPower(deltaTime); float combustionEnergy = CalculateCombustionPower(deltaTime);

View File

@@ -18,11 +18,11 @@ namespace Car_simulation
private bool _isPlaying = false; private bool _isPlaying = false;
// Harmonic series - DIRECT RPM TO FREQUENCY // Harmonic series - DIRECT RPM TO FREQUENCY
private float[] _harmonicRatios = { 1f, 2f, 4f, 6f }; private float[] _harmonicRatios = { 1f, 2f, 3f, 5f };
private float[] _harmonicAmplitudes = { 1f, 0.3f, 0.1f, 0.05f }; private float[] _harmonicAmplitudes = { 0.2f, 0.5f, 0.35f, 0.2f };
private float[] _harmonicPhases = new float[4]; 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 int CylinderCount { get; set; } = 4;
public float FiringFrequencyMultiplier => CylinderCount / 2f; // 4-stroke engines public float FiringFrequencyMultiplier => CylinderCount / 2f; // 4-stroke engines

View File

@@ -28,6 +28,7 @@ internal class Program
private Clock _clock = new Clock(); private Clock _clock = new Clock();
private Time _timePerUpdate = Time.FromSeconds(1.0f / 60.0f); // 60 FPS physics private Time _timePerUpdate = Time.FromSeconds(1.0f / 60.0f); // 60 FPS physics
private Time _accumulatedTime = Time.Zero; private Time _accumulatedTime = Time.Zero;
private float _totalTime = 0.0f;
private long _updateCount = 0; private long _updateCount = 0;
private Dictionary<Keyboard.Key, bool> _previousKeyStates = new Dictionary<Keyboard.Key, bool>(); private Dictionary<Keyboard.Key, bool> _previousKeyStates = new Dictionary<Keyboard.Key, bool>();
@@ -75,7 +76,8 @@ internal class Program
while (_accumulatedTime >= _timePerUpdate) while (_accumulatedTime >= _timePerUpdate)
{ {
ProcessInput(_timePerUpdate.AsSeconds()); ProcessInput(_timePerUpdate.AsSeconds());
car.Update(_timePerUpdate.AsSeconds()); _totalTime += _timePerUpdate.AsSeconds();
car.Update(_timePerUpdate.AsSeconds(), _totalTime);
_accumulatedTime -= _timePerUpdate; _accumulatedTime -= _timePerUpdate;
_updateCount++; _updateCount++;
} }
@@ -202,15 +204,15 @@ internal class Program
if (line < _displayTexts.Count) _displayTexts[line++].DisplayedString = "ENERGY"; 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 = $" 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 = $" 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 = $" Wheel Rotation: {car.WheelSystem.GetRotationalEnergy() / 1000,7:F0} KJ";
if (line < _displayTexts.Count) _displayTexts[line++].DisplayedString = $" Car Translation: {car.WheelSystem.GetTranslationalEnergy(),7:F0} J"; if (line < _displayTexts.Count) _displayTexts[line++].DisplayedString = $" Car Translation: {car.WheelSystem.GetTranslationalEnergy() / 1000,7:F0} KJ";
} }
private void DrawGauges() private void DrawGauges()
{ {
_window.Draw(_tachometerBackground); _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); float tachometerAngle = -90 + (270 * rpmRatio);
_tachometerNeedle.Rotation = tachometerAngle; _tachometerNeedle.Rotation = tachometerAngle;
_window.Draw(_tachometerNeedle); _window.Draw(_tachometerNeedle);