0
\$\begingroup\$

I've been trying to implement collision for a platformer but I can't find a good way to get the collision of certain sides without it get glitchy. So i try to get the collision of the top rectangle first which works, but any other side has a problem. I have looked at days worths of tutorials and articles but they were either too complex or not calculating collision for one side of a rectangle. I am truely stumped and can't find a solution that works for me.

What I need:

  • working collision that wont give the bullet through paper problem *simple gravity (I have a way of doing this)
  • the collision allowing me to know what side is touching what

Now I don't want to do the method where the player is made up of several small rectangles because of possible future problems and the fact that it's not acurate. Can I have a small bite of code that shows how I can handle collision in these cases? Also, here's my current way of doing in OpenGL + Java:

public class AABBDemo {

        public AABBDemo() {
                try {
                        Display.setDisplayMode(new DisplayMode(640, 480));
                        Display.setTitle("test");
                        Display.create();
                } catch (LWJGLException e) {
                        e.printStackTrace();
                }

                glMatrixMode(GL_PROJECTION);
                glLoadIdentity();
                glOrtho(0, 640, 480, 0, -1, 1);
                glMatrixMode(GL_MODELVIEW);

                Rectangle A = new Rectangle(100, 100, 50, 50);//player
                Rectangle B = new Rectangle(100, 300, 90, 20);//enemy

                int leftA, leftB;
                int rightA, rightB;
                int topA, topB;
                int bottomA, bottomB;


                int xVel = 0;
                int yVel = 1;

                int size = 50;

                boolean jumping = false;                
                float jump = 0;
                boolean jumped = false;

                while (!Display.isCloseRequested()) {
                        glClear(GL_COLOR_BUFFER_BIT);



                        A.setX(A.getX() + xVel);
                        A.setY(A.getY() + yVel);



                        if(jumping)
                        {
                           A.setY((int) (A.getY() - jump));

                           jump -= 0.3f;

                           if(jump < -5)
                              jump = -5;

                        }

                        if(!jumping)
                           jump = 10;

                        if(A.getX() < 0 || A.getX() + size > 640 || check_collision(A, B))
                        {
                           jumping = false;
                           A.setX(A.getX() - xVel);
                           A.setY(A.getY() -  2);



                        }



                        if(Keyboard.isKeyDown(Keyboard.KEY_D))
                           xVel = 2;
                        else if(Keyboard.isKeyDown(Keyboard.KEY_A))
                           xVel = -2;
                        else 
                           xVel = 0;

                        if(Keyboard.isKeyDown(Keyboard.KEY_W) && !jumping && !jumped)
                        {
                           jumped = true;
                           jumping = true;
                        }

                        if(!Keyboard.isKeyDown(Keyboard.KEY_W))
                           jumped = false;





                        glBegin(GL_QUADS);
                        glColor3f(1, 0, 0);
                        glVertex2i(A.getX(), A.getY()); // Upper-left
                        glVertex2i(A.getX() + A.getWidth(), A.getY()); // Upper-right
                        glVertex2i(A.getX() + A.getWidth(), A.getY() +A.getHeight()); // Bottom-right
                        glVertex2i(A.getX(), A.getY() + A.getHeight()); // Bottom-left
                        glEnd();


                        glBegin(GL_QUADS);
                        glColor3f(0, 1, 0);
                        glVertex2i(B.getX(), B.getY());
                        glVertex2i(B.getX() + B.getWidth(), B.getY());
                        glVertex2i(B.getX() + B.getWidth(), B.getY() + B.getHeight());
                        glVertex2i(B.getX(), B.getY() + B.getHeight());
                        glEnd();

                        Display.update();
                        Display.sync(60);
                }

                Display.destroy();
                System.exit(0);
        }


