Question

I'm trying to implement a very basic version of Pong using Allegro 4 and C++. I'm running into a problem however when I use the timing mechanism in conjunction with a rest() call. My game is set up for 2 players and a player wins a set once the player gets 7 points, and then both start over from 0. First player to win 2 sets wins. After a set is won, I display the name of the winner and call rest(2000) so that the players can see the message. However, after this, the ball seems to come out of nowhere and results in an automatic point for one of the players at the beginning of the set. After that, it resumes coming from the center as it's supposed to. This does not happen when I remove the timing mechanism or the rest() call.

I've tried moving the updation of the score and the sets outside the timing loop, but it doesn't work. Nor does calling the ball's init() function just after the rest() call. Would really appreciate some input as to how to fix the problem.

Here's the code. I've left out basic bits and the includes that don't affect the problem. //includes...

Paddle p1, p2;  //paddles for player 1, player 2
Ball b;   //game ball

int main()
{
    setupGame();   //setup allegro and bitmaps
    init();    //initialize paddles and ball

    bool done = false;
    int win, game = 0;

    //game loop
    while(!done)    
    {
     if(key[KEY_X])   //quick exit for debugging
        done = true;

     //timing loop
     while(counter > 0) {
         movePaddles();   
         moveAndCollideBall();
         game = checkCondition(b, p1, p2);  //check if either player 1 or player 2 has won a point
         updateScore(game);   //update score
         updateSets();        //update set if score of either equals 7

         counter --; 
     }

     draw();    //draw paddles and ball
     displayScore();   

     blit(buffer, screen, 0, 0, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);  //draw buffer to screen
     clear_bitmap(buffer);   //clear buffer for next iteration

     checkWinner(done);   //check if either player has won 2 sets, exit loop if so
    }
    exitGame();   //clear bitmaps and exit allegro
    return 0;
}
END_OF_MAIN()

//Returns 1 if player 1 has won a point, 2 for player 2
int checkCondition(Ball b, Paddle p1, Paddle p2)
{
  if(b.x < p1.x)
     return 2;
  else if(b.x > p2.x+PADDLE_WIDTH)
     return 1;
  return 0;
}

//setup allegro and timing variables, load bitmaps
void setupGame()
{
    //allegro, screen setup, etc.

    //timing mechanism
    LOCK_VARIABLE(counter);
    LOCK_FUNCTION(increment_counter);
    install_int_ex(increment_counter, BPS_TO_TIMER(240));

    srand(time(0));

    //other setup stuff
}

//initialize paddles and ball
void init()
{
    p1.init(10, 210);
    p2.init(620, 210);
    b.init();
}

//output score to buffer
void displayScore()
{
  textprintf_ex(buffer, gamefont, SCREEN_WIDTH/4, 10, WHITE, -1, "%i", p1.score);
  textprintf_ex(buffer, gamefont, SCREEN_WIDTH/2 - SCREEN_WIDTH/3, 450, WHITE, -1, "Sets: %i", p1.sets);
  textprintf_ex(buffer, gamefont, SCREEN_WIDTH/2 + SCREEN_WIDTH/4, 10, WHITE, -1, "%i", p2.score);
  textprintf_ex(buffer, gamefont, SCREEN_WIDTH/2 + SCREEN_WIDTH/6, 450, WHITE, -1, "Sets: %i", p2.sets);
}

 //taking the winner of the point as parameter, update the corresponding player's score by 1, reset ball
void updateScore(int game)
{
  if(game > 0)
    {game == 1 ? ++p1.score : ++p2.score;
     b.init();
     game = 0;
    }              
}


//update no of sets won if either player has score of 7, reset scores
void updateSets()
{
if(p1.score == 7 || p2.score == 7)
 {
   if(p1.score == 7)
      {p1.sets++;
       textprintf_ex(screen, gamefont, SCREEN_WIDTH/5, SCREEN_HEIGHT/2,WHITE, -1, "Player 1 wins the set!");
       }         
   else
      {p2.sets++;
       textprintf_ex(screen, gamefont, SCREEN_WIDTH/5, SCREEN_HEIGHT/2,WHITE, -1, "Player 2 wins the set!");

      }
   p2.score = 0;
   p1.score = 0;

   rest(2000);  //THIS SEEMS TO CAUSE THE PROBLEM, AFTER THE REST, THE BALL INSTEAD OF COMING FROM THE CENTER, QUICKLY COMES FROM SOMEWHERE CLOSE TO THE CORNER
  }   
}     

//check if either player has won 2 sets, if so set done to true
void checkWinner(bool& done)
{
if(p1.sets == 2)
  {textprintf_ex(screen, gamefont, SCREEN_WIDTH/4, SCREEN_HEIGHT/2 + 30,WHITE, -1, "Player 1 wins!!");
   rest(2000);
   done = true;
   }
else if(p2.sets == 2)
  {textprintf_ex(screen, gamefont, SCREEN_WIDTH/4, SCREEN_HEIGHT/2 + 30,WHITE, -1, "Player 2 wins!!");
   rest(2000);
   done = true;
  }
}
Was it helpful?

Solution

After rest(2000), reset the counter to 0. It is ticking away for two seconds during that rest, so after it's finished you'll get two seconds of a gameplay burst as it tries to catch up.

The proper fix is to have better organized code. The two second rest should really take place as part of your regular timing loop.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top