1

I'm trying to implement 2D collision detection with two rectangles constructed using a graphics package. Unfortunately, I'm beginning to think I don't understand the logic needed to write a function that will handle this.

Below is my code that draws a small sprite and a couple of other rectangles. My sprite moves with keyboard inputs.

I've used several books and also tried sites like Nehe etc and although they're really good tutorials, they only seems to deal directly with 3D collision.

Can someone please show me an efficient way of implementing collision detection using my rectangles above? I know you need to compare the coordinates of each object. I'm just unsure how to track the position of the objects, checking collision and stopping it moving should it collide.

I am self learning and seem to have come to a stop for days now. I'm totally out of ideas and searched more google pages than I care to remember. I'm sorry for my naivety.

I'd appreciate any constructive comments and example code. Thank you.

    void drawSprite (RECT rect){
    glBegin(GL_QUADS);
        glColor3f(0.2f, 0.2f, 0.2f);
            glVertex3f(rect.x, rect.y, 0.0);
        glColor3f(1.0f, 1.0f, 1.0f);
            glVertex3f(rect.x, rect.y+rect.h, 0.0);
        glColor3f(0.2f, 0.2f, 0.2f);
            glVertex3f(rect.x+rect.w, rect.y+rect.h, 0.0);
        glColor3f(1.0f, 1.0f, 1.0f);
            glVertex3f(rect.x+rect.w, rect.y, 0.0);
    glEnd();
}

void drawPlatform (RECT rect){
    glBegin(GL_QUADS);
        glColor3f(0.2f,0.2f,0.0f);
            glVertex3f(rect.x, rect.y, 0.0);
        glColor3f(1.0f,1.0f,0.0f);
            glVertex3f(rect.x, rect.y+rect.h, 0.0);
        glColor3f(0.2f, 0.2f, 0.0f);
            glVertex3f(rect.x+rect.w, rect.y+rect.h, 0.0);
        glColor3f(1.0f, 1.0f, 0.0f);
            glVertex3f(rect.x+rect.w, rect.y, 0.0);
    glEnd();
}
Reanimation
  • 3,151
  • 10
  • 50
  • 88
  • Searching the web for "2D collision detection" brings up a lot of tutorials. Can you describe *why* those didn't work for you? – Drew Dormann Mar 20 '13 at 14:03
  • I guess its because I don't understand them. Maybe I've read too many and confusing myself. I think where I'm going wrong is I'm not 100% sure how to track the current position of the sprite therefore I think I'm always comparing the sprites origin x/y which, of course, will always return as a false collision... – Reanimation Mar 20 '13 at 14:12
  • You may want to refine your question to a specific "first step" that you're trying. Tracking the position, perhaps. If tutorials have only confused you then asking for another tutorial is probably not going to help. – Drew Dormann Mar 20 '13 at 14:18
  • Thanks for your patience. That's a good point. I've now written a function that tests collision based on the comment below, but when my sprite collides with another rectangle it redraws my sprite at the original x/y coordinates. Hence back to the "tracking" dilemma. – Reanimation Mar 20 '13 at 14:33

2 Answers2

2

You can use this collide function with an AABB struct (AABB stands for Aligned Axis Bounding Box) before drawing.

AABB.c

AABB* box_new(float x, float y, float w, float h, int solid)
{
    AABB* box = 0;
    box = (AABB*)malloc(sizeof(AABB*));

    box->x = (x) ? x : 0.0f;
    box->y = (y) ? y : 0.0f;
    box->width = (w) ? w : 1.0f;
    box->height = (h) ? h : 1.0f;

    return(box);
}

void box_free(AABB *box)
{
    if(box) { free(box); }
}

int collide(AABB *box, AABB *target)
{
    if
    (
        box->x > target->x + target->width &&
        box->x + box->width < target->x &&
        box->y > target->y + target->height &&
        box->y + box->height < target->y
    )
    {
        return(0);
    }
    return(1);
}

AABB.h

#include <stdio.h>
#include <stdlib.h>

typedef struct AABB AABB;
struct AABB
{
    float x;
    float y;
    float width;
    float height;
    int solid;
};

AABB* box_new(float x, float y, float w, float h, int solid);
void box_free(AABB *box);
int collide(AABB *box, AABB *target);

I hope it will help ! :)

1

You won't get that far by detecting a collision since you will have issues of floating-point precision. What you can do is detect overlaps between the rects, and if such an overlap occurs the collision has already happened so you can bump the rects out of each other.

Also, you need to split the engine in two states:

  1. Rects get moved by input
  2. Overlaps are detected and if found the rects get moved out of each other
  3. Display the scene

As to detecting whether two rects overlap see this question:

Determine if two rectangles overlap each other?

Community
  • 1
  • 1
Julik
  • 7,676
  • 2
  • 34
  • 48
  • 1
    It should (probably) be noted that this approach will miss collisions that would only occur *between* two successive updates. – Drew Dormann Mar 20 '13 at 14:07
  • Totally, but is it not so that any engine will quantize T when doing this kind of stuff? – Julik Mar 20 '13 at 14:08
  • 1
    Thanks for taking the time to write your comment. Its very constructive. I have taken it on board and written a collision test. My sprite now disappears and reappears at its original x/y coordinates when it collides another rectangle. It's not what I wanted but at least I'm getting some interaction between them now, which is more than I've had for days :P – Reanimation Mar 20 '13 at 14:35