Monogame - how to make a smooth color transition with Color.Lerp()?

I would like to know how to dynamically change a color. My code:

Color myColor;
Color startColor = new Color(255, 255, 255);
Color finalColor = new Color(231, 214, 90);
myColor = Color.Lerp(startColor, finalColor, 0.5f);

spriteBatch.Draw(myTexture, Vector2.Zero, myColor);


But the color does not change, in fact I get something similar to the finalColor, that's perhaps because I need to decrement the RGB values of startColor and check if they match finalColor? Help would be much appreciated.

If you look at the Color.Lerp documentation you'll notice that the third parameter is the amount.

public static Color Lerp(Color value1, Color value2, float amount)


amount - A value between 0 and 1.0 indicating the weight of value2.

What this means is that to get the color to change you'll need to change the amount over time between values of 0.0 and 1.0. To do this, create a member variable in your class and change it in the Update method.

 private float _colorAmount = 0.0f;

protected override void Update(GameTime gameTime)
{
var deltaSeconds = (float)gameTime.ElapsedGameTime.TotalSeconds;

_colorAmount += deltaTime;

if(_colorAmount > 1.0f)
_colorAmount = 0.0f;

// rest of update method...
}

protected override void Draw(GameTime gameTime)
{
// start of draw method..

var startColor = new Color(255, 255, 255);
var finalColor = new Color(231, 214, 90);
var myColor = Color.Lerp(startColor, finalColor, _colorAmount);

spriteBatch.Draw(myTexture, Vector2.Zero, myColor);

// rest of draw method...
}


Obviously the actual logic you use will differ from the example here, but this should give you enough to get started.

• I can't see why this isn't directly useable but I'd wrap _colorAmount, rather than truncate it. Consider adding, as an example, running _colorAmount through a trig function to get a nice repeating back and forth between -1:1, scaled to 0:1. – Jon Mar 15 '16 at 1:13
• Maybe show how actually uncomplicated it is too: Color Lerp(Color c0, Color c1, float t) { return (1-t)*c0 + t*c1; } – Jon Mar 15 '16 at 1:15
• @Jon I realize my example won't produce the nicest animation but I think it's better to keep the example as simple as possible without complicating it with extra information. There's loads of different ways to interpolate between 0 and 1 once you understand the basics. – craftworkgames Mar 15 '16 at 1:28
• @craftworkgames Oh now I see. I read those docs but I hadn't drank my coffee yet so I couldn't figure it out. Thanks for the help! – PowerUser Mar 15 '16 at 12:22
• You're welcome. Animation code is fun to write. – craftworkgames Mar 15 '16 at 12:39

I made this general class to help with any kinda lerping transitions. Thought maybe someone could use it. Memory.gameTime.ElapsedGameTime.TotalMilliseconds is a public static variable that my project uses to track the game time you might need to change that for your project.

    public class Slide<T>
{
#region Fields

private double _currentMS;
private T _end;
private Func<T, T, float, T> _function;
private T _start;
private double _totalMS;

#endregion Fields

#region Constructors

public Slide(T start, T end, double totalMS, Func<T, T, float, T> function)
{
_start = start;
_end = end;
_totalMS = totalMS;
_function = function;
}

#endregion Constructors

#region Properties

public double CurrentMS => _currentMS;
public bool Done => _currentMS >= _totalMS;

public T End { get => _end; set => _end = value; }
public Func<T, T, float, T> Function { get => _function; set => _function = value; }
public T Start { get => _start; set => _start = value; }
public double TotalMS { get => _totalMS; set => _totalMS = value; }

#endregion Properties

#region Methods

public void Restart() => _currentMS = 0d;

public void Reverse()
{
T tmp = _start; _start = _end; _end = tmp;
}

public float UpdatePercent()
{
if (!Done)
{
_currentMS += Memory.gameTime.ElapsedGameTime.TotalMilliseconds;
return (float)(Done ? 1f : _currentMS / _totalMS);
}
else
return 1f;
}

public T Update()
{
float percent;
if (_function!=null && (percent = UpdatePercent())!=1f)
return _function(_start, _end, percent);
return _end;
}

#endregion Methods
}


For this question the you can use.

Slide<Color> ColorSlider = new Slide<Color>(new Color(255, 255, 255),
new Color(231, 214, 90), 2000d, Color.Lerp);
Color cval = ColorSlider.Update();