13 Replies - 900 Views - Last Post: 07 May 2013 - 04:06 PM Rate Topic: -----

#1 Goldfinger007  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 27
  • Joined: 17-September 12

Rectangle collision is not working correctly

Posted 01 May 2013 - 01:26 PM

I have difficulties with the rectangle collision. My character can go through the right side and through the bottom of each platform rectangle. I guess their is a mathematical problem with the collision, but I don't know what is wrong.
What should I change? I want to do a little platformer, something like the old Mario games.
Backgrounds.LevelTilesList is a list of type RectangleF. Every tile in the level is saved in this list.
Vector2 Player_Gravity = new Vector2(0, 4.5f);
Vector2 Player_Movement = new Vector2();
Vector2 Player_Size = new Vector2(29, 80);
System.Drawing.RectangleF Player_RectF = new System.Drawing.RectangleF(100, 100, 29, 80);
System.Drawing.RectangleF Player_NewRect;
bool collisionTop, collisionBottom, collisionRight, collisionLeft;


    protected override void Update(GameTime gameTime)
    {
        KeyboardState currentkeyState = Keyboard.GetState();

        if (currentkeyState.IsKeyDown(Keys.Left))
            Player_Movement.X -= 5;
        if (currentkeyState.IsKeyDown(Keys.Right))
            Player_Movement.X += 5;
        if (currentkeyState.IsKeyDown(Keys.Up))
            Player_Movement.Y -= 10;
        if (currentkeyState.IsKeyDown(Keys.Down))
            Player_Movement.Y += 10;

        Player_Movement += Player_Gravity;
        // Calculate new position
        Player_NewRect = Player_RectF;
        Player_NewRect.X += Player_Movement.X;
        Player_NewRect.Y += Player_Movement.Y;

        // check for collision
        for (int j = 0; j <= Backgrounds.LevelTilesList.Count - 1; j++)
        {
            if (Player_NewRect.IntersectsWith(Backgrounds.LevelTilesList[j]))
            {
                float halfBoxWidth = Backgrounds.LevelTilesList[j].Width * 0.5f;
                float halfBoxHeight = Backgrounds.LevelTilesList[j].Height * 0.5f;
                float halfBoxPlayerWidth = Player_NewRect.Width * 0.5f;
                float halfBoxPlayerHeight = Player_NewRect.Height * 0.5f;

                Vector2 posDiff = new Vector2((int)((Backgrounds.LevelTilesList[j].X + halfBoxWidth) - (Player_NewRect.X + halfBoxPlayerWidth)), (int)((Backgrounds.LevelTilesList[j].Y + halfBoxHeight) - (Player_NewRect.Y + halfBoxPlayerHeight)));
                float maxDiffX = halfBoxWidth + halfBoxPlayerWidth;
                float maxDiffY = halfBoxHeight + halfBoxPlayerHeight;

                collisionTop = posDiff.Y < -halfBoxHeight &&
                                        posDiff.Y > (maxDiffY) * -1
                                        &&
                                        !collisionRight && !collisionLeft;

                collisionBottom = posDiff.Y > halfBoxHeight &&
                                        posDiff.Y < maxDiffY
                                        &&
                                        !collisionRight && !collisionLeft;

                collisionLeft = posDiff.X < -halfBoxWidth &&
                                    posDiff.X > maxDiffX * -1 &&
                                    !collisionBottom && !collisionTop;

                collisionRight = posDiff.X > halfBoxWidth &&
                                        posDiff.X < maxDiffX &&
                                        !collisionBottom && !collisionTop;

                if (collisionTop || collisionBottom)
                    Player_Movement.Y *= -0.5f;
                if (collisionLeft || collisionRight)
                    Player_Movement.X *= -0.5f;


                // Adjust the position
                if (collisionBottom)
                {
                    Player_NewRect.Y -= Player_NewRect.Bottom - Backgrounds.LevelTilesList[j].Top;
                }

                if (collisionTop)
                {
                    Player_NewRect.Y += Player_NewRect.Top - Backgrounds.LevelTilesList[j].Bottom;
                }

                if (collisionLeft)
                {
                    Player_NewRect.X += Player_NewRect.Left - Backgrounds.LevelTilesList[j].Right;
                }

                if (collisionRight)
                {
                    Player_NewRect.X -= Player_NewRect.Right - Backgrounds.LevelTilesList[j].Left;
                }
            }
        }

        Player_RectF = Player_NewRect;
        Player_Movement = new Vector2(0, 0);  
        base.Update(gameTime);
    }


Is This A Good Question/Topic? 0
  • +

Replies To: Rectangle collision is not working correctly

#2 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3652
  • View blog
  • Posts: 11,421
  • Joined: 05-May 12

Re: Rectangle collision is not working correctly

Posted 01 May 2013 - 05:50 PM

I suggest setting up a unit test and stepping through the code. You've got a very powerful debugger in the form of Visual Studio. Use it.

I don't think the problem is with collision detection. I think that the problem is with your collision resolution. I feel that you outsmarted yourself with the use of posDiff, maxDiffX, and maxDiffY. Your determination of collisionTop and collisionBottom depends on collisionLeft and collisionRight having bet set, but those get set a few lines later.
Was This Post Helpful? 0
  • +
  • -

#3 Goldfinger007  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 27
  • Joined: 17-September 12

Re: Rectangle collision is not working correctly

Posted 02 May 2013 - 03:39 PM

I'm sure that I don't need the 4 lines 60-63. I have deleted these lines.
Is it better to use a completely different collision resolution? Is it better to work without posDiff, maxDiffX and maxDiffY?
Was This Post Helpful? 0
  • +
  • -

