Left and right collision not working

For my game the character can land on top of platforms but can’t collide left and right. My if statement for touching
the left of a rectangle doesn’t do anything. Here’s code:

foreach (player player in Players){
foreach (platform platform in Platforms){
if (player.hitbox.isOnLeft(platform.hitbox)){
player.cantmoveright = true;
}
}

the bool cantmoveright works for sure. i even checked in the draw method by drawing string

 (Players[0].hitbox.isOnLeft(Platforms[0].hitbox)).ToString();

and still nothing. false.

here’s the class for the TouchLeftOf bool in it:

static class RectangleHelper
{
    const int penetrationMargin = 5;
public static bool isOnLeft(this Rectangle r1, Rectangle r2)
     {
       return (
        r1.Left >= r2.Right - 1 &&
        r1.Left <= r2.Right + 1 &&
        r1.Bottom >= r2.Top + penetrationMargin &&
        r1.Top <= r2.Bottom - penetrationMargin
        );
}
}

it just doesn’t even respond

This is very vague.

What do you mean exactly? That it is always false?

You have a very small margin there, if the player moves more than 2 pixels per frame he could easily shoot through the obstacles. Another note, this checks if r1 is on the right of r2, rather than on the left.

return (r1.Right <= r2.Right &&
        r1.Right >= r2.Left - 5 &&
        r1.Top <= r2.Bottom - (r2.Width / 4) &&
        r1.Bottom >= r2.Top + (r2.Width / 4));

How about this?

You should use a speed variable and use time to move, or you player will be as fast as the game can go and collisions will fail sometimes. And maybe if the player can go left use a negative speed.
And you should replace your prediction statement with this value to be sure to be ahead of the next move.
As jjagg said, your code is a little confuse.

How can I use time for that?

Position.X += (float)gameTime.ElapsedGameTime.TotalSeconds; ????

And also the problem isn’t that the collision is failing. It’s that it’s missing it. For example, when I run right into the left of a platform, no collision detection. But, if I jump into it a certain way so that the bottom of the player hitbox is between the top and bottom of the platform, then bam, collision detection.

you need to calculate delta time so if your game is updating 60 times a second you know that 1 update is

1 / 60 = .0166f
so your delta time would be

dt = (float)GameTime.ElaspedGameTime.TotalSeconds / .0166f;

then you would do something like

Position.X += Speed * dt;

that way if your game runs slow dt will compensate by been larger and your player will still move at the same speed.

More that likely

1 Like

Exactly :slight_smile: so movement is independant from fps. And collisions should be fixed (hopefully)

I’m lost.

More that likely

So is there any solution to that?

And collisions should be fixed (hopefully)

does that mean it’s a bug in MonoGame?

Does this mean you could accurately portray 1s in game as dt * 60?

ie speed / dt * 60 = velocity per second.

or like position.x += 120 / dt * 60 = 2 pixels per second?

edit: would you have to calculate as float and resolve as int every frame?

dt = gameTime.ElapsedTime.TotalSeconds;

Will give you the time that passed in seconds, so of you have a velocity and every frame do

Position += dt*Velocity;

The unit of that velocity will essentially be pixels/second. If you don’t divide by the time between updates like Mattlekim said, you can think in terms of time rather than number of updates.

You should store floats (or vector2 in this case) and round only when you need to. If you round after every recalculation movement may look a bit jittery at low speeds.