2

I have this function for a death screen of a game that I am creating.

def deathScreen():
    deathScreen = True
    while deathScreen == True:
        screen.fill(black)
        for event in pg.event.get():
            if event.type == pg.QUIT:
                quitGame()
        deadText = titleFont.render("You Died!", True, white)
        screen.blit(deadText, (155,200))
        time.sleep(5)
        screen.fill(black)


        pg.display.flip()
        clock.tick(15)

I want this function to work by displaying the "deadText" variable, and then waiting 5 seconds before the screen is cleared and another piece of text to be displayed where the user will be able to enter their name. The code was initially working by displaying the "deadText" variable however ever since I added the time sleep the program just crashes with no error message at all.

I would like to know how to get a 5 second delay and then clear the screen so U will be able to display new text.

Callum
  • 65
  • 1
  • 3
  • 9

3 Answers3

4

You should (almost) never pause the execution of your game with time.sleep or pygame.time.wait, since it's (almost) always the wrong thing to do.

What happens in your code is that you tell pygame to render the text onto the screen surface, and then wait some time.

screen.blit(deadText, (155,200))
time.sleep(5)

The first problem is that telling pygame to alter the screen surface does not actually change something on the screen. Any result will only be visible after you tell pygame to actually update the screen with pygame.display.flip (or pg.display.flip() in your case).


The second problem is that while the game is waiting (with e.g. time.sleep), everything stops. So if you wait 5 seconds, the user will not be able to e.g. close the window during this time, because events won't be processed. This may be OK for a simple scene that just displays some text, but you'll run into major headaches if you're not aware of this. You could either use pygame's event system (an example is here), use a timer to continually check the time or even count frames.

Another thing is that you probably should organize your different scenes into acutal scenes, maybe take a look here for an example.

sloth
  • 99,095
  • 21
  • 171
  • 219
  • I have a question. Why do we need to wait in the loop or make a delay or such thing? I mean; generally every next command execute only after the completion of the before command. Then why do we need to wait? – Vicrobot Sep 11 '18 at 17:08
2

Using sleep(5) or time.wait(5000) you can't close window in this time because it doesn't check events.

You can use pygame.time.get_ticks() to get current time and compare if it is delay to exit loop. And it doesn't stops loop.

def deathScreen():

    # you can render only once
    deadText = titleFont.render("You Died!", True, white)

    # you can display only once
    screen.fill(black)
    screen.blit(deadText, (155,200))
    pg.display.flip()

    # calculate exit time: 5000ms = 5s
    current_time = pygame.time.get_ticks()
    exit_time = current_time + 5000

    # - mainloop -

    deathScreen = True

    while deathScreen:

        for event in pg.event.get():
            if event.type == pg.QUIT:
                quitGame()

        current_time = pygame.time.get_ticks()

        if current_time >= exit_time:
            deathScreen = False

        clock.tick(5)

   # - after loop -

   screen.fill(black)
   pg.display.flip()

The same way you can do other things in game - ie. fire bullet every 2 seconds.


EDIT: working example

import pygame as pg

# --- constants --- (UPPER_CASE names)

WHITE = (255, 255, 255)
BLACK = (  0,   0,   0)

RED   = (255,   0,   0)
GREEN = (  0, 255,   0)
BLUE  = (  0,   0, 255)

# --- functions --- (lower_case names)

def message(text, delay=5000, foreground=WHITE, background=BLACK):

    image = font.render(text, True, foreground)
    rect = image.get_rect()
    rect.center = screen.get_rect().center

    screen.fill(background)
    screen.blit(image, rect)
    pg.display.flip()

    current_time = pg.time.get_ticks()
    exit_time = current_time + delay

    clock = pg.time.Clock()
    running = True

    while running:

        for event in pg.event.get():
            if event.type == pg.QUIT:
                pg.quit()
                quit()
            if event.type == pg.KEYDOWN:
                if event.key == pg.K_ESCAPE:
                    running = False

        current_time = pg.time.get_ticks()

        if current_time >= exit_time:
            running = False

        clock.tick(5)

# --- main --- (lower_case names)

pg.init()

screen = pg.display.set_mode((800, 600))
screen_rect = screen.get_rect()

font = pg.font.Font(None, 40)

message("Wait 2 seconds or press ESC", 2000, BLACK, RED)
message("You Died!", 2000)
message("Good Bye!", 2000, BLACK, GREEN)

pg.quit()
quit()
furas
  • 134,197
  • 12
  • 106
  • 148
1

Since you are using pygame you should use

pygame.time.wait(5000)

instead of

time.sleep(5)

Note that wait requires milliseconds instead of seconds!

koalo
  • 2,113
  • 20
  • 31
  • This no longer crashes my program but the first block of text is not displayed. – Callum Jan 31 '17 at 09:37
  • @Callum - That is a different issue for which you should ask a new question complete with what you have tried and researched, if this answer helped solve *this* issue, you should consider accepting it – Sayse Jan 31 '17 at 09:38
  • @Sayse actually, I asked how to get a 5 second delay after my first block of text is displayed and this solution no longer displays my first block of text. – Callum Jan 31 '17 at 09:40
  • @koalo I've figured it out, time.wait is in miliseconds, thank you. – Callum Jan 31 '17 at 09:52
  • what're the pros to use `pygame.time.wait()` instead of `time.sleep()`? – Hzzkygcs Apr 24 '20 at 11:55