2

I'm running into an issue while using Mathhelper.Clamp in a game I'm working on. Here's a snippet of the code that's causing me problems:

if (background.position.Y == 0) 
{
    player.position.Y = MathHelper.Clamp(player.position.Y, 0, viewport.Height / 2);
}
if (Math.Abs(background.position.Y) == background.sprite.Height - viewport.Height / 2)
{
    player.position.Y = MathHelper.Clamp(player.position.Y, viewport.Height / 2, viewport.Height - player.sprite.Height);
}
if (player.position.Y == viewport.Height / 2) 
{
    background.position.Y = MathHelper.Clamp(background.position.Y, -(background.sprite.Height - viewport.Height / 2), 0);
}

Essentially, what I'm hoping to accomplish is (starting at x,0) let the player sprite move down until it reaches the middle of the screen, then the background will move instead, until it reaches the bottom of the background minus half the height of the screen, then the player sprite will move again until it reaches the bottom of the screen. (I have code to make this happen) - To me, this seems like pretty typical camera functionality for a 2D sidescroller.

However, the problem I'm having is that the positions aren't clamping exactly at the numbers they should be, which means that the code that relies on them being so specifically placed is breaking as well. To be more specific, it looks like one extra frame worth of movement is being allowed beyond the clamp point.

Can anyone tell me if there's a reason why this shouldn't work, or what I can do to make it work? Thanks in advance!

Amro
  • 123,847
  • 25
  • 243
  • 454
Andrux51
  • 43
  • 5

2 Answers2

4

To compare floating point numbers, you should never use ==, as that's almost always wrong. Since floating point numbers have only a limited precision, you should always look if the difference between them is smaller than a given epsilon.

Like this:

// Difference less than one tenthousandth should be considered equal
private const float Epsilon = 0.0001;

public static bool FloatEquals(float f1, float f2)
{
    return Math.Abs(f1 - f2) < Epsilon;
}
Nuffin
  • 3,882
  • 18
  • 34
  • Exactly, a function like 2f/10f might not equal to 0.2f, as because of floating point accuracy it can result to 0.19999998~, unfortunately it's quite difficult to notice, as the debugger tries to convert these to readable formats when you are watching it. Strange with c# having so many warnings about potential programming mistakes, this one is still valid. – Marking Jan 31 '12 at 12:56
  • Thanks for the insight, I never realized floats are so inaccurate. I think I might just revamp the code and use ints instead. I don't need fractions in this case, but it's definitely something to keep in mind for times when I do. – Andrux51 Jan 31 '12 at 21:18
0

I realized what I did wrong that let the player position move outside of the bounds of my clamp...I put the clamp code before the movement code. Rearranging them cleared that right up!

Andrux51
  • 43
  • 5