Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Best way for collision detection/bounding box collision

This thread is locked; no one can reply to it. rss feed Print
 1   2 
Best way for collision detection/bounding box collision
Lasaqus7
Member #15,950
May 2015

That's slowly making some kind of sense to me. Thanks

I saw the difference between #define NOGDI and without it too, I'd never heard of this till now.

I have no implemented code which you gave previously and tried to do it the best I could, it now runs without errors, although no collision detected.

I'm now going to try and see what is not working and hopefully fix it. It is quite difficult to learn as it's a lot of new things to take in.

Edit: I think I'm slowly getting there, but having an issue with the array (Not sure where to put it or code it);

#SelectExpand
1struct Rectangle 2{ 3 int x, y, w, h; 4}; 5struct Player 6{ 7 Rectangle r; //Working now 8 //Other Player Variables 9}; 10void RectSet(Rectangle* pr, int x, int y, int w, int h); 11void RectInit(Rectangle* pr); 12bool Collision2(Player &Human1, Rectangle* pr); 13 14int main(int argc, char **argv) 15{ 16 Player p; 17 Player* pp = &p; 18 Rectangle* pr = &(pp->r); 19 RectInit(pr); // Not 100% this goes here 20} 21while (!done) 22 { 23 ALLEGRO_EVENT ev; 24 al_wait_for_event(event_queue, &ev); 25else if (ev.type == ALLEGRO_EVENT_TIMER) 26 { 27 render = true; 28 29 if (keys[W]) 30 { 31 //if (Collision(Human1, Human2) == false) 32 if (Collision2(Human1, &(pp->r)) == false) 33 { 34 Human1.oldy = Human1.y; 35 Human1.oldx = Human1.x; 36 MoveHumanUp(Human1); 37 } 38 else 39 { 40 Human1.y = Human1.oldy; 41 Human1.x = Human1.oldx; 42 } 43 } 44 } 45} 46//////////// 47//END OF MAIN 48//////////// 49void RectSet(Rectangle* pr, int x, int y, int w, int h) 50{ 51 for (int i = 0; i < array_size; i++) 52 { 53 pr->x = x; 54 pr->y = y; 55 pr->w = w; 56 pr->h = h; 57 } 58} 59void RectInit(Rectangle* pr) 60{ 61//I guess the array goes here ? 62 RectSet(pr, 0, 0, 860, 90) 63 RectSet(pr, 920, 0, 360, 210); 64} 65bool Collision2(Player &Human1, Rectangle* pr) 66{ 67 if ((Human1.x > Human1.speed + pr->x + pr->w - 1) || 68 (Human1.y > Human1.speed + pr->y + pr->h - 1) || 69 (pr->x > Human1.x + Human1.speed + Human1.w - 1) || 70 (pr->y > Human1.y + Human1.speed + Human1.h - 1)) 71 return false; 72 else 73 return true; 74}

I have only managed to get 1 bound to collide, I guess as there is no array whatever the last x, y, w, h values where are the only ones stored.

I hope I have things in somewhat the correct way now, as you can see I have taken parts of the codes you have provided me

Edgar Reynaldo
Member #8,592
May 2007
avatar

Go ahead and keep posting code if you need to. The best way to learn is from making mistakes and figuring them out. We're here to help.

Edit for your edit. Don't just add code in without knowing what it does. Those were just examples of how to work with structs and pointers, it isn't all actual code that you should be using.

I said:

Then you include a Rectangle member in your Human or other structs if they need one.

typedef struct Human {
   // ...
   Rectangle pos;
};

And you test for collision between Humans and other objects (such as Humans) by checking their rectangles.

bool HumansCollide(Human* h1 , Human* h2) {
   return RectCollide(&(h1->pos) , &(h2->pos));
}

Something that will help you is a helper function like this :

bool CollideRects(Rectangle* r1 , Rectangle* r2) {
//...
}

bool CollidePlayerAndHuman(Player* p , Human* h) {
   return CollideRects(&(p->rect) , &(h->rect));
}

To create an array, you need to use a constant size variable for the size, or else you need to allocate memory dynamically through malloc or new or new[] and then use free or delete or delete[] respectively.

const int MAX_NUM_ENEMIES = 10;
Human humans[MAX_NUM_ENEMIES];
// or
Human* mhumans = (Human*)malloc(MAX_NUM_ENEMIES*sizeof(Human));
// or
Human* nhumans = new Human[MAX_NUM_ENEMIES];
// and then to free it you do either
free(mhumans);
// or 
delete [] nhumans;

Edit2
Oh, and I forgot you need to test against the future position. This can easily be accomplished by another helper function :

   void MoveRectBy(Rectangle* r , int dx , int dy) {
      r->x += dx;
      r->y += dy;
   }

Then to use it you do :

   bool CollideHumanWithPlayer(Human* h , Player* p) {
      Rect future_human_rect = h->rect;
      MoveRectBy(&future_human_rect , h->xvelocity , h->yvelocity);
      return CollideRects(&(p->rect) , &future_human_rect);
   }

Lasaqus7
Member #15,950
May 2015

Yeah, I was kinda thinking the code you posted was to be used to get it to work. But also if I write my code how I get the advice I can sometimes see how and why it works.

At the moment I have all the movement and things set up to work correctly.

The only thing I'm working on at the moment, is to have my rectangles co-ordinates set into an array and then pass this array into the collision detection.

So for example (I know this isn't code format but easier to do for me)

RectangleBoundingBox say has 2 rectangles to store data for
(x, y, w, h)
So my 2 rectangles are
(0, 0, 860, 90)
(920, 0, 360, 210)
These should be stored in an array

Then in my collision which I have setup as
(Human1.x > Human1.speed + RectangleBoundingBoxArray.x + RectangleBoundingBoxArray.w - 1)

Rather than mutliple rows of that code, all my bounds co-ords should be in an array.
As of now I have only managed to collided with 1 rectangle, to me is seems that the array isn't working well inside the collision function.

The code you posted, I will look at in future, as I feel the way we got told to program this is not the easiest nor the best, so next time around I'll be looking into different ways to do it.

Should I use my array like ARRAYNAME[2][4], so it has 2 rows and 4 co-ords or is that not needed because I'm reading about them and they say to do that with a 2 dimensonal array.

Edgar Reynaldo
Member #8,592
May 2007
avatar

Arrays can be hard to work with. You might want to use a std::vector<Rectangle>.

With a vector you can add a rectangle to your vector at any time.

#SelectExpand
1#include <vector> 2using std::vector; 3 4struct Rectangle { 5 int x,y,w,h; 6}; 7 8int main(int argc , char** argv) { 9 10 vector<Rectangle> rects; 11 12 Rectangle r = {0,0,10,10}; 13 14 rects.push_back(r); 15 16 Rectangle r2 = {50,50,100,100}; 17 18 rects.push_back(r2); 19 20 printf("Size of our rects vector is : %u\n" , rects.size()); 21 22 for (unsigned int i = 0 ; i < rects.size() ; ++i) { 23 Rectangle r = rects[i];// like an array 24 printf("r : x = %d , y = %d , w = %d , h = %d\n" , r.x , r.y , r.w , r.h); 25 } 26 27 return 0; 28}

SGI's STL guide is the best way to learn the C++ Standard Template Library.
https://www.sgi.com/tech/stl/

And specifically on vectors :
https://www.sgi.com/tech/stl/Vector.html

Later on once you want to remove objects from your array you might want to use a std::list<Rectangle> instead.
Read about list here :
https://www.sgi.com/tech/stl/List.html

Lasaqus7
Member #15,950
May 2015

I'll look into these Edgar, I'm going to have more time on this as I hand in my game tomorrow.

I may even look into using the tile map editor to create the bounds for my terrain, it was some that seemed really complicated and I didn't want to break my game before the hand in.

I do feel I still went above and beyond what was needed so here's hoping.

Not sure where to put this but for everyone that helped on this. I appreciate it, and this is was I came up with in the end.

My 2D Game

Still issues and bugs to fix, but it will all come in time.

Thank again all.

 1   2 


Go to: