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\$
  • \$\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 Apr 16 '15 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 Apr 16 '15 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 Apr 16 '15 at 1:02
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\$
  • \$\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 Apr 16 '15 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 Apr 16 '15 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 Apr 16 '15 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 Apr 16 '15 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 Apr 16 '15 at 1:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.