0
votes

I'm working on a platformer, I have a 32x32 sprite, and 32x32 tiles. I also use a tile engine, that generates the map with help of an array. I use a RectangleHelper.cs to fix the collision with the tiles and the player, and so far, it can collide with the top of the tile, and also the left side of the tile.

enter image description here

In picture one, I'm showing that the "On Top Of" collision works just fine. No errors or anything.

In picture 2, I'm showing the "Collision Left Of", and that also works great.

But in picture 3, you can see that the character is floating. It's because the collision rectangle somehow stretches out a a couple of pixels, and thats one of the problems, that I cant seem to find any answers on.

In picture 4, I tried to collide from the right of the stretched collision rectangle, and I ended up hopping back into the wall for like 1 - 2 frames, so I couldn't manage to take a screenshot on it, but thats also one of the problems.

Heres my RectangleHelper.cs, it's from "oyyou9"'s tutorial on youtube for a tile collision engine, and for him, everything works just fine.

Also, if I collide with the bottom of a block, my character disappears.

RectangleHelper.cs

public static class RectangleHelper
{

    public static bool TouchTopOf(this Rectangle r1, Rectangle r2)
    {
        return (r1.Bottom >= r2.Top - 1 &&
                r1.Bottom <= r2.Top + (r2.Height / 2) &&
                r1.Right >= r2.Left + (r2.Width / 5) &&
                r1.Left <= r2.Right - (r2.Width / 5));
    }

    public static bool TouchBottomOf(this Rectangle r1, Rectangle r2)
    {
        return (r1.Top <= r2.Bottom + (r2.Height / 5) &&
                r1.Top >= r2.Bottom - 1 &&
                r1.Right >= r2.Left + (r2.Width / 5) &&
                r1.Left <= r2.Right - (r2.Width / 5));
    }

    public static bool TouchLeftOf(this Rectangle r1, Rectangle r2)
    {
        return (r1.Right <= r2.Right &&
                r1.Right >= r2.Left  - 5&&
                r1.Top <= r2.Bottom - (r2.Width / 4) &&
                r1.Bottom >= r2.Top + (r2.Width / 4));  
    }

    public static bool TouchRightOf(this Rectangle r1, Rectangle r2)
    {
        return (r1.Left >= r2.Left &&
                r1.Left <= r2.Right &&
                r1.Top <= r2.Bottom - (r2.Width / 4) &&
                r1.Bottom >= r2.Top + (r2.Width / 4));
    }
}

As you can see here, there's lots of random values, and in the video, he didn't really said what they was good for, only that I might have to adjust it to fit my game.

And the collision method in my player class:

public void Collision(Rectangle newRectangle, int xOffset, int yOffset)
    {
        if (rectangle.TouchTopOf(newRectangle))
        {
            rectangle.Y = newRectangle.Y - rectangle.Height;
            velocity.Y = 0f;
            hasJumped = false;
        }
        if (rectangle.TouchLeftOf(newRectangle))
        {
            position.X = newRectangle.X - rectangle.Width * 2;
        }
        if (rectangle.TouchRightOf(newRectangle))
        {
            position.X = newRectangle.X + newRectangle.Width +1;
        }
        if (rectangle.TouchBottomOf(newRectangle))
        {
            velocity.Y = 1f;
        }
    }

Which uses the RectangleHelper.cs to fix the collision.

3
Avoid copying all of your code in a question, nobody will read it.pinckerman
Oh, ok, i just thought that almost every class have a connection to eachother, but yeah, ill delete some.Uffe Puffe
in this line of code in the TouchLeftOf void, return (r1.Right <= r2.Right && r1.Right >= r2.Left - 5 && r1.Top <= r2.Bottom - (r2.Width / 4) && r1.Bottom >= r2.Top + (r2.Width / 4)); why do you have the -5 in the second condition? Wouldn't that be causing your character to stop a little before he actually makes it to the tile? And also what's the addition/subtraction (+- (r2.Width / 4)) accomplishing in the 3rd and 4th conditions?davidsbro
I'm not sure really, as i said, i followed a video tutorial, and he said that i don't have to use thoose exact numbers, so i tried diffrent numbers and combinations, but got no diffrence actually.. Can this have something to do with that in the video he does this for the movement: velocity.X -= (float)gameTime.ElapsedGameTime.TotalMilliSeconds / 3;, but i use my position variable for movement, cus the velocity variable didn't work, only for the gravity/falling part :/ I did position += velocity, but it didn't make any diffrence :/ Is there any other ways of doing this? Any ideas?? Thanks!Uffe Puffe
This isn't the place for that, you need to debug it and narrow it down into a question without a ton of code (or a project for that matter). Though I might post my collision code tomorrow if I am not busy. This code you found seems a bit weird, with all these unknown and random values. Also, make sure you are always using elapsed time in your movement calculations.Cyral

3 Answers

0
votes

I'm not sure what all those random values are doing in your collision checking code, so I think this might fix your problem:

    public static bool TouchTopOf(this Rectangle r1, Rectangle r2)
    {
        return (r1.Bottom >= r2.Top - 1 &&
                r1.Bottom <= r2.Top + (r2.Height / 2) &&
                r1.Right >= r2.Left &&
                r1.Left <= r2.Right);
    }

    public static bool TouchBottomOf(this Rectangle r1, Rectangle r2)
    {
        return (r1.Top <= r2.Bottom + (r2.Height / 2) &&
                r1.Top >= r2.Bottom - 1 &&
                r1.Right >= r2.Left  &&
                r1.Left <= r2.Right );
    }

    public static bool TouchLeftOf(this Rectangle r1, Rectangle r2)
    {
        return (r1.Right <= r2.Right &&
                r1.Right >= r2.Left &&
                r1.Top <= r2.Bottom &&
                r1.Bottom >= r2.Top);
    }

    public static bool TouchRightOf(this Rectangle r1, Rectangle r2)
    {
        return (r1.Left >= r2.Left &&
                r1.Left <= r2.Right &&
                r1.Top <= r2.Bottom &&
                r1.Bottom >= r2.Top);
    }

And change this:

    if (rectangle.TouchLeftOf(newRectangle))
    {
        position.X = newRectangle.X - rectangle.Width * 2;
    }

To this:

    if (rectangle.TouchLeftOf(newRectangle))
    {
        position.X = newRectangle.X - 1;
    }

HTH. It worked for me for the most part. Hopefully this will get rid of some of your major bugs, but I just want to point out that the best way you'll learn is by debugging this yourself. One way you could start is by setting up everything the way you did in picture 3, and then put a breakpoint in your rectangle.TouchTopOf() condition and see if that's returning true, and if so, why it's returning true when obviously it shouldn't be.

0
votes
public static bool TouchLeftOf(this Rectangle r1, Rectangle r2)
{
    return (r1.Left <= r2.Right &&
            r1.Right >= r2.Right - 5 &&
            r1.Top <= r2.Bottom - (r2.Width / 4) &&
            r1.Bottom >= r2.Top + (r2.Width / 4));
}
0
votes
public static bool TouchRightOf(this Rectangle r1, Rectangle r2)
{
    return (r1.Right >= r2.Left &&
            r1.Left <= r2.Left - 5 &&
            r1.Top <= r2.Bottom - (r2.Width / 4) &&
            r1.Bottom >= r2.Top + (r2.Width / 4));
}