So I am a little confused with my code, I have got left and right collision to work but when it comes to colliding with the top and bottom, the player is thrown to the side of the enemy instead of being pushed back (please see the gif). Any help would be greatly appreciated.
Here is the code that I am working with currently:
A wild guess: If it doesn't work on the Y-Axis but does work on the X-Axis, why do you believe that the mistake happens in the collision detection code rather than SetPosition?
Also, you shouldn't use magic numbers (like 0.1f) and why are you calling GetPosition when you have a rect already acquired on the top of the function?
Elit3d said: but when it comes to colliding with the top and bottom, the player is thrown to the side of the enemy instead of being pushed back
It's because your code applies position correction in fixed order. If there is a vertical collision, there is a horizontal collision too, so the horizontal collision is resolved first and after that there is no more vertical collision.
A better way would be to calculate overlap and it's center, then displacement directions from object center to overlap center (blue lines). Then you could store a mass for each object, or you calculate area of the boxes and use that for mass. Use the masses to decide which object should move more. E.g. if red had mass of 2 and green had mass of 1, the red would resolve 1/(2+1) = 33% of the collision, the green would resolve 2/(2+1) = 67 %. (while drawing i assumed both have the same mass) Then you displace them along their blue lines so they touch but don't overlap.
That's just a proposal i came up with right now. It's not physical as it does not cause the objects to rotate, but likely you don't want rotations.
Another way, simpler and maybe more like what you want:
If the absolute horizontal difference between the centers is smaller than the absolute vertical difference, use horizontal separation, otherwise vertical.
Elit3d said: but when it comes to colliding with the top and bottom, the player is thrown to the side of the enemy instead of being pushed back
It's because your code applies position correction in fixed order. If there is a vertical collision, there is a horizontal collision too, so the horizontal collision is resolved first and after that there is no more vertical collision.
A better way would be to calculate overlap and it's center, then displacement directions from object center to overlap center (blue lines). Then you could store a mass for each object, or you calculate area of the boxes and use that for mass. Use the masses to decide which object should move more. E.g. if red had mass of 2 and green had mass of 1, the red would resolve 1/(2+1) = 33% of the collision, the green would resolve 2/(2+1) = 67 %. (while drawing i assumed both have the same mass) Then you displace them along their blue lines so they touch but don't overlap.
That's just a proposal i came up with right now. It's not physical as it does not cause the objects to rotate, but likely you don't want rotations.
I don't really like to ask this, but could you give me a brief example of this please?
I tried to get the best of both worlds. Seems to work fairly well, but did not do much testing.
In case the contact is close to the corner, it does a diagonal resolve:
In case the whole height of the overlap fits into one box, it does strict horizontal resolve (same for the vertical case):
Otherwise some diagonal resolve fades in:
Feels pretty good. I would expect this behavior from something like auto positioning windows in a GUI. And i hope it also works for rotation less game physics. But this depends. You can turn off the diagonal stuff with preventDiscontinuousSolution = 0. Advantage of the diagonal stuff is: As objects move smoothly, solution changes smoothly as well and there is no discontinuity from switching between horizontal and vertical resolve, which could cause issues. To make one object static, use masses 0 and 1.
I guess I have a question in terms of 2D programming but I kind of anticipate the answer already… Is it better to handle collision from the center of the sprite collision or from the edges of the sprite or the points/corners of the sprite?
The edges. I guarantee a good collision detection. I have an article on my site explaining the whole process and why it is better. The reason is that you can detect faces and know which one was it, for example, if you want some faces of the sprite to react differently to collisions.
The edges. I guarantee a good collision detection. I have an article on my site explaining the whole process and why it is better. The reason is that you can detect faces and know which one was it, for example, if you want some faces of the sprite to react differently to collisions.