python - 为什么 PyGame 在延迟或 sleep 之前没有在窗口中绘制?

标签 python pygame

我正在做一个乒乓球游戏。当任何一个得分达到 10 时,它应该在屏幕上显示一些文字,并说右边的玩家赢了或左边的玩家赢了。但是,在我的程序中,它不起作用。当它必须显示右边或左边玩家获胜的文本时,它不会显示它。但它适用于其他一切。这是代码:

# Importing libraries
import pygame
import random
import time

# Initializing PyGame
pygame.init()

# Setting a window name
pygame.display.set_caption("Ping Pong")

# Creating a font
pygame.font.init()
font = pygame.font.SysFont(None, 30)
pong_font = pygame.font.SysFont("comicsansms", 75)

# Set the height and width of the screen
window_width = 700
window_height = 500
size = [window_width, window_height]
game_win = pygame.display.set_mode(size)
game_win2 = pygame.display.set_mode(size)


# Creating a messaging system
def message(sentence, color, x, y, font_type, display):
    sentence = font_type.render(sentence, True, color)
    display.blit(sentence, [x, y])


# Creating colors
white = (225, 225, 225)
black = (0, 0, 0)
gray = (100, 100, 100)

# Setting up ball
ball_size = 25


class Ball:
    """
    Class to keep track of a ball's location and vector.
    """

    def __init__(self):
        self.x = 0
        self.y = 0
        self.change_x = 0
        self.change_y = 0


def make_ball():
    ball = Ball()
    # Starting position of the ball.
    ball.x = 350
    ball.y = 250

    # Speed and direction of rectangle
    ball.change_x = 5
    ball.change_y = 5

    return ball


def main():
    # Scores
    left_score = 0
    right_score = 0

    pygame.init()

    # Loop until the user clicks the close button.
    done = False

    ball_list = []

    ball = make_ball()
    ball_list.append(ball)

    # Right paddle coordinates
    y = 200
    y_change = 0
    x = 50
    # Left paddle coordinates
    y1 = 200
    y1_change = 0
    x1 = 650

    while not done:
        
        # --- Event Processing
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                done = True
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_w:
                    y_change = -7

                elif event.key == pygame.K_s:
                    y_change = 7

                elif event.key == pygame.K_UP:
                    y1_change = -7

                elif event.key == pygame.K_DOWN:
                    y1_change = 7

            elif event.type == pygame.KEYUP:
                y_change = 0
                y1_change = 0

        y += y_change
        y1 += y1_change

        # Preventing from letting the paddle go off screen
        if y > window_height - 100:
            y -= 10
        if y < 50:
            y += 10
        if y1 > window_height - 100:
            y1 -= 10
        if y1 < 50:
            y1 += 10

        # Logic
        for ball in ball_list:
            # Move the ball's center
            ball.x += ball.change_x
            ball.y += ball.change_y

            # Bounce the ball if needed
            if ball.y > 500 - ball_size or ball.y < ball_size:
                ball.change_y *= -1
            if ball.x > window_width - ball_size:
                ball.change_x *= -1
                left_score += 1
            if ball.x < ball_size:
                ball.change_x *= -1
                right_score += 1

            ball_rect = pygame.Rect(ball.x - ball_size, ball.y - ball_size, ball_size * 2, ball_size * 2)

            left_paddle_rect = pygame.Rect(x, y, 25, 75)
            if ball.change_x < 0 and ball_rect.colliderect(left_paddle_rect):
                ball.change_x = abs(ball.change_x)

            right_paddle_rect = pygame.Rect(x1, y1, 25, 75)
            if ball.change_x > 0 and ball_rect.colliderect(right_paddle_rect):
                ball.change_x = -abs(ball.change_x)
                            
            # Here is the where the messaging system doesn't work, I don't know why! It works fine for everything else
            if right_score == 10:
                message("RIGHT PLAYER HAS WON!!", white, 300, 200, font, game_win)
                time.sleep(5)
                pygame.quit()
                quit()
            elif left_score == 10:
                message("LEFT PLAYER HAS WON!!", white, 300, 200, font, game_win)
                time.sleep(5)
                pygame.quit()
                quit()
        # Drawing
        # Set the screen background
        game_win.fill(black)

        # Draw the balls
        for ball in ball_list:
            pygame.draw.circle(game_win, white, [ball.x, ball.y], ball_size)

        # Creating Scoreboard
        message("Left player score: " + str(left_score), white, 10, 10, font, game_win)
        message("Right player score: " + str(right_score), white, 490, 10, font, game_win)

        # Drawing a left paddle
        pygame.draw.rect(game_win, white, [x, y, 25, 100])
        # Drawing a right paddle
        pygame.draw.rect(game_win, white, [x1, y1, 25, 100])

        # Setting FPS
        FPS = pygame.time.Clock()
        FPS.tick(60)

        # Updating so actions take place
        pygame.display.flip()


