Pygame help: Game text constantly stuck on screen

2019-09-17 03:56发布

问题:

I'm trying to make a simple submarine game in Pygame and I'm having problems displaying a piece of text called 'crashed' whenever the player hits the boundaries of the game window.

The text is supposed to appear on the screen as soon as the submarine collides with the game boundary ("You crashed!") - followed by a 2 second timer before respawning the submarine and clearing the text from the display.

The problem I'm having is that the 'crashed' text doesn't appear on the screen until the 2 second timer has ended (as the submarine respawns) - then the text is constantly stuck on the screen after respawning (i.e the text isn't resetting every time the submarine spawns)

I've got a function called 'crash' which contains the message and a separate function to handle the message display called 'message_display'. I'm following a tutorial on YouTube but unlike the project in the video I have a background image which the text overlaps, but I can't get it to display when the submarine first crashes or make it disappear when the sub respawns.

Here's my code in full:

**import pygame
import time
pygame.init()
display_width = 1280
display_height = 720
sound = pygame.mixer.Sound('YellowSubmarine.wav')
sound.play()
black = (0,0,0)
white = (255,255,255)
red = (255,0,0)
gameDisplay = pygame.display.set_mode((display_width,display_height))

bg = pygame.image.load("bg.jpg") <<<<<<<< THE BACKGROUND IMAGE

pygame.display.set_caption('The Amazing Yellow Submarine!')
clock = pygame.time.Clock()

SubImage = pygame.image.load('sub.png')<<<< <<<<< SUB IMAGE

SubImage = pygame.transform.scale(SubImage,(160,100)) <<< SCALE SUB IMAGE

def submarine(x,y): <<<<<<<<<< THE SUBMARINE OBJECT

    gameDisplay.blit(bg,(0,0)) <<<<<< BLITTING THE BACKGROUND IMAGE

    gameDisplay.blit(SubImage,(x,y)) <<<< BLITTING THE SUB IMAGE

def text_objects(text, font): <<<<< CREATING THE TEXT OBJECT 

    textSurface = font.render(text, True, white)

    return textSurface, textSurface.get_rect()

def message_display(text): <<<< DISPLAYING THE TEXT TO THE SCREEN

    largeText = pygame.font.Font('freesansbold.ttf',80)
    TextSurf, TextRect = text_objects(text, largeText)
    TextRect.center = ((display_width/2),(display_height/2))

    bg.blit(TextSurf, TextRect) <<< MAKING SURE THE TEXT OVERLAPS THE BACKROUND IMAGE

    time.sleep(2) <<<<< TWO SECOND TIMER 

    game_loop() <<<< RUN THE MAIN GAME LOOP


def crash():

    message_display('You Crashed!') <<<<< DISPLAYS THE CRASH MESSAGE

def game_loop(): <<<< RUNS UNLESS THE GAME IS QUIT

    x = (display_width * 0.02)
    y = (display_height * 0.4)
    y_change = 0
    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
                    y_change = 0
                if event.key == pygame.K_RIGHT:
                    x_change = 5               <<<<<< CONTROLS
                    y_change = 0
                if event.key == pygame.K_UP:
                    y_change = -2
                if event.key == pygame.K_DOWN:
                    y_change = 2                    
            if event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT: 
                    x_change = -1
                if event.key == pygame.K_RIGHT:
                    x_change = 1
                if event.key == pygame.K_DOWN:
                    y_change = 2
        x += x_change
        y += y_change

        submarine(x,y) 

        if x > 1125 or x < -25 or y > 650 or y < -25: <<<<<< IF BOUNDARY IS HIT

            crash() <<<<< RUNS CRASH FUNCTION (WHICH DISPLAYS THE MESSAGE)

            pygame.mixer.Sound.stop()

        clock.tick(60)
        pygame.display.update() <<<<<<<< UPDATING THE DISPLAY
game_loop()
pygame.quit()

quit()

回答1:

The text appears after two seconds because after blitting the text to the screen, you pause your game for two seconds before updating the screen:

bg.blit(TextSurf, TextRect) <<< MAKING SURE THE TEXT OVERLAPS THE BACKROUND IMAGE

time.sleep(2) <<<<< TWO SECOND TIMER 

game_loop() <<<< RUN THE MAIN GAME LOOP

So instead of blocking your entire game with time.sleep(2), you have to keep your main loop running.

You could use an event to trigger a state change of your game. To get an idea of how custom events work, take a look here and here.


Then the text never disappears because you blit the text to the Surface you use as your background surface, and you continue to blit this now altered Surface to the screen:

bg.blit(TextSurf, TextRect) <<< MAKING SURE THE TEXT OVERLAPS THE BACKROUND IMAGE

So instead of drawing the text to the background Surface, blit it to the screen Surface directly.


There are some other issues with your code but that's out of scope of this answer, but you should get the idea of how to solve your main issues.



标签: python pygame