I've read all around the net, watched videos, tried things and in the end I can't make a decent platform collision detection.
I've followed this tutorial.
It didn't work out at 100%. My object stops above ground and can't hit the ground. Anyway, I think the guy got fed up with me asking questions. And his way seems too complicated. In short it's about constant calculations how far are you from a wall/ground and how much steps can you make("step" is also defined), how much DID you make, etc. Too complicated if you ask me. So let's forget about that.
I began anew on my own. Here's what I got:
private void ApplyCollision()
{
if (PlayerIsOnPlatform())
{
this.Position -= new Vector2(0, 5); // Holds Player on platform.
}
}
private bool PlayerIsOnPlatform()
{
int playerBottom = this.Bounds.Bottom;
int platformTop = Platform.CurrentPlatform.Bounds.Top;
bool playerIntersectsPlatform =
this.Bounds.Intersects(Platform.CurrentPlatform.Bounds);
if ((playerBottom >= platformTop) && (playerIntersectsPlatform))
{
return true;
}
return false;
}
And gravity and friction:
private void Friction()
{
Movement -= Movement * new Vector2(.1f, .1f);
}
private void Gravity()
{
Movement += Vector2.UnitY * .5f;
}
Like this, the player bounces a bit and stays about a pixel above ground. And the gravity is always trying to pin the object down even when I somehow manage to land on the platform.
=======
EDIT:
The player stops at the platform top correctly. But now I have another problem:
private void ApplyCollision()
{
// Object is above
if (playerBottom > platformTop && playerBottom < platformBottom && playerIntersectsPlatform)
{
this.Position = new Vector2(currentPlayerPosX, platformTop - playerHeight);
}
// Object below
else if (playerTop < platformBottom && playerTop > platformTop && playerIntersectsPlatform)
{
this.Position = new Vector2(currentPlayerPosX, platformBottom);
}
// Object to the left !! Conflicts with Vertical detection
if (playerLeft < platformLeft && playerRight > platformLeft && playerIntersectsPlatform &&
this.Bounds.Center.X <= platformLeft) // Not perfect
{
this.Position = new Vector2(platformLeft - playerWidth, currentPlayerPosY);
}
// Object to the right !! Conflicts with Vertical detection
else if (playerRight > platformRight && playerLeft < platformRight && playerIntersectsPlatform)
{
this.Position = new Vector2(platformRight, currentPlayerPosY);
}
}
This methods works. It's shorter, better and doesn't need my initial boolean methods I had for top, bottom, sides check. But the Left and Right checks still need work. When the player is near the Platform border, he gets pushed/teleported off the edge. The Left check actually allows half of the Player to go off the edge without falling instantly - thanks to this.Bounds.Center.X <= platformLeft
. Not perfect.
Here's a picture to illustrate the problem:
I know why this is happening. It's due to the conditions in the if statements. I guess this calls for collision depth calculation. I find Jon's implementation kinda confusing. And I wonder if that's the only solution. I tried adding another condition. Pseudocode for left check: if 1/4 of Player.Width <= platformLeft >THEN> this.Position = new Vector2(platformLeft - playerWidth, currentPlayerPosY);
But due to the friction and speed I have, it doesn't work.
new Vector2(0, 5)
supposed to be ? If player intersects with the platform, then move him directly on the top edge of the platform. So in pseudocode:Player.Bounds.Bottom = Platform.Bounds.Top
\$\endgroup\$this.Position = new Vector2(currentPosX, platformTop);
locks the player in the middle of the platform:screen I think this.Position means that the position coordinates start from the top left corner. But then again, shouldn't the Player top corner overlap the top platform border and not be below it? \$\endgroup\$this.Position = new Vector2(currentPlayerPosX, platformPosY - playerHeight);
This is amazing! Thank you so much!!! \$\endgroup\$