How to make pygame update the display only upon an event?
Question:
I’m trying to do something like this.
pygame.event.set_allowed([pygame.KEYDOWN])
for event in pygame.event.get():
. . .
pygame.display.flip()
Since the game I’m making is static when there’s no input anyway, I’m trying to avoid re-rendering identical frames between inputs in every single while True
iteration. This code seems to be almost working, except there’s the slightest (disorienting) delay between input and result. If someone can help me mitigate this I want to go further and put much of the rest of the code within the for event in ...
block to optimise a bunch more by skipping iterating over the game state 2D list every loop since it’s static until there’s input. Thank you.
Answers:
To answer your title question:
while True:
for event in pygame.event.get():
if event.type == ...:
# game updates
# draw display
pygame.display.flip()
However, that is indeed slow as game updates and drawing displays are called on every for-event-loop iteration. Perhaps you may want to refactor it to:
while True:
for event in pygame.event.get():
if event.type == ...:
...
# game updates starts here
# for keyboard presses
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
...
# draw display
pygame.display.flip()
This way, the game update and drawing of display is called only once for every frame.
The usual way is to update the game in every frame and to limit the frames per second using pygame.time.Clock.tick
.
clock = pygame.time.Clock()
run = True
while run:
for event in pygame.event.get():
# handle events
# [...]
# clear background
# [...]
# draw scene
# [...]
# update the display
pygame.display.flip()
# limit frames per second
clock.tick(100)
If there is more than 1 event at once, your approach can update the game several times per frame. Sets a status variable when there was an event and updates the game once when the status is set:
run = True
while run:
redraw_scene = False
for event in pygame.event.get():
redraw_scene = True
# handle events
# [...]
if redraw_scene:
# clear background
# [...]
# draw scene
# [...]
# update the display
pygame.display.flip()
I’m trying to do something like this.
pygame.event.set_allowed([pygame.KEYDOWN])
for event in pygame.event.get():
. . .
pygame.display.flip()
Since the game I’m making is static when there’s no input anyway, I’m trying to avoid re-rendering identical frames between inputs in every single while True
iteration. This code seems to be almost working, except there’s the slightest (disorienting) delay between input and result. If someone can help me mitigate this I want to go further and put much of the rest of the code within the for event in ...
block to optimise a bunch more by skipping iterating over the game state 2D list every loop since it’s static until there’s input. Thank you.
To answer your title question:
while True:
for event in pygame.event.get():
if event.type == ...:
# game updates
# draw display
pygame.display.flip()
However, that is indeed slow as game updates and drawing displays are called on every for-event-loop iteration. Perhaps you may want to refactor it to:
while True:
for event in pygame.event.get():
if event.type == ...:
...
# game updates starts here
# for keyboard presses
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
...
# draw display
pygame.display.flip()
This way, the game update and drawing of display is called only once for every frame.
The usual way is to update the game in every frame and to limit the frames per second using pygame.time.Clock.tick
.
clock = pygame.time.Clock()
run = True
while run:
for event in pygame.event.get():
# handle events
# [...]
# clear background
# [...]
# draw scene
# [...]
# update the display
pygame.display.flip()
# limit frames per second
clock.tick(100)
If there is more than 1 event at once, your approach can update the game several times per frame. Sets a status variable when there was an event and updates the game once when the status is set:
run = True
while run:
redraw_scene = False
for event in pygame.event.get():
redraw_scene = True
# handle events
# [...]
if redraw_scene:
# clear background
# [...]
# draw scene
# [...]
# update the display
pygame.display.flip()