// Update is called once per frame private void Update(float dt) { // Wheel controls bool isBraking = _input.GetKeyDown((int)SDL.SDL_Keycode.SDLK_DOWN); bool isAccelerating = _input.GetKeyDown((int)SDL.SDL_Keycode.SDLK_UP); foreach (Wheel wheel in _wheels) { // We give priority to braking if (isBraking) { // This function also emit particles Wheel.DynamicsData wheelDynamics = wheel.ApplyNonLinearTorque(_horsePower, _maxSpdBwd, true); if (wheelDynamics.IsInContact) { // If the wheel is in contact, we play the braking sound according to the current work in the wheel if (_soundSource.Sound != _brakeSound || !_soundSource.IsPlaying()) { _soundSource.Play(_brakeSound); } _soundSource.SetFrequency(48000); _soundSource.Gain = wheelDynamics.Resistance * -1; if (_soundSource.Gain > 1) { _soundSource.Gain = 1; } } else { _soundSource.Stop(); } } else if (isAccelerating) { Wheel.DynamicsData wheelDynamics = wheel.ApplyNonLinearTorque(-_horsePower, -_maxSpdFwd); // We set the sound frequency according to the speed and gain according to the work being done _soundSource.SetFrequency((wheelDynamics.AngularVelocity / -40 + 1) * 48000); _soundSource.Gain += 0.03f; if (_soundSource.Gain > 1) { _soundSource.Gain = 1; } _soundSource.Gain += Math.Abs(1 - wheelDynamics.Resistance * 5); if (_soundSource.Sound != _accelSound || !_soundSource.IsPlaying()) { _soundSource.Play(_accelSound); } } else { // If it's not receiving any input, fades out engine sound or stop other sounds if (_soundSource.Sound == _accelSound) { _soundSource.SetFrequency(48000); _soundSource.Gain -= 0.01f; if (_soundSource.Gain < 0.3f) { _soundSource.Gain = 0.3f; } } else { _soundSource.Stop(); } // We emit surface particles anyway wheel.EmitSurfaceParticles(); } } // Roll controls if (_input.GetKeyDown((int)SDL.SDL_Keycode.SDLK_LEFT)) { _rigidBody.ApplyTorque(_rollForce, true); } if (_input.GetKeyDown((int)SDL.SDL_Keycode.SDLK_RIGHT)) { _rigidBody.ApplyTorque(_rollForce * -1, true); } // Debug control for when you rolled over if (_input.GetKeyDown((int)SDL.SDL_Keycode.SDLK_SPACE)) { _rigidBody.SetAngularVelocity(2); } // We apply bit of the vehicle's velocity to the exhaust particles so they look OK Vector2 currentVelocity = _rigidBody.GetLinearVelocity(); _exhaustParticles.Effect.Speed = Math.Abs(100 + currentVelocity.LengthFast * 20); _exhaustParticles.Effect.SpeedVariance = currentVelocity.LengthFast * 10; _exhaustParticles.Effect.Angle = -Node.Rotation2D + (float)(Math.Atan2(currentVelocity.X - 5, -currentVelocity.Y) * (360 / (Math.PI * 2))) - 90; // Suspension sounds foreach (Wheel wheel in _wheels) { if (wheel.CurrentSuspensionCompression() > 0.7f) { if (DateTime.Now - lastSuspensionSound > TimeSpan.FromMilliseconds(500)) { lastSuspensionSound = DateTime.Now; _suspensionSoundSource.Play(_suspensionSounds[new Random().Next(_suspensionSounds.Length)]); } } } }