Thread: Allegro Pong Collision Problems

  1. #1
    Registered User
    Join Date
    Sep 2007
    Posts
    26

    Allegro Pong Collision Problems

    Hi

    I've been learning some 'Allegro' (a game programming library) for c++. i decided to compile what i'd learned and to try and make a pong clone called 'bat and ball'. ive run into a problem that i have been un-able to fix. when i run this code everything works as it should but the colision on the bat to ball doesn't work. please help:

    Code:
    #include <allegro.h>
    #include <cstdlib>
    
    int BallX = 100;
    int BallY = 100;
    
    int TempX = 100;
    int TempY = 100;
    
    int Dir = 1; //This will keep track of the circles direction
                //1= up and left, 2 = down and left, 3 = up and right, 4 = down and right
    
    int PlayerX = 300;
    int PlayerY = 400;            
    
    int TempPlayerX = 300;
    int TempPlayerY = 400;
    
    void MovePlayer(){
         
         TempPlayerX = PlayerX;
         TempPlayerY = PlayerY;
         
         if (key[KEY_LEFT] && PlayerX > 10) {
                           PlayerX = PlayerX - 5;
                            }
         else if (key[KEY_RIGHT] && PlayerX < 570) {
                                 PlayerX = PlayerX + 5;
                                 }
         acquire_screen();
         rectfill( screen, TempPlayerX, TempPlayerY, (TempPlayerX + 50), (TempPlayerY + 20), makecol ( 0, 0, 0));
         rectfill( screen, PlayerX, PlayerY, (PlayerX + 50), (PlayerY + 20), makecol ( 255, 255, 255));
         release_screen();
         
         }                        
         
    
    
    void MoveBall(){
    
        TempX = BallX;
        TempY = BallY;
        
        if (Dir == 1 && BallX != 10 && BallY != 20 && (BallX < PlayerX || BallX > PlayerX + 50)) {
         
            BallX = BallX - 1;
            BallY = BallY - 1;
                  
        } else if (Dir == 2 && BallX != 20 && BallY != 460) {
    
            BallX = BallX - 1;
            BallY = BallY + 1;
    
        } else if (Dir == 3 && BallX != 620 && BallY != 20)  { 
        
            BallX = BallX + 1;
            BallY = BallY - 1;
    
        } else if (Dir == 4 && BallX != 620 && BallY != 460) {
    
            BallX = BallX + 1;
            BallY = BallY + 1;
           
        } else if ((BallX > PlayerX || BallX < (PlayerX + 50)) && BallY == 395) { 
    
            BallY = BallY - 5;
            Dir = rand() % 4 + 1;
            
        }
        
        else {
        Dir = rand() % 4 + 1;
    }     
                 
        
        acquire_screen();
        circlefill ( screen, TempX, TempY, 5, makecol( 0, 0, 0));
        circlefill ( screen, BallX, BallY, 5, makecol( 255, 255, 255));
        release_screen();
        
        rest(10);
    
    }    
    
    int main(){
    
        allegro_init();
        install_keyboard();
        set_color_depth(16);
        set_gfx_mode( GFX_AUTODETECT, 640, 480, 0, 0);
        
        while( !key[KEY_ESC]){
         
            MoveBall();
            MovePlayer();
       
        }    
        
        return 0;
    
    }
    END_OF_MAIN();

  2. #2
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Collision is best done by ruling out all the false possibilities first. What remains must be true.

    To determine which side the object hit on you subtract the center of the two objects. If the x distance is greater than or equal to the stationary object's (the test object) width or bounding width then the hit was either on the left or right, else it was top or bottom.

  3. #3
    Registered User
    Join Date
    Sep 2007
    Posts
    26
    k howz this?

    Code:
    #include <allegro.h>
    #include <cstdlib>
    
    int BallX = 300;
    int BallY = 300;
    
    int TempX = 300;
    int TempY = 300;
    
    int Dir = 3; //This will keep track of the circles direction
                //1= up and left, 2 = down and left, 3 = up and right, 4 = down and right
    
    int PlayerX = 300;
    int PlayerY = 400;            
    
    int TempPlayerX = 300;
    int TempPlayerY = 400;
    
    void MovePlayer(){
         
         TempPlayerX = PlayerX;
         TempPlayerY = PlayerY;
         
         if (key[KEY_LEFT] && PlayerX > 10) {
                           PlayerX = PlayerX - 5;
                            }
         else if (key[KEY_RIGHT] && PlayerX < 570) {
                                 PlayerX = PlayerX + 5;
                                 }
         acquire_screen();
         rectfill( screen, TempPlayerX, TempPlayerY, (TempPlayerX + 50), (TempPlayerY + 20), makecol ( 0, 0, 0));
         rectfill( screen, PlayerX, PlayerY, (PlayerX + 50), (PlayerY + 20), makecol ( 255, 255, 255));
         release_screen();
         
         }                        
         
    
    
    void MoveBall(){
    
        TempX = BallX;
        TempY = BallY;
                            
                                                                                                                      
        if (Dir == 1 && BallX != 10 && BallY != 20) {
         
            BallX = BallX - 1;
            BallY = BallY - 1;
                  
        } else if (Dir == 2 && BallX != 20 && BallY != 460) {
    
            BallX = BallX - 1;
            BallY = BallY + 1;
    
        } else if (Dir == 3 && BallX != 620 && BallY != 20)  { 
        
            BallX = BallX + 1;
            BallY = BallY - 1;
    
        } else if (Dir == 4 && BallX != 620 && BallY != 460) {
    
            BallX = BallX + 1;
            BallY = BallY + 1;
           
        } else if ((BallX < PlayerX || BallX > (PlayerX + 50)) && BallY != 395) {
                   
                   if (Dir == 1) {
                           
                           BallX = BallX - 1;
                           BallY = BallY - 1;
                           
                           } else if (Dir == 2) {
                           
                           BallX = BallX - 1;
                           BallY = BallY + 1;
                           
                           } else if (Dir == 3) {
                           
                           BallX = BallX + 1;
                           BallY = BallY - 1;
                           
                           } else if (Dir == 4) {
                           
                           BallX = BallX + 1;
                           BallY = BallY + 1;
                           
                           }
    
        
        } else {
        Dir = rand() % 4 + 1;
    }     
                 
        
        acquire_screen();
        circlefill ( screen, TempX, TempY, 5, makecol( 0, 0, 0));
        circlefill ( screen, BallX, BallY, 5, makecol( 255, 255, 255));
        release_screen();
        
        rest(10);
    
    }    
    
    int main(){
    
        allegro_init();
        install_keyboard();
        set_color_depth(16);
        set_gfx_mode( GFX_AUTODETECT, 640, 480, 0, 0);
        
        while( !key[KEY_ESC]){
         
            MoveBall();
            MovePlayer();
       
        }    
        
        return 0;
    
    }
    END_OF_MAIN();
    now the ball isnt recognising any collision

  4. #4
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Code:
    bool Sprite::Collide(float left,float top,float right,float bottom)
    {
        float SrcLeft   = m_vecPos.x + m_vecMin.x;
        float SrcRight  = m_vecPos.x + m_vecMax.x;
        float SrcTop    = m_vecPos.y + m_vecMin.y;
        float SrcBottom = m_vecPos.y + m_vecMax.y;
    
        if (SrcRight < left) return false;
        if (SrcLeft > right) return false;
        if (SrcBottom > top) return false;
        if (SrcTop < bottom) return false;
       
        return true;
    }
    This code assumes that m_vecPos is a 3D vector and m_vecMin and m_vecMax are two 3D vectors describing the min and max values of the bounding volume for the Sprite.

  5. #5
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Code:
    Dir = rand() &#37; 4 + 1;
    Is this the collision response? Two directions out of four will always make the ball move in an unwanted direction...

    It might be simpler to represent Dir as the X and Y component of the ball's movement instead (see code below).

    Then you'll need to detect collisions with the edges of the screen and reverse movement direction. If we are colliding with the sides, reverse X component. If colliding with the top, reverse Y component. If colliding with the bottom, do something special (e.g substract from player's "lives" and reset the ball to the centre).

    Also check collision with the bat and reverse the ball's Y movement (make it go up). Below I only considered the top surface of the bat for collisions. You might also want to check collisions against other sides of the bat.

    Code:
    #include <allegro.h>
    #include <cstdlib>
    
    int BallX = 300;
    int BallY = 300;
    
    int BallMoveX = -1;
    int BallMoveY = -1;
    
    int PlayerX = 300;
    int PlayerY = 400;
    
    void MovePlayer(){
        //temporary local variables
        int TempPlayerX = PlayerX;
        int TempPlayerY = PlayerY;
    
        if (key[KEY_LEFT] && PlayerX > 10) {
            PlayerX = PlayerX - 5;
        }
        else if (key[KEY_RIGHT] && PlayerX < 570) {
            PlayerX = PlayerX + 5;
        }
    
        acquire_screen();
        rectfill( screen, TempPlayerX, TempPlayerY, 
            (TempPlayerX + 50), (TempPlayerY + 20), makecol ( 0, 0, 0));
        rectfill( screen, PlayerX, PlayerY, 
            (PlayerX + 50), (PlayerY + 20), makecol ( 255, 255, 255));
        release_screen();
    
    }
    
    void MoveBall(){
        //These variables are only used temporarily in this function
        int TempX = BallX;
        int TempY = BallY;
    
        //detect collisions with sides
        if (BallX <= 5 || BallX >= SCREEN_W - 5) {
            BallMoveX = -BallMoveX;
        }
        //detect collision with top
        if (BallY <= 5) {
            BallMoveY = 1;
        }
        //detect collision with pad
        else if ( BallY + 5 == PlayerY && BallX >= PlayerX && BallX <= PlayerX + 50) {
            BallMoveY = -1;
            //determine horizontal direction (which half of pad was hit?)
            BallMoveX = (BallX < PlayerX + 25 ? -1 : 1);
        }
        //detect collision with bottom
        else if (BallY >= SCREEN_H - 5) {
            //reset ball
            BallX = BallY = 300;
            BallMoveX = BallMoveY = -1;
        }                                                                                                            
        //move ball
        BallX += BallMoveX;
        BallY += BallMoveY;
    
        acquire_screen();
        circlefill ( screen, TempX, TempY, 5, makecol( 0, 0, 0));
        circlefill ( screen, BallX, BallY, 5, makecol( 255, 255, 255));
        release_screen();
    
        rest(10);
    
    }
    
    int main(){
    
        allegro_init();
        install_keyboard();
        set_color_depth(16);
        set_gfx_mode( GFX_AUTODETECT, 640, 480, 0, 0);
    
        while( !key[KEY_ESC]){
    
            MoveBall();
            MovePlayer();
    
        }
    
        return 0;
    
    }
    END_OF_MAIN() //<-- no semicolon here
    Other than that the graphics output is rather poor. It wouldn't flicker so much, if you used double buffering (and separated drawing from logic).

    You should also check out this to improve the general quality of your code: Magic numbers and Global variables (morale: try to avoid them).
    Last edited by anon; 12-30-2007 at 06:12 AM.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Pong Clone Collision Allegro
    By gillypie in forum C++ Programming
    Replies: 1
    Last Post: 12-29-2007, 02:42 AM
  2. installing and setting up Allegro
    By Emotions in forum Game Programming
    Replies: 11
    Last Post: 12-30-2004, 06:28 PM
  3. allegro installation problems on dev-c++
    By ichijoji in forum Game Programming
    Replies: 5
    Last Post: 09-14-2004, 10:57 AM
  4. bounding box collision detection
    By DavidP in forum Game Programming
    Replies: 7
    Last Post: 07-07-2002, 11:43 PM
  5. Replies: 4
    Last Post: 05-03-2002, 09:40 PM