I’m working on a Tetris-clone type game and I’m wondering what would be the best way to handle the logic that moves the blocks down every N seconds. I initially did it the easy way:
pygame.time.set_timer(USEREVENT+1, 300)
This will of course add a PyGame event to the queue every 300 milliseconds. In the main loop I can test for this event, and drop the block down when it occurs. The problem with this approach is that the player can easily flood the queue with keyboard generated events. I noticed that player can essentially keep the block at the same height indefinitely by simply rapidly pressing the up-arrow which flips it around. It doesn’t seem to matter that the code testing for timer event is evaluated before the test for keyboard events. Somehow keyboard always gets higher priority than the timer. Any idea how to prevent this from happening?
And if this is unavoidable quirk of pygame.time what would be a better way to handle the timed events?
- Check elapsed time on each loop iteration and advance blocks if it is greater than a certain value?
- Use sched or something similar running in a separate thread and signaling back via some shared resource?
Any ideas?
Here’s how a typical game loop works:
A timer that is supposed to fire every 300 ms but doesn’t work if the user floods the game with events could be a broken timer. However, if you redraw the screen on every user event instead of redrawing the screen once you’ve processed all pending events, then your code is the problem.
Here’s an example of a broken version of a game loop:
It’s broken because it tries to redraw the screen far too often. If the player presses two keys at the same time, they’ll get separated into different frames, which is unnecessary.
The above loops assume that you want to draw to the screen as often as possible. This is very common, but you might want to draw to the screen less often. Your method of using events should be fine as long as you grab all pending events before redrawing the screen.
P.S. Do NOT use multiple threads to solve this problem. That would cause a huge mess.