How to wait some time in pygame?

For animation / cooldowns, etc: If you want to 'wait', but still have code running you use: pygame.time.get_ticks

class Unit():
    def __init__(self):
        self.last = pygame.time.get_ticks()
        self.cooldown = 300    

    def fire(self):
        # fire gun, only if cooldown has been 0.3 seconds since last
        now = pygame.time.get_ticks()
        if now - self.last >= self.cooldown:
            self.last = now
            spawn_bullet()

For Python in general, you will want to look at the sleep library.

For Pygame, however, using pygame.time.delay() will pause for a given number of milliseconds based on the CPU clock for more accuracy (as opposed to pygame.time.wait).


If you just wait for some time, you can use pygame.time.wait or pygame.time.delay. However, if you want to display a message and then wait some time, you need to update the display beforehand. The display is updated only if either pygame.display.update() or pygame.display.flip() is called. See pygame.display.flip():

This will update the contents of the entire display.

Further you've to handles the events with pygame.event.pump(), before the update of the display becomes visible in the window. See pygame.event.pump():

For each frame of your game, you will need to make some sort of call to the event queue. This ensures your program can internally interact with the rest of the operating system.

This all means that you have to call pygame.display.flip() and pygame.event.pump() before pygame.time.delay() or pygame.time.wait():

screen.blit(text, (x, y))
pygame.display.flip()
pygame.event.pump()
pygame.time.delay(delay * 1000) # 1 second == 1000 milliseconds

See also Why doesn't PyGame draw in the window before the delay or sleep?


In any case, this is not the way to wait or delay something in a typical application. The game does not respond while you wait. Use pygame.time.get_ticks() to measure the time.
For instance if you want to show a message on the display, get the current time and calculate the point in time after that the message has to disappear. Display the message as long as the current time is below the calculated time:

message_end_time = 0
run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    # [...]

    current_time = pygame.time.get_ticks()
    if something_has_happened:
        message_surf = font.render('Important message!', True, (255, 0, 0))
        message_end_time = pygame.time.get_ticks() + 3000 # display for 3 seconds

    window.fill(0)

    # [...]

    if current_time < message_end_time:
        window.blit(message_surf, (x, y))
    pygame.display.flip()

See also How do I stop more than 1 bullet firing at once?


Minimal example: repl.it/@Rabbid76/PyGame-MessageDelay

import pygame

pygame.init()
font = pygame.font.SysFont(None, 50)
text = font.render('press key or mouse', True, (255, 0, 0))

window = pygame.display.set_mode((500, 200))
clock = pygame.time.Clock()
message_end_time = pygame.time.get_ticks() + 3000

run = True
while run:
    clock.tick(60)
    current_time = pygame.time.get_ticks()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        if event.type == pygame.KEYDOWN:
            text = font.render(pygame.key.name(event.key) + ' pressed', True, (255, 0, 0))
            message_end_time = pygame.time.get_ticks() + 2000
        if event.type == pygame.MOUSEBUTTONDOWN:
            text = font.render('button ' + str(event.button) + ' pressed', True, (255, 0, 0))
            message_end_time = pygame.time.get_ticks() + 2000

    window.fill(0)
    if current_time < message_end_time:
        window.blit(text, text.get_rect(center = window.get_rect().center))
    pygame.display.flip()

pygame.quit()
exit()