#4 aczwicker  Icon User is offline

  • New D.I.C Head
  • member icon

Reputation: 2
  • View blog
  • Posts: 43
  • Joined: 23-May 12

Re: Rectangle collision is not working correctly

Posted 02 May 2013 - 04:32 PM

Does this happen to be in Unity3d?
Was This Post Helpful? 0
  • +
  • -

#5 Goldfinger007  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 27
  • Joined: 17-September 12

Re: Rectangle collision is not working correctly

Posted 03 May 2013 - 01:03 AM

I work with Visual Studio/XNA.
Was This Post Helpful? 0
  • +
  • -

#6 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3652
  • View blog
  • Posts: 11,421
  • Joined: 05-May 12

Re: Rectangle collision is not working correctly

Posted 03 May 2013 - 06:26 AM

My original thought was to take advantage of the resulting rectangle of the intersection, but a pile of corner cases (no pun intended) come up. Maybe there is no recourse but to handle each case one by one.

You may get more traction on this question if it is posted in the game programming subforum. Would you like this topic to be moved there?
Was This Post Helpful? 0
  • +
  • -

#7 Goldfinger007  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 27
  • Joined: 17-September 12

Re: Rectangle collision is not working correctly

Posted 03 May 2013 - 06:57 AM

OK. You can move it to the game programming subforum.
Was This Post Helpful? 0
  • +
  • -

#8 oyyou  Icon User is offline

  • D.I.C Head

Reputation: 27
  • View blog
  • Posts: 190
  • Joined: 26-April 10

Re: Rectangle collision is not working correctly

Posted 03 May 2013 - 07:14 AM

Hey man, I've had this problem plenty of times and came up with a solution to fix it.
I'm not on my home computer atm so I can't just give you the code, but if you go here and look through my tutorials, I have an extension method I use for rectangle collision.

I think the best one is in my tile map creator tutorial (2/3), but I'm not entirely sure.

If you find it, and have any problems with it, just ask away.
Was This Post Helpful? 0
  • +
  • -

#9 Goldfinger007  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 27
  • Joined: 17-September 12

Re: Rectangle collision is not working correctly

Posted 04 May 2013 - 01:56 PM

thanks, I will try your tutorial. http://www.youtube.c...h?v=l0WS5SvKdY4
Is your rectangle collision working with multiple collisions at the same time? For example, if the player touches 2 different tiles at the same time. Is that working correctly? Because I had always trouble with my rectangle collision if this case happened.
In addition, my player moves sometimes very fast. Is that a problem for your rectangle collision? Because I don't want that the player moves thru the tiles.
Was This Post Helpful? 0
  • +
  • -

#10 oyyou  Icon User is offline

  • D.I.C Head

Reputation: 27
  • View blog
  • Posts: 190
  • Joined: 26-April 10

Re: Rectangle collision is not working correctly

Posted 06 May 2013 - 06:35 AM

It generally does work with multiple rectangles at once, but that depends on how you pass the rectangles.
And for the fast movement, you can alter the RectangleHelper to work for that.
Was This Post Helpful? 0
  • +
  • -

#11 Goldfinger007  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 27
  • Joined: 17-September 12

Re: Rectangle collision is not working correctly

Posted 06 May 2013 - 07:01 AM

I tried the tile map creator tutorial (2/3), but the player can jump thru the tiles if it touches the bottom of the tiles. I don't know what is wrong with the code :helpsmilie:
Was This Post Helpful? 0
  • +
  • -

#12 anonymous26  Icon User is offline

  • D.I.C Lover

Reputation: 1
  • View blog
  • Posts: 3,638
  • Joined: 26-November 10

Re: Rectangle collision is not working correctly

Posted 06 May 2013 - 06:39 PM

Alright, someone needs to put a stop to this. Hasn't anyone heard of a ray intersection test? It doesn't have to be super complicated, but can make collision detection between rectangles very accurate.

Imagine you have a square, you subdivide that square into four equal part vertically and horizontally. These lines that partition the square extend along each of their axes to infinity. Now, if these conceptual lines extend from the center of the rectangle that it belongs to, it should bisect the side of its own rectangle first. If it bisects another rectangle's side at the same time or before it bisects a side of the rectangle that it belongs to, a collision has taken place.

This is based on pure math with no magic numbers and can be quickly computed for any number of rectangles. What has been suggested to this point has been terrible and lazy. Put some thought into it.
Was This Post Helpful? 0
  • +
  • -

#13 oyyou  Icon User is offline

  • D.I.C Head

Reputation: 27
  • View blog
  • Posts: 190
  • Joined: 26-April 10

Re: Rectangle collision is not working correctly

Posted 07 May 2013 - 02:35 AM

View PostButchDean, on 06 May 2013 - 06:39 PM, said:

This is based on pure math with no magic numbers and can be quickly computed for any number of rectangles. What has been suggested to this point has been terrible and lazy. Put some thought into it.


Is there any way you could do show an example of this?
It's all well on good telling us what type of collision to implement, but getting started can be difficult if we have no idea what you mean?
Was This Post Helpful? 0
  • +
  • -

#14 anonymous26  Icon User is offline

  • D.I.C Lover

Reputation: 1
  • View blog
  • Posts: 3,638
  • Joined: 26-November 10

Re: Rectangle collision is not working correctly

Posted 07 May 2013 - 04:06 PM

What don't you understand? Did you look up 'ray intersection test'?
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1