using Car_simulation; using SFML.Window; using SFML.Graphics; using SFML.System; using System.Diagnostics; internal class Program { Car car = new Car(); private bool _isRunning = true; private RenderWindow _window; // Timing for physics private Clock _clock = new Clock(); private Time _timePerUpdate = Time.FromSeconds(1.0f / 60.0f); // 60 FPS physics private Time _accumulatedTime = Time.Zero; private long _updateCount = 0; private Dictionary _previousKeyStates = new Dictionary(); private Dictionary _currentKeyStates = new Dictionary(); private static void Main(string[] args) { Program program = new Program(); program.Run(); } private void Run() { _window = new RenderWindow(new VideoMode(800, 600), "Car Simulation", Styles.Default); _window.SetVisible(true); _window.SetFramerateLimit(60); _window.SetKeyRepeatEnabled(false); _window.Closed += (sender, e) => _isRunning = false; _window.KeyPressed += OnKeyPressed; _window.KeyReleased += OnKeyReleased; InitializeTrackedKeys(); _clock.Restart(); while (_isRunning && _window.IsOpen) { _window.DispatchEvents(); Time elapsed = _clock.Restart(); _accumulatedTime += elapsed; while (_accumulatedTime >= _timePerUpdate) { ProcessInput(_timePerUpdate.AsSeconds()); car.Update(_timePerUpdate.AsSeconds()); _accumulatedTime -= _timePerUpdate; _updateCount++; if (_accumulatedTime >= Time.FromSeconds(0.2f)) { _accumulatedTime = _timePerUpdate; } } UpdateDisplay(); UpdatePreviousKeyStates(); } _window.Close(); Console.WriteLine($"\nSimulation stopped after {_updateCount} updates"); } private void InitializeTrackedKeys() { // Initialize all keys we care about var keysToTrack = new Keyboard.Key[] { Keyboard.Key.W, Keyboard.Key.Up, Keyboard.Key.Down, Keyboard.Key.B, Keyboard.Key.Space, Keyboard.Key.Left, Keyboard.Key.Right, Keyboard.Key.Escape }; foreach (var key in keysToTrack) { _currentKeyStates[key] = false; _previousKeyStates[key] = false; } } private void OnKeyPressed(object sender, KeyEventArgs e) { var key = e.Code; // Update current state if (_currentKeyStates.ContainsKey(key)) { _currentKeyStates[key] = true; } } private void OnKeyReleased(object sender, KeyEventArgs e) { var key = e.Code; // Update current state if (_currentKeyStates.ContainsKey(key)) { _currentKeyStates[key] = false; } } private void ProcessInput(float deltaTime) { // quit if (IsKeyDown(Keyboard.Key.Escape)) { _isRunning = false; return; } // force clutch car.ForceClutch = (IsKeyDown(Keyboard.Key.Space)); // throttle if (IsKeyDown(Keyboard.Key.W)) { car.ThrottleInput = Math.Min(car.ThrottleInput + 2f * deltaTime, 1.0f); } else { car.ThrottleInput = Math.Max(car.ThrottleInput - 10f * deltaTime, 0f); } // brake if (IsKeyDown(Keyboard.Key.B)) { car.BrakeInput = Math.Min(car.BrakeInput + 1f * deltaTime, 1.0f); } else { car.BrakeInput = Math.Max(car.BrakeInput - 4f * deltaTime, 0f); } // clutch if (IsKeyDown(Keyboard.Key.Up)) { car.ClutchInput = Math.Min(car.ClutchInput + 0.1f * deltaTime, 1.0f); } else if (IsKeyDown(Keyboard.Key.Down)) { car.ClutchInput = Math.Max(car.ClutchInput - 0.1f * deltaTime, 0f); } // clutch if (IsKeyDown(Keyboard.Key.Up)) { car.ClutchInput = Math.Min(car.ClutchInput + 1f * deltaTime, 1.0f); } else if (IsKeyDown(Keyboard.Key.Down)) { car.ClutchInput = Math.Max(car.ClutchInput - 1f * deltaTime, 0f); } // gear if (WasKeyPressed(Keyboard.Key.Left)) { car.Drivetrain.GearDown(); } else if (WasKeyPressed(Keyboard.Key.Right)) { car.Drivetrain.GearUp(); } } private void UpdatePreviousKeyStates() { var keys = new List(_currentKeyStates.Keys); foreach (var key in keys) { _previousKeyStates[key] = _currentKeyStates[key]; } } private bool IsKeyDown(Keyboard.Key key) { return _currentKeyStates.ContainsKey(key) && _currentKeyStates[key]; } private bool WasKeyPressed(Keyboard.Key key) { return IsKeyDown(key) && (!_previousKeyStates.ContainsKey(key) || !_previousKeyStates[key]); } private void UpdateDisplay() { _window.Clear(Color.Black); // Render car or simulation visualization here // For example, if car has Draw() method: // car.Draw(_window); car.DisplayUpdate(); // If this updates console display _window.Display(); } }