super powerful engine
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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; }
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user