|
|
This thread is locked; no one can reply to it.
|
1
2
|
| Allegro collision help! |
|
mrukki
Member #9,433
January 2008
|
Hello! Mrukki |
|
Yellow_Yackets
Member #9,427
January 2008
|
This function might help you:
|
|
TeamTerradactyl
Member #7,733
September 2006
|
Yellow_Yackets: please use [code]...[/code] tags... mrukki: for collision detection, tell us what kinds of objects you already have. You should both their x/y coordinates and their height/width. You can do rectangular bounds checking (not extremely accurate, but good enough), circular bounds checking (a little more accurate), etc. For rectangular bounds checking, use Yellow_Yackets' suggestion. For circular, simply determine on both objects where you want to ensure that they collide, and then use the distance formula (sqrt(a^2 + b^2)) and check that they don't. (More accurately: sqrt[(obj1.x - obj2.x)^2 + (obj1.y - obj2.y)^2].)
|
|
mrukki
Member #9,433
January 2008
|
Thanks guys! Now I have one idea! |
|
Paul whoknows
Member #5,081
September 2004
|
inline bool collide(int x1, int y1, int x2, int y2, int xx1, int yy1, int xx2, int yy2) { if (x2 <= xx1) return false; else if (x1 >= xx2) return false; else if (y2 <= yy1) return false; else if (y1 >= yy2) return false; else return true; } Tags: Bounding Box Collision ____ "The unlimited potential has been replaced by the concrete reality of what I programmed today." - Jordan Mechner. |
|
Timorg
Member #2,028
March 2002
|
A suggestion if you want to go with circular collisions as TeamTerradactyl suggested Don't use sqrt(), it can become a bottle neck for the code, instead of taking the square root of the two squares, square what you are comparing it to. (distance ^ 2) < (a^2 + b^2) and save on the sqrt() call, also ^ in c/c++ is the xor operator, not power of, so you will have to go (distance * distance) < ((a * a) + (b * b)) -Tim ____________________________________________________________________________________________ |
|
mrukki
Member #9,433
January 2008
|
Timorg: Thanks, but I'm using cub like players Paul whoknows: Thanks, I understand but not how I should use it? I have 4 variables called walk_u, walk_d, walk_r and walk_l, and I switching them true or false. How can I switch those when I use the function? Can I return the variables? |
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
One way is to check an objects future position with the bounding box collision check Paul suggested. That is , if they try to move , find their future position and check it with the bounding box collision function. If there is a collision , then they can't move that direction so don't update their position. However , If an object moves more that it's width combined with another object's width , then it can skip over the object in front of it using this method. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
|
mrukki
Member #9,433
January 2008
|
Thanks! Pauls function works good but it can't return 3 inline bool collide(int x1, int y1, int x2, int y2, int xx1, int yy1, int xx2, int yy2) { if (x2 >= xx1) return 0; else if (x2 < xx1) return 1; else if (x1 >= xx2) return false; else if (y2 <= yy1) return false; else if (y1 >= yy2) return false; } if (collide(image1_bb_left, image1_bb_top, image1_bb_right, image1_bb_bottom, image2_bb_left, image2_bb_top, image2_bb_right, image2_bb_bottom) == 0) walk_r = false; else if (collide(image1_bb_left, image1_bb_top, image1_bb_right, image1_bb_bottom, image2_bb_left, image2_bb_top, image2_bb_right, image2_bb_bottom) == 1) walk_r = true;
thats works good but if I do another statement in the function that I want to return 3 or change 1 to 3 it doesn't work |
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
Depending on what you want to do when a collision happens , if you just want to prevent the player from moving , then this would work fine.
However if you'd like to know which side it collided on , since it can only collide on the sides that it was moving towards , then check for overlaps in those directions.
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
|
mrukki
Member #9,433
January 2008
|
YES!!! I made it!! I used Pauls idea to make those functions.
Thanks everybody! Now I can continue working on my game! |
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
Your code for the collide_r function : inline bool collide_r(int t1, int b1, int r1, int l1, int t2, int b2, int r2, int l2) { if (r1 == l2 && b1 > t2 && t1 < b2) return false; else return true; }
Semantically , that code is : First of all , that will only work if you only ever move your objects by one at a time. Second , I think you've reversed the value that is returned by it. If all three of the conditions are true then a collision has occurred (The edges are at the same position and their dimensions perpendicular to the direction of movement overlap (collide_r is for when moving right , correct?)) but you return false. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
|
OnlineCop
Member #7,919
October 2006
|
Dang, mrukki, that sure is complicated. Why have all those separate functions (and all those passed-in variables)?!
This should tell you where the collision hit (by the returned "Collisions" value), and if it returns "none", then you don't have to do any further tests. Having the structure such that you represent the x/y coordinates (as being the center of the image), you can even use the same structure to do rounded bounds checking (which can be even faster than rectangular bounds checking).
|
|
mrukki
Member #9,433
January 2008
|
Edgar Reynaldo: I have variables called walk_r, walk_l, walk_u and walk_d and if a collision occurred it turns to false and ex walk_r turns false. OnlineCop: Thanks! I've tried to use OnlineCops function but I getting errors if (collide_rect(image1, image2) == COLLISION_NONE) { walk_u = true; walk_d = true; walk_l = true; walk_r = true; } And I get the error: invalid initialization of reference of type 'Objects&' from expression of type 'BITMAP*' in passing argument 1 of `int collide_rect(Objects&, Objects&)' I don't understand the error but it's something with image1 and image2, |
|
someone972
Member #7,719
August 2006
|
Are you passing a BITMAP* to the function, instead of an object? Here is an example of how to use it if you are:
Hope this helps;D. ______________________________________ |
|
mrukki
Member #9,433
January 2008
|
Oh yeah! Thanks man! EDITED: OH!! Why won't it work! I've tried all ways but it just don't work!
And when I get in collision it just ignore it, I don't know how to do? |
|
OnlineCop
Member #7,919
October 2006
|
You don't need the lines: int right = COLLISION_RIGHT; int left = COLLISION_LEFT; int top = COLLISION_TOP; int bottom = COLLISION_BOTTOM; I've reworked this (haven't tested it, but logically, it should work...), but try something like this:
It may blow up, but I THINK that it should work now.
|
|
someone972
Member #7,719
August 2006
|
Mrukki, in the collision detection code you posted you have the checks as '=='. Ex: if(player1.left == player2.right) This wouldn't always work because player1's left could be past player2's right and still be having a collision. ______________________________________ |
|
mrukki
Member #9,433
January 2008
|
OnlineCop: Your code is great! But it have an error if ((players[0] == player2) && (result != COLLISION_NONE))
Here's the error message: |
|
OnlineCop
Member #7,919
October 2006
|
It should probably be something like: The "players[0]" should be pointing to the address of player2, instead of to the object itself. See if that helps.
|
|
mrukki
Member #9,433
January 2008
|
I didn't work. I got the same error |
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
Semantically , there's nothing wrong with the line the way it was when you first got the error. From OnlineCop's code , players[0] and player2 are both 'Objects' objects. There may be some kind of include error. That's usually the only time I see the compiler suggest allegro's fixed class functions. You may have to actually write an equivalence operator for the Objects class(struct) yourself. I can't remember if the compiler supplies a default equivalence operator or not. From http://www.cplusplus.com/doc/tutorial/classes.html : cplusplus.com said: But the compiler not only creates a default constructor for you if you do not specify your own. It provides three special member functions in total that are implicitly declared if you do not declare your own. These are the copy constructor, the copy assignment operator, and the default destructor. So , no I don't believe the compiler supplies a default equivalence operator. You could write one like this :
However , you could accomplish the same thing in OnlineCop's code by making players[2] an array of two pointers to player1 and player2 instead. You can only do that as long as the function parameters are Objects& (Objects references) though.
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
|
mrukki
Member #9,433
January 2008
|
Edgar Reynaldo: Thanks for the code but I think it's to difficult
|
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
That will only work if the character moves 1 pixel at a time. Do you remember to update the bottom right corner position values when the character moves? In my previous post , if the code in the first window is too advanced for right now , the code in the second window was just a very minor modification to what you were using from OnlineCop's code. It was only to prevent the compiler error you were getting by allowing you to check if they were the same objects by checking to see if they had the same address in memory. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
|
mrukki
Member #9,433
January 2008
|
I've updating the variables like this: while (!key[KEY_ESC]) { while (speed > 0) { l1 = charx; t1 = chary; r1 = (l1 + image1->w); b1 = (t1 + image1->h); character.left = l1; character.right = r1; character.top = t1; character.bottom = b1;
Yeah, But I think I'll first try to get my code to work |
|
|
1
2
|