Public Group

#### Archived

This topic is now archived and is closed to further replies.

# Collisions --> Allegro --> Pong

This topic is 5280 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi..im making a pong game with allegro.But Im having problems with collision detection (Im using bounding box). The problem is that when the ball hits one of the corners of the pad1 or pad2 it falls through the pad (with no collision at all). I would like to know what I am doing wrong.

while (!key[KEY_ESC])

{

while (Counter > 0)

{

Ball.PosY +=Ball.Speed*Ball.vy;
Ball.PosX +=Ball.Speed*Ball.vx;

ComputePlayers ();

// Player 1 //////////////////////////////////////////////////////////////////////

if ( ((Ball.PosX >= Player1.PosX) && (Ball.PosX <= Player1.PosX+Player1.map->w)) &&
((Ball.PosY >= Player1.PosY ) && (Ball.PosY <= Player1.PosY+Player1.map->h)) )

{

Ball.vx = -Ball.vx;

}

if ( (Ball.PosX >= Player1.PosX) &&
(Ball.PosX <= (Player1.PosX + Player1.map->w)) &&
(Ball.PosY <= (Player1.PosY + Player1.map->h)) &&
(Ball.PosY >= Player1.PosY) )

{

Ball.vy = -Ball.vy;

}

///////////////////////////////////////////////////////////////////////////////////

if ( (((Ball.PosX+Ball.map->w) >= Player2.PosX) && ((Ball.PosX+Ball.map->w) <= Player2.PosX+Player2.map->w)) &&
((Ball.PosY >= Player2.PosY ) && (Ball.PosY <= Player2.PosY+Player2.map->h)) )

{

Ball.vx = -Ball.vx;

}

// We test for player 1 coordinates
if (key[KEY_W])
Player1.PosY-=4;

if (key[KEY_S])
Player1.PosY+=4;

// We test for player 2 coordinates
Player2.PosY-=4;

Player2.PosY+=4;

Counter--;

}

vsync ();
textprintf (Buffer,font,8,8,makecol (255,255,255),"Player 1 Score: %d",Player1Score);
textprintf (Buffer,font,174,8,makecol (255,255,255),"Player 2 Score: %d",Player2Score);
blit (Buffer,screen,0,0,0,0,320,200);
clear(Buffer);

}


Thanks

##### Share on other sites
well what is your player position, is it the center of the paddle, the top or bottom of a paddle? that will change how you do the detection with your algorithm, for example playerY + map height might detect wrongly if your playerY isnt the bottom coord for your bounding box. id suggest making a rectangle structure like this one:
struct Rect{     int x,y,x2,y2;     bool collision(const Rect &obj)     {        return(    (Rect.x >= this.x)&&               (Rect.y <= this.y)&&               (Rect.x2 >= this.x2)&&               (Rect.y2 <= this.y2)    )     }};

then give each object that needs detection a Rect member and maintain proper coordinate maintaince ( ie making sure the bound box''s X and Y are the same X and Y of the bitmap your rendering)

##### Share on other sites
I wish you posted something that actually compiled. I starte filling in the missing pieces, then I started changing your code, and in the end I ended up with something completely different and I never figured out what was wrong with your code.

