Mathhelper.Clamp not exact?

1.2k views Asked by At

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!

2

There are 2 answers

0
Andrux51 On

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!

2
Nuffin On

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;
}