Question

I am trying to rotate a model with inertia damping with the keyboard. The code works great with a fixed time step but it doesn't behave the same with a variable update frequency.

Update method:

protected override void Update(GameTime gameTime)
{
    base.Update(gameTime);

    float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
    const float rotationPerSecond = 0.25f;
    const float decayPerSecond = 0.5f;

    KeyboardState kb = Keyboard.GetState();

    if (kb.IsKeyDown(Keys.Left))
    {
        m_velocity += rotationPerSecond * elapsed;
    }
    else if (kb.IsKeyDown(Keys.Right))
    {
        m_velocity -= rotationPerSecond * elapsed;
    }
    else
    {
        if (Math.Abs(m_velocity) < 0.01f)
        {
            m_velocity = 0;
        }
        else if (m_velocity > 0)
        {
            m_velocity -= decayPerSecond * elapsed;
        }
        else if (m_velocity < 0)
        {
            m_velocity += decayPerSecond * elapsed;
        }
    }

    m_rotationAngle += m_velocity;
}  

Draw method:

Matrix rot = Matrix.CreateWorld(new Vector3(0, 0, 0), Vector3.Forward, Vector3.Up) * 
                         Matrix.CreateRotationY(MathHelper.ToRadians(m_rotationAngle));

I am changing the time step with

IsFixedTimeStep = true;
graphics.SynchronizeWithVerticalRetrace = true;

and

IsFixedTimeStep = false;
graphics.SynchronizeWithVerticalRetrace = false;

Rotation speed and damping is completely different with different update frequencies. Any ideas what i am doing wrong?

Was it helpful?

Solution

You forgot (float)gameTime.ElapsedGameTime.TotalSeconds at m_rotationAngle calculation:

m_rotationAngle += m_velocity * elapsed;

And then increase your speed values:

const float rotationPerSecond = 250.0f;
const float decayPerSecond = 500.0f;

And it will work both for:

//IsFixedTimeStep = true/false;
//graphics.SynchronizeWithVerticalRetrace = true/false;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top