while True:
    game_win2.fill(black)
    pygame.event.get()
    mouse = pygame.mouse.get_pos()
    click = pygame.mouse.get_pressed()
    message("Pong", white, 280, 100, pong_font, game_win2)
    if 150 + 100 > mouse[0] > 150 and 350 + 50 > mouse[1] > 350:
        pygame.draw.rect(game_win, gray, [150, 350, 100, 50])
        if click[0] == 1:
            break
    else:
        pygame.draw.rect(game_win, white, [150, 350, 100, 50])

    if 450 + 100 > mouse[0] > 450 and 350 + 50 > mouse[1] > 350:
        pygame.draw.rect(game_win, gray, [450, 350, 100, 50])
        if click[0] == 1:
            pygame.quit()
            quit()
    else:
        pygame.draw.rect(game_win, white, [450, 350, 100, 50])

    message("Start", black, 175, 367, font, game_win2)
    message("Quit", black, 475, 367, font, game_win2)

    # Go ahead and update the screen with what we've drawn.
    pygame.display.flip()

    # Wrap-up
    # Limit to 60 frames per second
    clock = pygame.time.Clock()
    clock.tick(60)

if __name__ == "__main__":
    main()
我添加了一点评论,它是:“# Here is the where the messaging system doesn't work, I don't know why! It works fine for everything else”。现在,当有人得分 10 分时,什么都没有发生。它=等待几秒钟。这样您就可以在程序关闭之前阅读“左玩家赢了”或“右玩家赢了”。但它根本没有出现!我不知道为什么!有人可以帮忙吗?

最佳答案

仅当 pygame.display.update() 出现时才更新显示。或 pygame.display.flip()
叫做。见 pygame.display.flip() :

This will update the contents of the entire display.


此外,您必须使用 pygame.event.pump() 处理事件, 在显示的更新在窗口中变得可见之前。
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.


如果要显示文本并延迟游戏,则必须更新显示并处理事件。
编写一个延迟游戏并更新显示的函数。我建议使用 pygame.time 实现延迟的模块(例如 pygame.time.delay() )
def update_and_wait(delay):
    pygame.display.flip()
    pygame.event.pump()
    pygame.time.delay(delay * 1000) # 1 second == 1000 milliseconds
甚至实现自己的事件循环以保持应用程序响应的功能。通过 pygame.time.get_ticks() 测量时间:
def update_and_wait(delay):
    start_time = pygame.time.get_ticks()
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                print("auit")
                pygame.quit()
                return False
        if pygame.time.get_ticks() >= start_time + delay * 1000: 
            break
    return True
在应用程序中使用函数:
def main():
    # [...]

    while not done:
        # [...]

        for ball in ball_list:
            # [...]

            if right_score == 0:
                message_wait("RIGHT PLAYER HAS WON!!", white, 300, 200, font, game_win)
                update_and_wait(5)
                quit()
            elif left_score == 0:
                message_wait("LEFT PLAYER HAS WON!!", white, 300, 200, font, game_win)
                update_and_wait(5)
                quit()

关于python - 为什么 PyGame 在延迟或 sleep 之前没有在窗口中绘制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63218889/

相关文章:

python - Sympy subs 不输出替换表达式?

python - Flask Wtform 调用 FieldList 和 FormField validate() 会导致错误

python - 使用来自不同文件 pygame 的 Sprite 对象类

python - 如何将一些对象分布到整个屏幕上

python - 为什么在 pygame 中屏幕上的位图文本后面有一个矩形?

python - 类型错误 : argument 1 must be pygame. 表面,而不是 pygame.Rect

python - 如何从 Pandas DateTime Index 中删除时间值?

python - 如何在 pandas/sql 中按分层数据分组?

python - Tensorflow:_variable_with_weight_decay(...) 解释

python - 将位图图像绘制到 Pygame 中