        public boolean check_collision( Rectangle A, Rectangle B )
        {
            //The sides of the rectangles
            int leftA, leftB;
            int rightA, rightB;
            int topA, topB;
            int bottomA, bottomB;

            //Calculate the sides of rect A
            leftA = A.getX();
            rightA = A.getX() + A.getWidth();
            topA = A.getY();
            bottomA = A.getY() + A.getHeight();

            //Calculate the sides of rect B
            leftB = B.getX();
            rightB = B.getX() + B.getWidth();
            topB = B.getY();
            bottomB = B.getY() + B.getHeight();

            //If any of the sides from A are outside of B
            if( bottomA <= topB )
            {
                return false;
            }

            if( topA >= bottomB )
            {
                return false;
            }

            if( rightA <= leftB )
            {
                return false;
            }

            if( leftA >= rightB )
            {
                return false;
            }

            //If none of the sides from A are outside B
            return true;
        }


        public static void main(String[] args) {
                new AABBDemo();
        }

}
\$\endgroup\$
3
  • \$\begingroup\$ that's some massive white space in that code. are you basically trying to implement a collision check for 2 rectangles and also see which side is intersecting with which side ? how did you come up with this logic: if( bottomA <= topB ) return false; ? check_collision(A,B) would give a different result than check_collision(B,A), how does this work ? \$\endgroup\$
    – dimitris93
    Commented Apr 16, 2015 at 0:18
  • \$\begingroup\$ @Shiro I got the AABB information from lazy foo lazyfoo.net/SDL_tutorials/lesson17/index.php . that basically returns false if those parts of the rectangle intercept...i think \$\endgroup\$
    – The User
    Commented Apr 16, 2015 at 0:24
  • \$\begingroup\$ That code makes absolutely no sense. It doesn't even work in that specific example in the image right next to the code lazyfoo.net/SDL_tutorials/lesson17/collision.jpg if( bottomA <= topB ) would return false when there clearly is an intersection when at the same time bottomA is lower than topB \$\endgroup\$
    – dimitris93
    Commented Apr 16, 2015 at 1:02

1 Answer 1

0
\$\begingroup\$

Here is an Intersects(A,B) method implementation taken from C# Rectangle.cs

public bool Intersects(Rectangle a, Rectangle b) 
{
    return (b.X < a.X + a.Width)   &&
           (a.X < (b.X + b.Width)) &&
           (b.Y < a.Y + a.Height)  &&
           (a.Y < b.Y + b.Height);
}
\$\endgroup\$
12
  • \$\begingroup\$ Although this does do collision in a neater manner, it doesn't solve my problem with needing to tell if the player (or rect in this case) is colliding with a certain side of this Rectangle. I'm not sure If I can (or how to) use this for a platformer. \$\endgroup\$
    – The User
    Commented Apr 16, 2015 at 0:33
  • \$\begingroup\$ @CodeOfGenius a rectangle could intersect with another rectangle by being inside it, or intersect in the corner, or intersect with 2 or 3 sides at once. how does your game look like ? \$\endgroup\$
    – dimitris93
    Commented Apr 16, 2015 at 0:39
  • \$\begingroup\$ Oh, wellI got the collision to work with velocity. Now to make usre jumping physics don't screw it up. :D hastebin.com/woyadomogu.coffee . And my game has one platform right now. I had a bunch of 32x32 tiles but I'm using one platform for testing purposes. \$\endgroup\$
    – The User
    Commented Apr 16, 2015 at 0:50
  • \$\begingroup\$ @CodeOfGenius Sorry, I don't understand the context or the logic behind this code. What do you mean by "work with velocity" ? I can't visualize what your game looks like, without any information. What exactly are you trying to do in your game, other than checking if 2 rectangles intersect, since I already answered that. \$\endgroup\$
    – dimitris93
    Commented Apr 16, 2015 at 0:53
  • \$\begingroup\$ I'm trying to keep the player from going through the block when jumping. It's a falling box with one platform at the moment. \$\endgroup\$
    – The User
    Commented Apr 16, 2015 at 1:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .