   SDL Pong
  Below is my pong game, the bat on the right should always follow the ball up & down, but it makes jerky movements and mises half the time. When it does hit the ball the collision isn't detectedWhy do these things happen?(Sorry for posting such buggy/messy/full-of-memory-leaks code)//The headers#include "SDL/SDL.h"#include "SDL/SDL_image.h"#include "SDL/SDL_ttf.h"#include <string>#include <iostream>#include <sstream>//The screen sttributesconst int SCREEN_WIDTH = 640;const int SCREEN_HEIGHT = 480;const int SCREEN_BPP = 32;//The attributes of the dotconst int DOT_WIDTH = 20;const int DOT_HEIGHT = 20;const int DOT_VEL = 200;//The attributes of the playerconst int player_WIDTH = 34;const int player_HEIGHT = 135;const int player_VEL = 130;//The surfacesSDL_Surface *dot = NULL;SDL_Surface *pi = NULL;SDL_Surface *screen = NULL;//The event structureSDL_Event event;int cpus = 0;int players = 0;TTF_Font *font = NULL;//The color of the fontSDL_Color textColor = { 255, 255, 255 };//FunctionsSDL_Surface *load_image( std::string filename ){    //The image that's loaded    SDL_Surface* loadedImage = NULL;    //The optimized surface that will be used    SDL_Surface* optimizedImage = NULL;    //Load the image    loadedImage = IMG_Load( filename.c_str() );    //If the image loaded    if( loadedImage != NULL )    {   //Create an optimized surface   optimizedImage = SDL_DisplayFormat( loadedImage );   //Free the old surface   SDL_FreeSurface( loadedImage );   //If the surface was optimized   if( optimizedImage != NULL )   {  //Color key surface  SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, SDL_MapRGB( optimizedImage->format, 0, 0, 0) );   }    }    //Return the optimized surface    return optimizedImage;}void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL ){    //Holds offsets    SDL_Rect offset;    //Get offsets    offset.x = x;    offset.y = y;    //Blit    SDL_BlitSurface( source, clip, destination, &offset );}bool init(){    //Initialize all SDL subsystems    if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )    {   return false;    }    //Set up the screen    screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );    //If there was an error in setting up the screen    if( screen == NULL )    {   return false;    }   //Initialize SDL_ttf    if( TTF_Init() == -1 )    {   return false;    }   //Set the window caption    SDL_WM_SetCaption( "Pong", NULL );    //If everything initialized fine    return true;}bool load_files(){    //Load the dot image    dot = load_image( "data/ball.png" );    pi = load_image( "data/bat.png" );    //If there was a problem in loading the dot    if( dot == NULL )    {   return false;    }    font = TTF_OpenFont( "lazy.ttf", 72 );    //If everything loaded fine    return true;}bool check_collision( SDL_Rect A, SDL_Rect B ){    //The sides of the rectangles    int leftA, leftB;    int rightA, rightB;    int topA, topB;    int bottomA, bottomB;    //Calculate the sides of rect A    leftA = A.x;    rightA = A.x + A.w;    topA = A.y;    bottomA = A.y + A.h;    //Calculate the sides of rect B    leftB = B.x;    rightB = B.x + B.w;    topB = B.y;    bottomB = B.y + B.h;    //If any of the sides from A are outside of B    if( bottomA <= topB )    {   return false;    }    if( topA >= bottomB )    {   return false;    }    if( rightA <= leftB )    {   return false;    }    if( leftA >= rightB )    {   return false;    }    //If none of the sides from A are outside B    return true;}void clean_up(){    //Free the surface    SDL_FreeSurface( dot );   //Close the font    TTF_CloseFont( font );    //Quit SDL_ttf    TTF_Quit();    //Quit SDL    SDL_Quit();}//The dotclass Dot{    private:    //The X and Y offsets of the dot    float x, y;    //The velocity of the dot    float xVel, yVel;   //The direction 1=right,up 2=right,down 3=left,up 4=left,down    int dir;   public:    //Initializes the variables    Dot();    //Takes key presses and adjusts the dot's velocity    void handle_input();    //Moves the dot    void move( Uint32 deltaTicks, SDL_Rect b, SDL_Rect c );    //Shows the dot on the screen    void show();   SDL_Rect box; };//Playerclass Player{    private:    //The X and Y offsets of the player    float x, y;    //The velocity of the player    float xVel, yVel;   public:    //Initializes the variables    Player();    //Takes key presses and adjusts the player's velocity    void handle_input();   SDL_Rect box;//Moves the player    void move( Uint32 deltaTicks );    //Shows the player on the screen    void show();};//CPUclass CPU{    private:    //The X and Y offsets of the CPU    float x, y;    //The velocity of the CPU    float xVel, yVel; int heading;  public:    //Initializes the variables    CPU();    void handle_input(SDL_Rect b);   SDL_Rect box;//Moves the CPU    void move( Uint32 deltaTicks );    //Shows the CPU on the screen    void show();};//The timerclass Timer{    private:    //The clock time when the timer started    int startTicks;    //The ticks stored when the timer was paused    int pausedTicks;    //The timer status    bool paused;    bool started;    public:    //Initializes variables    Timer();    //The various clock actions    void start();    void stop();    void pause();    void unpause();    //Gets the timer's time    int get_ticks();    //Checks the status of the timer    bool is_started();    bool is_paused();};Dot::Dot(){    //Initialize the offsets    x = 0;    y = 0;    //Initialize the velocity    xVel = 0;    yVel = 0;   dir = 1;   box.x = x;    box.y = y;    box.w = DOT_WIDTH;    box.h = DOT_HEIGHT;}void Dot::handle_input(){}void Dot::move( Uint32 deltaTicks, SDL_Rect b, SDL_Rect c ){    //If the dot went too far to the left    if( x < 0 )    {   cpus++;   //Move back   x = SCREEN_WIDTH/2;   dir = 1;    }    //or the right    else if( x + DOT_WIDTH > SCREEN_WIDTH )    {   players++;   //Move back   x = SCREEN_WIDTH/2;   dir = 3;    }    //If the dot went too far up    if( y < 0 )    {   //Move back   y = 1;   dir += 1;    }    //or down    else if( y + DOT_HEIGHT > SCREEN_HEIGHT )    {   //Move back   y = SCREEN_HEIGHT - DOT_HEIGHT;   dir -= 1;    }   if (check_collision(box, b) || check_collision(box, c)){   if (dir == 1){  dir = 3;   }   if (dir == 2){  dir = 4;   }   if (dir == 3){  dir = 2;   }   if (dir == 4){  dir = 1;   }    }   if (dir == 1){   xVel = 200;   yVel = -200;    }    if (dir == 2){   xVel = 200;   yVel = 200;   }    if (dir == 3){   xVel = -200;   yVel = -200;    }    if (dir == 4){   xVel = -200;   yVel = 200;    }    //Move the dot    x += xVel * ( deltaTicks / 1000.f );    y += yVel * ( deltaTicks / 1000.f );    box.x = x;    box.y = y;    }void Dot::show(){    //Show the dot    apply_surface( (int)x, (int)y, dot, screen );}Player::Player(){    //Initialize the offsets    x = 10;    y = 10;    //Initialize the velocity    xVel = 0;    yVel = 0;   box.x = x;    box.y = y;    box.w = player_WIDTH;    box.h = player_HEIGHT;}void Player::handle_input(){    //If a key was pressed    if( event.type == SDL_KEYDOWN )    {   //Adjust the velocity   switch( event.key.keysym.sym )   {  case SDLK_UP: yVel -= player_VEL; break;  case SDLK_DOWN: yVel += player_VEL; break;   }    }    //If a key was released    else if( event.type == SDL_KEYUP )    {   //Adjust the velocity   switch( event.key.keysym.sym )   {  case SDLK_UP: yVel += player_VEL; break;  case SDLK_DOWN: yVel -= player_VEL; break;   }    }}void Player::move( Uint32 deltaTicks ){    //Move the dot left or right    x += xVel * ( deltaTicks / 1000.f );    //If the dot went too far to the left    if( x < 0 )    {   //Move back   x = 0;    }    //or the right    else if( x + player_WIDTH > SCREEN_WIDTH )    {   //Move back   x = SCREEN_WIDTH - player_WIDTH;    }    //Move the dot up or down    y += yVel * ( deltaTicks / 1000.f );    //If the dot went too far up    if( y < 0 )    {   //Move back   y = 0;    }    //or down    else if( y + player_HEIGHT > SCREEN_HEIGHT )    {   //Move back   y = SCREEN_HEIGHT - player_HEIGHT;    }    box.x = x;    box.y = y;  }void Player::show(){    //Show the dot    apply_surface( (int)x, (int)y, pi, screen );}CPU::CPU(){    //Initialize the offsets    x = SCREEN_WIDTH - 10;    y = 10;    //Initialize the velocity    xVel = 0;    yVel = player_VEL;   heading = 0;   box.x = x;    box.y = y;    box.w = player_WIDTH;    box.h = player_HEIGHT;}void CPU::handle_input(SDL_Rect b){    heading = b.y - y;    heading += player_HEIGHT/2;}void CPU::move( Uint32 deltaTicks ){    //Move the dot left or right    x += xVel * ( deltaTicks / 1000.f );    //If the dot went too far to the left    if( x < 0 )    {   //Move back   x = 0;    }    //or the right    else if( x + player_WIDTH > SCREEN_WIDTH )    {   //Move back   x = SCREEN_WIDTH - player_WIDTH;    }    //Move the dot up or down    float sec = deltaTicks / 1000.f;    int dis = yVel * ( deltaTicks / 1000.f );    int hed = heading / sec;    y += hed * dis;    //If the dot went too far up    if( y < 0 )    {   //Move back   y = 0;    }    //or down    else if( y + player_HEIGHT > SCREEN_HEIGHT )    {   //Move back   y = SCREEN_HEIGHT - player_HEIGHT;    }    box.x = x;    box.y = y;  }void CPU::show(){    //Show the dot    apply_surface( (int)x, (int)y, pi, screen );}Timer::Timer(){    //Initialize the variables    startTicks = 0;    pausedTicks = 0;    paused = false;    started = false;}void Timer::start(){    //Start the timer    started = true;    //Unpause the timer    paused = false;    //Get the current clock time    startTicks = SDL_GetTicks();}void Timer::stop(){    //Stop the timer    started = false;    //Unpause the timer    paused = false;}void Timer::pause(){    //If the timer is running and isn't already paused    if( ( started == true ) && ( paused == false ) )    {   //Pause the timer   paused = true;   //Calculate the paused ticks   pausedTicks = SDL_GetTicks() - startTicks;    }}void Timer::unpause(){    //If the timer is paused    if( paused == true )    {   //Unpause the timer   paused = false;   //Reset the starting ticks   startTicks = SDL_GetTicks() - pausedTicks;   //Reset the paused ticks   pausedTicks = 0;    }}int Timer::get_ticks(){    //If the timer is running    if( started == true )    {   //If the timer is paused   if( paused == true )   {  //Return the number of ticks when the timer was paused  return pausedTicks;   }   else   {  //Return the current time minus the start time  return SDL_GetTicks() - startTicks;   }    }    //If the timer isn't running    return 0;}bool Timer::is_started(){    return started;}bool Timer::is_paused(){    return paused;}int main( int argc, char* args[] ){   //Quit flag    bool quit = false;    //The dot that will be used    Dot myDot;   //The player    Player player;    //Keeps track of time since last rendering    Timer delta;   //The CPU    CPU cpu;    //Initialize    if( init() == false )    {   return 1;    }    //Load the files    if( load_files() == false )    {   return 1;    }    //Start delta timer    delta.start();    //While the user hasn't quit    while( quit == false )    {   //While there's events to handle   while( SDL_PollEvent( &event ) )   {  myDot.handle_input();  player.handle_input();  cpu.handle_input(myDot.box);  //If the user has Xed out the window  if( event.type == SDL_QUIT )  { //Quit the program quit = true;  }   }   //Move the dot   myDot.move(delta.get_ticks(), player.box, cpu.box);   player.move(delta.get_ticks());   cpu.move(delta.get_ticks());   //Restart delta timer   delta.start(); //Fill the screen white   SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0,0,0) );   //Show the dot on the screen   myDot.show();   player.show();   cpu.show(); //Update the screen   if( SDL_Flip( screen ) == -1 )   {  return 1;   }    }    //Clean up    clean_up();    return 0;}[When you switch from code tags to source tags, the forum breaks angle brackets in the source, showing HTML escape sequences in the resulting post. To fix this, just re-edit, making no changes. I've done this for you here - Zahlman]Thanks[Edited by - matio on September 1, 2009 11:03:09 AM]
  Why dont you do cpu x = 0;cpu y = 0;if(ball.y >= cpu.y)yVel += 9;if(ball.y <= cpu.y)yVel += -9and aslong as the ball yvel is greater than 9 then the paddle will miss the ball every now and again. Note that you might have to play around with the code above to get it to work I am trying to do it from memory.I could suggest that you do a different sort of idea for your collision detection. What I would do is every time the player misses the ball take one life off. So I would do if(ball.x = 0){cpu_lives -= 1}if(ball.x + 20 = SCREEN_WIDTH){Player_lives -= 1} thats how I did it but it is just a suggestion. Hope this helps   ;  Thanks, can anyone see any problem with the collision?   