In my game, when the user is browsing through the menus I show a fade in effect every time a menu is displayed.
I use the alpha value that goes from 0 to 255. I would like the duration going from 0 to 255 to be the same no matter the current frame rate is.
This is what I’m doing but it’s not working properly.
int AlphaValue = 0;
public void Update(GameTime gameTime)
{
float time = (float)gameTime.ElapsedGameTime.TotalSeconds;
AlphaValueIncrement = 10;
AlphaValue += AlphaValueIncrement;
AlphaValue = (int)(AlphaValue / time);
}
your code is basically dividing your alpha by seconds (which is something like 1/60) so you end up with a pretty big alpha. I guess, what you’d want to do is:
Alpha += Increment * time;
you’d need to max() it of course
FYI:
If you use FixedTimeStep, just “lerp” to the desired alpha (you have to adjust the value, because it depends on the update frequency, which is good enough for fading most of the time) and gives a nice easing.
The other (simple) solution - increment a (float) timer by elapsedseconds, clamp to min/max of your choice and there you go (can be used in both directions and a target value)
I tried with that formula but Alpha doesn’t seem to increase. However, I used your other (simple) solution and it works great, so that’s good enough for me!
You can use this timer class i think it will help.
In this way the fade amount is based on just the time regardless of the frame rate.
// declare it in the game class and set the amount of time in seconds for a fade in to occur.
const float fadeInSeconds = .8f;
Timer timer = new Timer(fadeInSeconds);
// in update
timer.Update(gameTime);
var percent = timer.GetElapsedPercentageOfTimer;
int alpha = (int)(percent * 255f);
// Test it simulate a event keypress mouse click ect,..
if (Keyboard.GetState().IsKeyDown(Keys.T))
timer.ResetElapsedToZero();
// Print it out ect.
Console.WriteLine("% of opacity: "+ percent + " Alpha value: "+ alpha);
here is the class.
/// <summary>
/// Timer class based on seconds.
/// </summary>
public class Timer
{
private float timer = 0f;
private float totalElapsed = 0f;
private float multiplier = 1f;
bool isTriggered = false;
const float pi = 3.141592653f;
public Timer()
{
SetTimer = 1.0f;
IsActivelyTiming = false;
isTriggered = false;
}
public Timer(float seconds)
{
SetTimer = seconds;
IsActivelyTiming = true;
isTriggered = false;
}
public Timer(float seconds, bool startingStateActive)
{
SetTimer = seconds;
IsActivelyTiming = startingStateActive;
isTriggered = false;
}
public bool IsActivelyTiming { get; set; } = false;
public float SetTimer
{
set
{
timer = value;
}
}
public float GetTimer
{
get
{
return timer;
}
}
public float SetTimerAndStart
{
set
{
timer = value;
IsActivelyTiming = true;
isTriggered = false;
}
}
public float AddToTimer
{
set
{
timer += value;
}
}
public float AddToElapsed
{
set
{
totalElapsed += value;
}
}
public float AddToMultiplier
{
set
{
multiplier += value;
}
}
public float Multiplier
{
set
{
multiplier = value;
}
get
{
return multiplier;
}
}
/// <summary>
/// When used as a stop watch.
/// </summary>
public bool IsTimedAmountReached
{
get { return isTriggered; }
}
/// <summary>
/// When used as a stop watch.
/// </summary>
public bool IsTriggered
{
get { return isTriggered; }
}
/// <summary>
/// performs a rotation of time multiplied by 2 pi
/// </summary>
public float GetElapsedTimeAsRadianRotation
{
get { return GetElapsedPercentageOfTimer * 2 * pi; }
}
public float GetElapsedPercentageOfTimer
{
get
{
if (timer > 0f)
return totalElapsed / timer;
else
return 0;
}
}
public float GetElapsedPercentageOfTimerInverted
{
get
{
if (timer > 0f)
return 1f - (totalElapsed / timer);
else
return 0;
}
}
/// <summary>
/// performs a linear oscilation on the given time
/// </summary>
public float GetElapsedPercentageAsOscillation
{
get
{
if (timer > 0f)
{
var half = timer * .5f;
var n = (totalElapsed - half) / half;
if (n < 0f)
n = -n;
return 1f - n;
}
else
return 0;
}
}
public void StartTimer()
{
IsActivelyTiming = true;
}
public void StopTimer()
{
IsActivelyTiming = false;
}
/// <summary>
/// Leaves the timer running, retains the timing amount and restarts the timer at zero.
/// </summary>
public void ResetElapsedToZero()
{
totalElapsed = 0;
isTriggered = false;
IsActivelyTiming = true;
}
/// <summary>
/// Turns off the timer completely.
/// </summary>
public void ClearStopResetTimer()
{
totalElapsed = 0;
isTriggered = false;
multiplier = 1f;
IsActivelyTiming = false;
}
/// <summary>
/// Returns true if the time reaches its timer amount
/// </summary>
public bool Update(GameTime gameTime)
{
return Update((float)gameTime.ElapsedGameTime.TotalSeconds);
}
/// <summary>
/// Returns true if the time reaches its timer amount
/// </summary>
public bool Update(float elapsedTimeInSeconds)
{
totalElapsed += elapsedTimeInSeconds * multiplier;
if (totalElapsed >= timer)
{
isTriggered = true;
totalElapsed = timer;
}
return isTriggered;
}
public void UpdateContinuously(GameTime gameTime)
{
UpdateContinuously((float)(gameTime.ElapsedGameTime.TotalSeconds));
}
/// <summary>
/// Updates continuously typically used for oscillarions or looping algorithms
/// </summary>
public void UpdateContinuously(float elapsedTimeInSeconds)
{
totalElapsed += elapsedTimeInSeconds * multiplier;
if (totalElapsed >= timer)
{
totalElapsed -= timer;
IsActivelyTiming = true;
}
}
}
Your alpha has to be float in order to work, because elapsed seconds is 0,016 at 60FPS - so if you multiply that with an int, it’s always zero - your code doesn’t show this, just be sure to work with floats and not with ints