Anyway, this is what I ended up with:
#include <allegro.h>#include <math.h>#include <time.h>#include <stdlib.h>struct entity {  float PosX, PosY, vx, vy;  BITMAP *map; };void Update(struct entity *e, int friction) {  e->PosX += e->vx;  e->PosY += e->vy;    if(friction)   {    e->vx *= 0.99;    e->vy *= 0.99;        if(e->PosY < 0)     e->vy = fabs(e->vy)*0.7;    else if(e->PosY + e->map->h > SCREEN_H)     e->vy = -fabs(e->vy)*0.7;   }  else   {    if(e->PosY < 0)     e->vy = fabs(e->vy);    else if(e->PosY + e->map->h > SCREEN_H)     e->vy = -fabs(e->vy);   } }void ResetBall(struct entity *b) {  b->PosX = SCREEN_W/2-b->map->w/2;  b->PosY = SCREEN_H/2-b->map->h/2;  b->vx = ((rand()%2)?1:-1)*(rand()/(float)RAND_MAX+1.3);  b->vy = rand()/(float)RAND_MAX*2.0-1.0; }int main(int argc, char *argv[]) {  srand(time(0));  allegro_init();  set_color_depth(32);  set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0);  BITMAP *Buffer = create_bitmap(SCREEN_W, SCREEN_H);  install_keyboard();    struct entity Ball, Player1, Player2;  int Player1Score = 0, Player2Score = 0;    Ball.map = create_bitmap(17, 17);  clear_to_color(Ball.map, MASK_COLOR_32);  circlefill(Ball.map, 8, 8, 8, makecol(255, 255, 255));  ResetBall(&Ball);    Player1.map = create_bitmap(16, 64);  clear_to_color(Player1.map, makecol(255, 0, 0));  rectfill(Player1.map, 0, 8, 8, 56, MASK_COLOR_32);  Player1.PosX = 0;  Player1.PosY = SCREEN_H/2-16;  Player1.vx = Player1.vy = 0;    Player2.map = create_bitmap(16, 64);  clear_to_color(Player2.map, makecol(0, 0, 255));  rectfill(Player2.map, 8, 8, 16, 56, MASK_COLOR_32);  Player2.PosX = SCREEN_W-16;  Player2.PosY = SCREEN_H/2-16;  Player2.vx = Player2.vy = 0;    while(!key[KEY_ESC])   {    Update(&Ball, 0);    Update(&Player1, 1);    Update(&Player2, 1);        // Player 1    if(Ball.vx < 0 && Ball.PosX < Player1.PosX+Player1.map->w)     {      if(Ball.PosY >= Player1.PosY - Ball.map->h && Ball.PosY <= Player1.PosY + Player1.map->h)       {        Ball.vx *= -1;        Ball.vy += Player1.vy;       }      else       {        ResetBall(&Ball);        ++Player2Score;       }     }          // Player 2    if(Ball.vx > 0 && Ball.PosX + Ball.map->w > Player2.PosX)     {      if(Ball.PosY >= Player2.PosY - Ball.map->h && Ball.PosY <= Player2.PosY + Player2.map->h)       {        Ball.vx *= -1;        Ball.vy += Player2.vy;       }      else       {        ResetBall(&Ball);        ++Player1Score;       }     }        if(key[KEY_W])     Player1.vy -= 0.1;        if(key[KEY_S])     Player1.vy += 0.1;        if(key[KEY_8_PAD])     Player2.vy -= 0.1;        if(key[KEY_5_PAD])     Player2.vy += 0.1;        vsync();    clear(Buffer);    masked_blit(Player1.map, Buffer, 0, 0, Player1.PosX, Player1.PosY, Player1.map->w, Player1.map->h);    masked_blit(Player2.map, Buffer, 0, 0, Player2.PosX, Player2.PosY, Player2.map->w, Player2.map->h);    masked_blit(Ball.map, Buffer, 0, 0, Ball.PosX, Ball.PosY, Ball.map->w, Ball.map->h);    textprintf(Buffer, font, 8, 8, makecol(255,255,255), "Player 1 Score: %d", Player1Score);    textprintf(Buffer, font, 174, 8, makecol(255,255,255), "Player 2 Score: %d", Player2Score);    blit(Buffer,screen,0,0,0,0,SCREEN_W, SCREEN_H);   }    allegro_exit(); } END_OF_MAIN();

[edited by - smart_idiot on June 4, 2004 6:47:00 AM]

##### Share on other sites
Oh, and just for fun, try adding ''e->vy += 0.05;'' to the start of the Update function. Gravity makes things a little harder, don''t you think?

##### Share on other sites
Still playing around. Look, multiple balls!

#include <allegro.h>#include <math.h>#include <time.h>#include <stdlib.h>#define BALLS 5struct entity {  float PosX, PosY, vx, vy;  BITMAP *map; };void Update(struct entity *e, int friction) {  e->PosX += e->vx;  e->PosY += e->vy;    if(friction)   {    e->vx *= 0.99;    e->vy *= 0.99;        if(e->PosY < 0)     e->vy = fabs(e->vy)*0.7;    else if(e->PosY + e->map->h > SCREEN_H)     e->vy = -fabs(e->vy)*0.7;   }  else   {    if(e->PosY < 0)     e->vy = fabs(e->vy);    else if(e->PosY + e->map->h > SCREEN_H)     e->vy = -fabs(e->vy);   } }void ResetBall(struct entity *b) {  b->PosX = SCREEN_W/2-b->map->w/2;  b->PosY = SCREEN_H/2-b->map->h/2;  b->vx = ((rand()%2)?1:-1)*(rand()/(float)RAND_MAX+1.3);  b->vy = rand()/(float)RAND_MAX*2.0-1.0; }int main(int argc, char *argv[]) {  srand(time(0));  allegro_init();  set_color_depth(32);  set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0);  BITMAP *Buffer = create_bitmap(SCREEN_W, SCREEN_H);  install_keyboard();    struct entity Ball[BALLS], Player1, Player2;  int Player1Score = 0, Player2Score = 0;    int i;    for(i = 0; i < BALLS; ++i)   {    Ball[i].map = create_bitmap(17, 17);    clear_to_color(Ball[i].map, MASK_COLOR_32);    circlefill(Ball[i].map, 8, 8, 8, makecol(128+rand()%127, 128+rand()%127, 128+rand()%127));    ResetBall(Ball+i);   }    Player1.map = create_bitmap(16, 64);  clear_to_color(Player1.map, makecol(255, 0, 0));  rectfill(Player1.map, 0, 8, 8, 56, MASK_COLOR_32);  Player1.PosX = 0;  Player1.PosY = SCREEN_H/2-16;  Player1.vx = Player1.vy = 0;    Player2.map = create_bitmap(16, 64);  clear_to_color(Player2.map, makecol(0, 0, 255));  rectfill(Player2.map, 8, 8, 16, 56, MASK_COLOR_32);  Player2.PosX = SCREEN_W-16;  Player2.PosY = SCREEN_H/2-16;  Player2.vx = Player2.vy = 0;    while(!key[KEY_ESC])   {    Update(&Player1, 1);    Update(&Player2, 1);        for(i = 0; i < BALLS; ++i)     {      Update(Ball+i, 0);            if(Ball[i].vx < 0 && Ball[i].PosX < Player1.PosX+Player1.map->w)       {        if(Ball[i].PosY >= Player1.PosY - Ball[i].map->h && Ball[i].PosY <= Player1.PosY + Player1.map->h)         {          Ball[i].vx *= -1;          Ball[i].vy += Player2.vy;         }        else         {          ResetBall(Ball+i);          ++Player2Score;         }       }              // Player 2      if(Ball[i].vx > 0 && Ball[i].PosX + Ball[i].map->w > Player2.PosX)       {        if(Ball[i].PosY >= Player2.PosY - Ball[i].map->h && Ball[i].PosY <= Player2.PosY + Player2.map->h)         {          Ball[i].vx *= -1;          Ball[i].vy += Player2.vy;         }        else         {          ResetBall(Ball+i);          ++Player1Score;         }       }     }        if(key[KEY_W])     Player1.vy -= 0.17;        if(key[KEY_S])     Player1.vy += 0.17;        if(key[KEY_8_PAD])     Player2.vy -= 0.17;        if(key[KEY_5_PAD])     Player2.vy += 0.17;        vsync();    clear(Buffer);    masked_blit(Player1.map, Buffer, 0, 0, Player1.PosX, Player1.PosY, Player1.map->w, Player1.map->h);    masked_blit(Player2.map, Buffer, 0, 0, Player2.PosX, Player2.PosY, Player2.map->w, Player2.map->h);        for(i = 0; i < BALLS; ++i)     masked_blit(Ball[i].map, Buffer, 0, 0, Ball[i].PosX, Ball[i].PosY, Ball[i].map->w, Ball[i].map->h);        textprintf(Buffer, font, 8, 8, makecol(255,255,255), "Player 1 Score: %d", Player1Score);    textprintf(Buffer, font, 174, 8, makecol(255,255,255), "Player 2 Score: %d", Player2Score);    blit(Buffer,screen,0,0,0,0,SCREEN_W, SCREEN_H);   }    allegro_exit(); } END_OF_MAIN();

##### Share on other sites
I added AI just for no apparent reason.

#include <allegro.h>#include <math.h>#include <time.h>#include <stdlib.h>struct entity {  float PosX, PosY, vx, vy;  BITMAP *map; };void Update(struct entity *e, int friction) {  if(friction)   {    if(e->PosY < 0)     e->vy = fabs(e->vy)*0.7;    else if(e->PosY + e->map->h >= SCREEN_H)     e->vy = -fabs(e->vy)*0.7;        e->PosX += (e->vx *= 0.99);    e->PosY += (e->vy *= 0.99);   }  else   {    if(e->PosY < 0)     e->vy = fabs(e->vy);    else if(e->PosY + e->map->h >= SCREEN_H)     e->vy = -fabs(e->vy);        e->PosX += e->vx;    e->PosY += e->vy;   } }void ResetBall(struct entity *b) {  if(rand()%2)   {    b->vx = rand()/(float)RAND_MAX+4.3;    b->PosX = 0;   }  else   {    b->vx = -rand()/(float)RAND_MAX-4.3;    b->PosX = SCREEN_W-b->map->w;   }    b->vy = rand()/(float)RAND_MAX*4.0-2.0;  b->PosY = SCREEN_H/2-b->map->h/2; }int main(int argc, char *argv[]) {  srand(time(0));  allegro_init();  set_color_depth(32);  set_gfx_mode(GFX_AUTODETECT, 320, 240, 0, 0);  BITMAP *Buffer = create_bitmap(SCREEN_W, SCREEN_H);  install_keyboard();    struct entity Ball, Player1, Player2;  int Player1Score = 0, Player2Score = 0;  int Player1Computer = 1, Player2Computer = 1;    Ball.map = create_bitmap(9, 9);  clear_to_color(Ball.map, MASK_COLOR_32);  circlefill(Ball.map, 4, 4, 4, makecol(255, 255, 255));  ResetBall(&Ball);    Player1.map = create_bitmap(16, 64);  clear_to_color(Player1.map, makecol(255, 0, 0));  rectfill(Player1.map, 0, 8, 8, 56, MASK_COLOR_32);  Player1.PosX = 0;  Player1.PosY = SCREEN_H/2-16;  Player1.vx = Player1.vy = 0;    Player2.map = create_bitmap(16, 64);  clear_to_color(Player2.map, makecol(0, 0, 255));  rectfill(Player2.map, 8, 8, 16, 56, MASK_COLOR_32);  Player2.PosX = SCREEN_W-16;  Player2.PosY = SCREEN_H/2-16;  Player2.vx = Player2.vy = 0;    while(!key[KEY_ESC])   {    Update(&Ball, 0);    Update(&Player1, 1);    Update(&Player2, 1);        if(Ball.vx < 0 && Ball.PosX < Player1.PosX+Player1.map->w)     {      if(Ball.PosY >= Player1.PosY - Ball.map->h && Ball.PosY <= Player1.PosY + Player1.map->h)       {        Ball.vx *= -1;        Ball.vy += Player1.vy;       }      else       {        ResetBall(&Ball);        ++Player2Score;       }     }        if(Ball.vx > 0 && Ball.PosX + Ball.map->w > Player2.PosX)     {      if(Ball.PosY >= Player2.PosY - Ball.map->h && Ball.PosY <= Player2.PosY + Player2.map->h)       {        Ball.vx *= -1;        Ball.vy += Player2.vy;       }      else       {        ResetBall(&Ball);        ++Player1Score;       }     }        if(key[KEY_W])     {      Player1.vy -= 0.17;      Player1Computer = 0;     }        if(key[KEY_S])     {      Player1.vy += 0.17;      Player1Computer = 0;     }        if(key[KEY_8_PAD])     {      Player2.vy -= 0.17;      Player2Computer = 0;     }        if(key[KEY_5_PAD])     {      Player2.vy += 0.17;      Player2Computer = 0;     }        if(Ball.vx > 0)     {      if(Player2Computer)       {        float predicted_time = (SCREEN_W-Player2.map->w-Ball.map->w-Ball.PosX)/Ball.vx, predicted_y = Ball.PosY + Ball.vy*predicted_time;                while(predicted_y < 0 || predicted_y > SCREEN_H-Ball.map->h)         if(predicted_y < 0)          predicted_y = 1-predicted_y;         else          predicted_y = 2*(SCREEN_H-Ball.map->h)-predicted_y;                if(Player2.PosY + Player2.vy * predicted_time - Ball.map->h/2 + Player2.map->h/2 > predicted_y)         Player2.vy -= 0.17;        else         Player2.vy += 0.17;       }            if(Player1Computer)       {        if(Player1.vy < 1 && Player1.PosY < (SCREEN_H-Player1.map->h)/3)         Player1.vy += 0.17;        else if(Player1.vy > -1 && Player1.PosY > (SCREEN_H-Player1.map->h)*2/3)         Player1.vy -= 0.17;       }     }    else     {      if(Player1Computer)       {        float predicted_time = (Ball.PosX-Player2.map->w)/-Ball.vx, predicted_y = Ball.PosY + Ball.vy*predicted_time;                while(predicted_y < 0 || predicted_y > SCREEN_H-Ball.map->h)         if(predicted_y < 0)          predicted_y = 1-predicted_y;         else          predicted_y = 2*(SCREEN_H-Ball.map->h)-predicted_y;                        if(Player1.PosY + Player1.vy * predicted_time - Ball.map->h/2 + Player1.map->h/2 > predicted_y)         Player1.vy -= 0.17;        else         Player1.vy += 0.17;       }            if(Player2Computer)       {        if(Player2.vy < 1 && Player2.PosY < (SCREEN_H-Player2.map->h)/3)         Player2.vy += 0.17;        else if(Player2.vy > -1 && Player2.PosY > (SCREEN_H-Player2.map->h)*2/3)         Player2.vy -= 0.17;       }     }       masked_blit(Player1.map, Buffer, 0, 0, Player1.PosX, Player1.PosY, Player1.map->w, Player1.map->h);    masked_blit(Player2.map, Buffer, 0, 0, Player2.PosX, Player2.PosY, Player2.map->w, Player2.map->h);    masked_blit(Ball.map, Buffer, 0, 0, Ball.PosX, Ball.PosY, Ball.map->w, Ball.map->h);    textprintf(Buffer, font, 0, 0, makecol(255,255,255), "%s: %d", Player1Computer?"Computer":"Human", Player1Score);    textprintf_right(Buffer, font, SCREEN_W-1, 0, makecol(255,255,255), "%s: %d",  Player2Computer?"Computer":"Human", Player2Score);    vsync();    blit(Buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);    clear(Buffer);   }    allegro_exit(); } END_OF_MAIN();

1. 1
Rutin
41
2. 2
3. 3
4. 4
5. 5

• 18
• 20
• 14
• 14
• 9
• ### Forum Statistics

• Total Topics
633368
• Total Posts
3011536
• ### Who's Online (See full list)

There are no registered users currently online

×