2
\$\begingroup\$

I have just started looking into XNA for WP7 - and I am definitely the sort of person who likes to find answers to my questions without begging for help!

I searched here to find an answer but I found it hard to word my question, so apologies if it has been asked.

Basically I have a sprite, which I am moving to and from set locations on the screen. I have defined these locations and set up the methods to detect the input on the screen (I only want to be able to swipe left and right to select the location).

The sprite moves to the correct location when I swipe, but sometimes when it arrives at its location, it jitters very quickly backwards and forwards. My guess is that because of the maths used to calculate the vectors, it never actually hits the exact location, so keeps moving.

My theory was to set up some sort of boundary, where if the sprite was detected within x amount of pixels of the actual location, the sprite is snapped to the correct location. Would this be a good way of doing something? I imagine it isn't the most elegant solution as it will have that snapping motion towards the end, or am I just over-exaggerating what that will look like in my mind?

can anyone suggest a way of getting around this jumpy sprite? Code that i think is relevant below :)

Initialising:

player = new Player();
playerMoveSpeed = 12.0f;
player.Position = positionsSet.getLocation(1);

I defined my 4 locations like this:

Vector2 position1 = new Vector2(10.0f, 30.0f);
Vector2 position2 = new Vector2(210.0f, 30.0f);

My calculating the movement happens like this and is where I believe the stuttering to occur:

Vector2 direction = goTo - player.Position;
direction.Normalize();
player.Position = player.Position + direction * playerMoveSpeed;

Oh, and to get there I call this method (the gametime parameter is something I was trying, its not actually being used at the moment :) ) :

if(player.Position != goTo)
moveToLocation(goTo,gameTime);

Any advice would be massively appreciated guys and girls, I think I am getting there, but it is just annoying me now :)

\$\endgroup\$

2 Answers 2

3
\$\begingroup\$

Vector2 uses floating point numbers, so when you calculate the difference between where you want to go and where you are (goTo - player.Position) it will almost never be exactly zero. This leads to some jitter, which is likely worse at some locations.

If you can't switch to integer-based positions (i.e. Point) you will end up having to cap the movement as you have found out. One way of doing this is to compare length of the direction vector before you normalize it and if it is under a set value simply go to the target position. If your margin of error before snapping is small enough you will not notice the snapping at all.

\$\endgroup\$
4
  • \$\begingroup\$ That is a good idea, thank you, despite only being a very simple test / concept, for some reason I did not think about using Points, I guess I got so caught up in the world of Vectors after moving to XNA! \$\endgroup\$
    – Graham M
    Dec 8, 2011 at 16:21
  • \$\begingroup\$ Using integers can also lead to snapping, so if you can have sub-pixel movement per update its a good idea to still use Vector2 to track progress and simply cap to integer positions when rendering. \$\endgroup\$ Dec 8, 2011 at 16:35
  • \$\begingroup\$ I would like to point out that the observed jitter is not caused by floating point precision issues. \$\endgroup\$ Dec 8, 2011 at 17:05
  • \$\begingroup\$ Also, switching to integer-based positions will not solve the problem either. \$\endgroup\$ Dec 8, 2011 at 18:00
4
\$\begingroup\$

The following code has the problem that you could go far beyond goTo:

Vector2 direction = goTo - player.Position;
direction.Normalize();
player.Position = player.Position + direction * playerMoveSpeed;

You need to stop moving when you reach your destination. I suggest rewriting it this way:

Vector2 direction = goTo - player.Position;
if (playerMoveSpeed > direction.Length())
{
    player.Position = goTo;
}
else
{
    direction.Normalize();
    player.Position = player.Position + direction * playerMoveSpeed;
}

Also, you will soon find out that your game is not framerate-independent. This is already obvious because you are adding a speed to a position, which is inconsistent: somewehere you will need to multiply that speed by a duration. See this thread on MSDN which is very closely related to your current code.

\$\endgroup\$
6
  • \$\begingroup\$ Thank you for your input! The framerate issue is something which I will definitely take into consideration. I did have it stopping when it reached its destination, but because of the floating point maths behind it all, it was only occasionally "spot on". I will look into the length of the vector as some side research, but as my project is very simple I might try the method from dadoo about using non-floating point numbers to start with! Thank you for your help! \$\endgroup\$
    – Graham M
    Dec 8, 2011 at 16:26
  • \$\begingroup\$ I am afraid using integer numbers will not work. You will not get sufficient precision for diagonal movements. Also, I believe you did not understand the problem exactly: dadoo's solution in the second paragraph is correct, but his explanation in the first paragraph is just plain wrong. The jitter is absolutely not caused by floating point precision issues. The jitter would be smaller that a billionth of a pixel. The problem, as I said, is not that you never reach goTo, it's that you go past goTo. \$\endgroup\$ Dec 8, 2011 at 16:58
  • \$\begingroup\$ I never said it was due to floating point precision issues, I said the difference between the goTo point and the current point will never be zero. So you will go past the target point, then back past it in the other direction over and over until you happen to get close enough that the jitter is not visible. How long this takes depends on a bunch of factors, not limited to the speed of the moving object, the framerate, etc. \$\endgroup\$ Dec 8, 2011 at 18:15
  • \$\begingroup\$ Also, as pointed out above, if you track movement using floating point numbers and render to integer pixel positions the jitter will fix itself in most cases. You may have more jumpiness for very slow moving objects, but your other option is to render at sub-pixel locations which has its own set of issues (blurrines, etc) \$\endgroup\$ Dec 8, 2011 at 18:18
  • 1
    \$\begingroup\$ @dadooGames: No it will not fix itself. And you will not have more jumpiness for very slow moving objects, but instead for very fast moving objects. The jitter is not caused by a float-versus-integer issue, it is caused by the failure to clamp the object displacement. Again, your solution does work, but your explanations are terrible and misleading, and this last comment of yours is an indication that you still did not understand where the jitter comes from. \$\endgroup\$ Dec 8, 2011 at 18:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .