LinuxDevCenter.com

oreilly.comSafari Books Online.Conferences.

We've expanded our Linux news coverage and improved our search! Search for all things Linux across O'Reilly!

Search
Search Tips

advertisement

Listen Print Discuss Subscribe to Linux Subscribe to Newsletters

Retro Gaming Hacks, Part 3: Add a Ball and Score to Pong
Pages: 1, 2, 3, 4, 5, 6

Now, you need to initialize the score to 0-0, and the number of points for a win to GAME_POINTS:

  // Initialise game data
  game.running           = 1;
  game.ball_speed        = BALL_SPEED;
  game.slope_max_dy      = SLOPE_MAX_DY;
  game.p1_speed          = P1_SPEED;
  game.p2_speed          = P2_SPEED;
  game.num_rects         = 0;
  game.score.p1          = 0;
  game.score.p2          = 0;
  game.score.game_points = GAME_POINTS;

Right after initializing SDL in your code, add:

  // Initialise TTF engine and load a font
  TTF_Init();
  if ((game.font = TTF_OpenFont( MSG_FONT, MSG_SIZE )) == NULL) {

    fprintf( stderr, "Could not open font: %s\n", MSG_FONT );
    return cleanUp( 2 );
    
  } // if (could not load font)

This performs whatever initialization SDL_TTF requires, and then attempts to load the MSG_FONT font and scale it to the proper size. Calling TTF_Init() introduces a slight new wrinkle: you must tear down SDL_TTF before exiting the program. No problem; you can just add a line to the cleanUp() function:

int cleanUp( int err ) {

  TTF_Quit();
  SDL_Quit();

  return err;

} // cleanUp()

Now, all of the remaining action is set in the moveBall() function; specifically inside that else/if block that used to just reset the sprites and regenerate the slope. Let's add scorekeeping code to this block:

  // If the ball hits the left or right wall, score a point for the
  // appropriate player and return the ball to the centre
  else if (game->ball.x < 0 || game->ball.x > (SCREEN_WIDTH - game->ball.w)) {

    SDL_Color white = { 0xff, 0xff, 0xff, 0 };
      
    SDL_Rect rect_msg      = { SCREEN_WIDTH / 2 - 90, 100, 200, 50 };
    SDL_Rect rect_score_p1 = { 100,                   200, 150, 50 };
    SDL_Rect rect_score_p2 = { SCREEN_WIDTH - 200,    200, 150, 50 };

    SDL_Rect rects[3];
    
    char str_msg[32], str_score_p1[16], str_score_p2[16];
    SDL_Surface *text_msg, *text_score_p1, *text_score_p2;

    if (game->ball.x < 0)
      game->score.p2++;
    else if (game->ball.x > (SCREEN_WIDTH - game->ball.w))
      game->score.p1++;

    // Write scoring messages
    snprintf( str_msg, 32, "Player %d scores!", 
      ((game->ball.x < 0) ? 2 : 1) );

    snprintf( str_score_p1, 16, "Player 1: %d", game->score.p1 );
    snprintf( str_score_p2, 16, "Player 2: %d", game->score.p2 );

    text_msg      = TTF_RenderText_Solid( game->font, str_msg,      
        white );
    text_score_p1 = TTF_RenderText_Solid( game->font, str_score_p1, 
        white );
    text_score_p2 = TTF_RenderText_Solid( game->font, str_score_p2, 
        white );
    
    // Display scoring messages
    rects[0] = rect_msg;
    rects[1] = rect_score_p1;
    rects[2] = rect_score_p2;

    SDL_BlitSurface( text_msg,      NULL, game->screen, 
        &rect_msg      );
    SDL_BlitSurface( text_score_p1, NULL, game->screen, 
        &rect_score_p1 );
    SDL_BlitSurface( text_score_p2, NULL, game->screen, 
        &rect_score_p2 );

    SDL_UpdateRects( game->screen, 3, rects );

    // Display the score for awhile
    SDL_Delay( MSG_TIME );

    // Erase scoring messages
    SDL_FillRect( game->screen, &rect_msg,      game->black );
    SDL_FillRect( game->screen, &rect_score_p1, game->black );
    SDL_FillRect( game->screen, &rect_score_p2, game->black );
    
    SDL_UpdateRects( game->screen, 3, rects );

    // Has someone just won the game?
    if (game->score.p1 == game->score.game_points ||
        game->score.p2 == game->score.game_points) {

      // Display the final score
      snprintf( str_msg, 32, "Player %d wins!",
                ((game->ball.x < 0) ? 2 : 1) );

      snprintf( str_score_p1, 16, "Player 1: %d", game->score.p1 );
      snprintf( str_score_p2, 16, "Player 2: %d", game->score.p2 );

      text_msg      = TTF_RenderText_Solid( game->font, str_msg,      
        white );
      text_score_p1 = TTF_RenderText_Solid( game->font, str_score_p1, 
        white );
      text_score_p2 = TTF_RenderText_Solid( game->font, str_score_p2, 
        white );
    
      rects[0] = rect_msg;
      rects[1] = rect_score_p1;
      rects[2] = rect_score_p2;

      SDL_BlitSurface( text_msg,      NULL, game->screen, 
        &rect_msg      );
      SDL_BlitSurface( text_score_p1, NULL, game->screen, 
        &rect_score_p1 );
      SDL_BlitSurface( text_score_p2, NULL, game->screen, 
        &rect_score_p2 );

      SDL_UpdateRects( game->screen, 3, rects );

      // Pause for awhile
      SDL_Delay( MSG_TIME * 2 );

      // End the game
      game->running = 0;
      return;
      
    } // if (game over!)

The goal of all of this code is simply to display three messages at different locations on the screen. When a player scores, the game displays "Player X scores!" in the top center of the screen, and then each player's new score on his side of the screen. This is accomplished with the help of a slew of local variables: three SDL_Rect structures, one for each message (the in-line initialization may be new to some of you; the first field of the SDL_Rect structure is the x coordinate, followed by the y coordinate, followed by the width, followed by the height); a local array of SDL_Rect structures to feed to our old friend SDL_UpdateRects(); a string for each message; and finally, an SDL_Surface pointer for each.

Pages: 1, 2, 3, 4, 5, 6

Next Pagearrow




Tagged Articles

Be the first to post this article to del.icio.us

Sponsored Resources

  • Inside Lightroom
Advertisement

Sponsored by:

O'Reilly Media

©2009, O'Reilly Media, Inc.
(707) 827-7000 / (800) 998-9938
All trademarks and registered trademarks appearing on oreilly.com are the property of their respective owners.
About O'Reilly
Academic Solutions
Authors
Contacts
Customer Service
Jobs
Newsletters
O'Reilly Labs
Press Room
Privacy Policy
RSS Feeds
Terms of Service
User Groups
Writing for O'Reilly
Content Archive
Business Technology
Computer Technology
Google
Microsoft
Mobile
Network
Operating System
Digital Photography
Programming
Software
Web
Web Design
More O'Reilly Sites
O'Reilly Radar
Ignite
Tools of Change for Publishing
Digital Media
Inside iPhone
O'Reilly FYI
makezine.com
craftzine.com
hackszine.com
perl.com
xml.com

Partner Sites
InsideRIA
java.net
O'Reilly Insights on Forbes.com