Saturday, January 16, 2016

Problems using easing equations in C# XNA


I'm having some trouble using the easing equations suggested by Robert Penner for ActionScript (http://www.robertpenner.com/easing/, and a Flash demo here) in my C# XNA game. Firstly, what is the definition of the following variables passed in as arguments to each equation?


float t, float b, float c, float d

I'm currently calculating the new X position of a sprite in the Update() loop, however even for the linear tween equation I'm getting some odd results. I'm using the following values:


float t = gameTime.TotalGameTime.TotalMilliseconds;
float d = 8000f;
float b = x.Position.X;

float c = (ScreenManager.Game.GraphicsDevice.Viewport.Width >> 1) - (x.Position.X + x.frameSize.X / 2);

And this equation for linear easing:


 float val = c*t/d + b;

Answer




Firstly, what is the definition of the following variables passed in as arguments to each equation?



The answer was in the link you provided:




  • t = current time (starting from 0 and increasing up to the chosen duration)

  • d = duration (i.e. total time of the animation)

  • b = initial value

  • c = change in value (i.e. how much the value should change, or the difference between the final value and the initial value)


Now for your troubles. Let's take a look at the values you chose for t and d:


float t = gameTime.TotalGameTime.TotalMilliseconds;
float d = 8000f;

I'm guessing you want your interpolation to take 8 seconds to complete, i.e. 8000 miliseconds. In that case the value of t should be starting a 0 on the first frame of the interpolation, and increment a little each frame until it reaches 8000, at which point you should stop updating because the interpolation is complete.



The problem is that you're passing it the value of gameTime.TotalGameTime which is the time that has passed since the game began, and you're supposed to pass it the time that has passed since the animation has begun. Here's the proper solution. First:


// Once at the start of the animation
// Note: I'll also use seconds instead of miliseconds
float t = 0f;
float d = 8f;
bool animating = true;

And then:


// Then once for each frame while the animation is active (i.e. in Update)
if(animating)

{
t += gameTime.ElapsedGameTime.TotalSeconds;

// Don't let time exceed the duration
t = MathHelper.Min(t, d);

// Calculate your "val" here
float val = b + t/d * c;

// Stop animating if we've reached the end

if(t >= d)
animating = false;
}

As for your other values, the value of c looks really cryptic and I'm not really sure what you're trying to do. But basically in this given context, c should be the amount of units you want your character to move.


Finally, unless you're trying to do some really fancy easing, I would just use one of the XNA's built in methods for this:



No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...