1

So I'm following along with this tutorial

Below is the code I have so far

import pygame
import time

pygame.init()

display_width = 800
display_height = 600

black = (0, 0, 0)
white = (255, 255, 255)
red = (255, 0, 0)

car_width = 73

gameDisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('A bit Racey')
clock = pygame.time.Clock()

carImg = pygame.image.load('racecar.png')


def car(x, y):
    gameDisplay.blit(carImg, (x, y))


def text_objects(text, font):
    textSurface = font.render(text, True, black)
    return textSurface, textSurface.get_rect()


def message_display(text):
    largeText = pygame.font.Font('freesansbold.ttf', 115)
    TextSurf, TextRect = text_objects(text, largeText)
    TextRect.center = ((display_width / 2), (display_height / 2))
    gameDisplay.blit(TextSurf, TextRect)

    pygame.display.update()

    time.sleep(2)

    game_loop()


def crash():
    message_display('You Crashed')


def game_loop():
    x = (display_width * 0.45)
    y = (display_height * 0.8)

    x_change = 0

    gameExit = False

    while not gameExit:

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    x_change = -5
                if event.key == pygame.K_RIGHT:
                    x_change = 5

            if event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                    x_change = 0

        x += x_change

        gameDisplay.fill(white)
        car(x, y)

        if x > display_width - car_width or x < 0:
            crash()

        pygame.display.update()
        clock.tick(60)


game_loop()
pygame.quit()
quit()

Here's the bit that's giving me trouble:

def message_display(text):
    largeText = pygame.font.Font('freesansbold.ttf', 115)
    TextSurf, TextRect = text_objects(text, largeText)
    TextRect.center = ((display_width / 2), (display_height / 2))
    gameDisplay.blit(TextSurf, TextRect)

    pygame.display.update()

    time.sleep(2)

    game_loop()

By right, the 'You crashed!' message is supposed to display for 2 seconds when the car exceeds the boundaries of the screen, before restarting the game. However, the car waits for 2 seconds before the message comes up. So instead of the message being displayed for 2 seconds, the screen pauses for 2 seconds before the message comes up. The message flashes for only an instant before the game restarts. It almost seems like Python is running the time.sleep function before my pygame.display.update code.

What have I done wrong here? My time.sleep is clearly below my display update, hence shouldn't it be executed later?

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
koifish
  • 424
  • 1
  • 6
  • 16

3 Answers3

1

Maybe the message appears after the execution of game_loop(), there is a pygame.display.update() in that function too.

The sequence of API execution may be async.

Ali
  • 2,702
  • 3
  • 32
  • 54
张振羽
  • 24
  • 4
0

Your code did work as intended for me. But I can imagine it failing because of asynchrome executing. What you could do it the following to make sure the update is executed:

import threading

def update():
    pygame.display.update()

def message_display(text):
    largeText = pygame.font.Font('freesansbold.ttf', 115)
    TextSurf, TextRect = text_objects(text, largeText)
    TextRect.center = ((display_width / 2), (display_height / 2))
    gameDisplay.blit(TextSurf, TextRect)
    t = threading.Thread(target = update)
    t.start()

    time.sleep(2)
    game_loop()

Might be a bit of a workaround, and maybe not optimal, but it does work.

Stef van der Zon
  • 633
  • 4
  • 13
0

time.sleep gets interrupted by any signal received, which I would assume includes pygame telling the window to update. Try using pygame.time.delay instead. The function takes milliseconds, so the call would be

pygame.time.delay(2000)

Perhaps I'm wrong, as I have never used pygame, but calling game_loop at the end of the function must be incorrect, as you are calling crash from game_loop. Every crash that happens starts another game on top of the game already happening.

Matt Ellen
  • 11,268
  • 4
  • 68
  • 90