Controlling Your Game's Display Rate
In the previous lesson, I introduced the idea of using Python objects to represent the things in your game. In this lesson, I’ll talk about controlling the display rate of your game and how that interacts with the perception of speed. Up until now, you’ve been using an uncontrolled game loop that in each iteration calls
display.flip() to push the screen buffer surface to the display.
00:24 Each iteration of the loop will run as fast as your computer will allow. This can be a problem. It means your game will run at different speeds on different computers. That asteroid moving from left to right? If you’re not careful, it will move too fast for the player to react to, and the difficulty of your game will be based on the machine that is running it.
This problem is solved by using Pygame’s
Clock object, which will put an upper limit on the FPS of your program. To better demonstrate how FPS limits work, let’s step away from the game for a moment.
01:10 What this script will do is show a little red dot that moves from left to right and back again on the screen. You’ll be able to control the speed, represented by how many pixels it moves at a time, and the frame rate.
The variables here will be used to track where the dot is which direction it is moving—
1 for right,
-1 for left—the number of pixels to advance each time, and the frames per second limiter. Line 14 instantiates a Pygame
This event gets fired each time a key is pressed, but only once per press. Holding a key only triggers a single event. If there is a
KEYDOWN event, the next step is to check which key was pushed. For the right arrow, the speed will increase. For the left arrow, the speed will decrease, but never go below zero. For the up arrow, the frame rate will increase. And for the down arrow, the frame rate will decrease, never going below one frame per second.
With all those events taken care of, the next step is the game logic. Here, I’m calculating the little red dot’s new position based on the old position, the direction, and its speed. Next, so that the dot stays on the screen, I check if the newly-calculated position would be less than
0. If it is, that would be off the left side of the screen, so I set the new position to
0 and change the direction so the dot is moving to the right. Similarly, I next check if the dot has gone off the right-hand side of the screen. If so, I set its position to the right side of the screen and change the direction to the left. Scrolling the code down some more, and here you see the typical circle drawing code.
In most games, you’d just hard-code this value to
30. Because this is a frame rate demo, I’m passing in the current value of the FPS variable. Note that this is a maximum of the FPS. Setting the FPS to 10,000 won’t make that many frames happen.
You’re always limited by how fast each iteration of your game loop runs. What the
.tick() method does is slow things down if your game loop executes very quickly, enforcing a maximum frame rate.
06:39 A quick note here: You’re watching a video. Don’t act surprised, I can see you doing it. The video itself has a frame rate. Although I’ve cranked the frame rate of the game up to 60, the video’s own frame rate will limit what you can see.
06:53 This is why in older movies you would sometimes see strange patterns when they recorded CRT computer monitors or the spokes on a wheel. The frame rate of the movie recording interacts with the refresh rate of the monitor or the rotation rate of the wheel and creates odd visual effects.
Nothing earth-shattering here. Modify the
.__init__() method to create and store a Pygame
Clock. Scrolling all the way down. Then use the
.tick() method on the
clock object at the bottom of your
07:39 This will be the last thing to run in your game loop before the next iteration. I won’t bother demoing this at this point, there’s nothing new to see on the screen, but now your game will behave the same on computers of different speeds.
Become a Member to join the conversation.