Floats vs. Ints for position and collision detection

So I’m writing a player class and using floats to store the positon and velocity (Vector2) as well as using it when drawing. When it comes to collision I get the player bounds using this code:
public Rectangle Bounds => new Rectangle((int)_pos.X, (int)_pos.Y, 12, 23); to test it against solid blocks.

The issue comes when I apply gravity to the player and the player moves in <1 increments per frame eg. first frame 0, second frame 0.25, etc. This causes the player to jitter when above a block due to him falling down little by little until the collision code (which uses ints) pushes it back up.

One solution I came across is to use the Bounds I calculated earlier for drawing, instead of using the position directly. However there is another problem (because the problems never stop coming)… Now the jitter occurs behind the scenes causing the ground detection to not work. How can I make the float positioning and int collision system work in harmony??

Now I know this might seem like a lot to take in so I’ve uploaded the pastebin for the player class (~100 lines): Player.cs - Pastebin.com. Thanks for helping.

You could make a new rectangleF struct that uses floats instead of ints.

Collision detection is a very complex topic, even with non rotated rectangles.

2 important things

  1. You need to consider the speed at which things move (too fast and they will move through an object in one frame)
  2. You need to also consider where the intersection occurs. If you simply chose to ignore the frames movement if you intersect with something you could still be 10 units of distance away from the object when you collide (if you where moving 15 units in that frame) varying frame rates will effect this

Normalise your movement between 0 and 1. So 0 is your last position, 1 is your destination.

I suggest first find the first object you collided with. If your moving fast and are worried about jumping over an object in that frame and don’t want to work out the maths to cast an intersecting ray you can always just step through your movement for that frame until you collide.

Then when you know the object you hit, you need to find the normalised movement percentage of when you hit. (Eg 0.55f of your move you will collide) So your move for that frame will be your velocity * 0.55f. If you wish to bounce or slide you know you still have 0.45f left of your velocity vector to change your direction.

Your basic problem is precision, especially because you work in frames and each frame is under 16 ms, so you always work wth fractions.

The regular approach is to have all data in floiting point precision and clamp it to int values for rendering only

So I’ve solved the problem by using a RectangleF struct that uses floats instead of ints and using that to calculate collision. I still use float to draw the player since casting them to ints caused choppy movement.

That seems odd… when you draw, you can only draw to pixel resolutions anyway. When you cast, are you casting right before you render, or are you casting for everything?

Under the hood, even 2d graphics aligned perfectly to pixels are rasterized using orthographic projection matrices in 3d space with outputs defined defined by the -1f…1f range.

Even if you don’t cast, the default SpriteBatch shader sure as heck is. The tricks to keep vertex precision at large distances get annoying to deal with real fast.