Uffe Puffe
Uffe Puffe

Reputation: 105

Platformer tile collision problems

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.

Upvotes: 0

Views: 2362

Answers (3)

Ali Al Lafta
Ali Al Lafta

Reputation: 1

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));
}

Upvotes: 0

Ali Al Lafta
Ali Al Lafta

Reputation: 1

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));
}

Upvotes: 0

davidsbro
davidsbro

Reputation: 2758

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.

Upvotes: 0

Related Questions