Tracking the Score
April 27, 2008 — Jesse
The game is starting to look like the real thing now. I can finally show the correct score using the sprite sheet I created and the game automatically ends when someone scores ten points. It took me a while to find a nice way of positioning the sprite sheet source rectangle to the digit which is supposed to represent the score. At first, I just hard coded all the sprite sheet coordinates into an SDL_Rect array structure by matching a sprite on the sheet to an integer which represented the score. This method was not very elegant or effective so I dropped it and redesigned the sprite sheet so that all the images are about the same distance from each other. This allowed me to avoid the hard coding and simply add the distance to the next image on the sprite sheet.
This is a new sprite sheet. The digits have been altered to look more like a real video game. Each digit can be bounded in a rectangle that is 43 pixels wide. This makes it easier to track the score.
First thing I do is include my custom header files. I have one for the global constants and one for the sprite class and one more for the game class. After main () starts, a new game object called Pong is created on the heap. The start () class method takes care of all the details for initializing SDL and declares and initializes some SDL surfaces. Two integer variables called dx and dy are declared for holding the current ball movement changes. Two SDL rectangles are declared for cropping the sprite sheet to display the correct score. Each of these rectangles will hold the coordinates of the image showing the correct score. The sprite sheet is 61 pixels high so h will never change and each image can be bounded in a rectangle that is 43 pixels wide. The only coordinate that will therefore change throughout the game is the x-coordinate.
Next, I instantiate the sprite objects. Each one is initialized to the correct position on the screen. The sprite images are loaded from disk and then they are positioned on the screen. The class method Pong.update_game() refreshes the screen to display the new changes. An array of bools is used for emulating the keyboard; each array member is initialized to false since no key is yet depressed. The game loop then begins and will continue for as long as the Pong.game_running() method returns true. A new loop then begins to handle user events. The event queue will return true if there’s an event waiting. The switch statement handles the different events. Basically, I have handlers for depressing the keys and for closing the game window.
Next, the game logic is handled. When the paddle moves, I check that it never moves beyond the top or bottom of the game window. If the bounds are correct, then I pass the new changes to the move () method to move the paddles. Then I check that the ball never moves out of the game window either. If it hits the top or bottom of the screen, then it reflects by changing dx to its negative. To check collisions, I compare the bounding box of the ball with the bounding box of the paddle. These are obtained using the sprite get_rectangle () class method. If the detect_collision method returns true, then the ball will bounce off the paddle. Next I check if there was a score. If the ball went out of bounds on one of the sides of the screen, then a player scored. When either player scores, the ball is returned to the center of the screen and the object pong updates the score by calling score_point(). To prepare the new score, I move the x-coordinate of the SDL rectangle used on the sprite sheet by a distance of 43 pixels. This is because each digit can be bounded in a rectangle that is 43 pixels wide. When I do this, the SDL rectangle that is pointing to the new score image is ready to be passed to the draw() method.
Finally, the screen is cleared out to prepare for the next frame. All the sprites are repositioned using the draw() method to reflect the latest changes. The SDL_Delay function then caps the frame rate by delaying for 10 ms and then update_game() refreshes the screen. The game loop ends here and will repeat until a player gets a ten for their score. When that happens, the pong object will change the bool returned by the game_running () method to false. This causes the while loop to terminate. Then all the objects are deleted to restore the resources and the SDL_Quit() method is called.



