private void PerformMovementInput() { float desiredXVelocity = MovementInput.X * MaxSpeed; float desiredYVelocity = MovementInput.Y * MaxSpeed; var xSign = Math.Sign(desiredXVelocity - XVelocity); XVelocity += xSign * MaxSpeed * TimeManager.SecondDifference / AccelerationTime; if (xSign != Math.Sign(desiredXVelocity - XVelocity)) { XVelocity = desiredXVelocity; } var ySign = Math.Sign(desiredYVelocity - YVelocity); YVelocity += ySign * MaxSpeed * TimeManager.SecondDifference / AccelerationTime; if (ySign != Math.Sign(desiredYVelocity - YVelocity)) { YVelocity = desiredYVelocity; } float currentVelocityLength = Velocity.Length(); if (currentVelocityLength > MaxSpeed) { Velocity.Normalize(); Velocity = Velocity * MaxSpeed; currentVelocityLength = MaxSpeed; } if (desiredYVelocity != 0 || desiredXVelocity != 0) { BubblesInstance.ThrustVector = new Microsoft.Xna.Framework.Vector3(desiredXVelocity, desiredYVelocity, 0); } else if (BubblesInstance.ThrustVector.Length() != 0) { BubblesInstance.ThrustVector = Microsoft.Xna.Framework.Vector3.Zero; } if (desiredXVelocity != 0 || desiredYVelocity != 0) { if (EngineLoop.State != SoundState.Playing) { EngineLoop.Play(); } if (EngineVolume == 0) { this.Tween(nameof(EngineVolume), MaxEngineSfxVolume, EngineFadeTime, InterpolationType.Linear, Easing.In); } } else { if (engineVolume > 0 && TweenerManager.Self.IsObjectReferencedByTweeners(this) == false) { this.Tween(nameof(EngineVolume), 0, EngineFadeTime, InterpolationType.Linear, Easing.In); } } if ((desiredXVelocity == 0 && desiredYVelocity == 0) && Velocity.LengthSquared() > 0) { if (SubLoop.State != SoundState.Playing) { SubLoop.Play(); } SubLoop.Volume = MaxEngineSfxVolume * currentVelocityLength / MaxSpeed; } else { // Calling stop or pause here seems to make the sound "pop" //SubLoop.Stop(); } }