Python Pygame曲面非顺序更新

Python Pygame曲面非顺序更新,python,python-3.x,pygame,Python,Python 3.x,Pygame,我正在尝试实现一个简单的Pygame脚本,它应该: 首先,检查用户何时按下空格键 在空格键上,显示一些文字;然后 暂停2秒钟,然后将屏幕更新为其原始状态 请注意,上述所有事件都必须按顺序发生,,不能无序 我遇到的问题是,程序首先暂停,然后显示文本,在屏幕更新到原始状态之前,文本仅显示一秒钟(或者根本不显示) 程序似乎跳过了步骤2,并在显示文本之前继续执行步骤3中的暂停。我的代码如下: import pygame import sys from pygame.locals import * WH

我正在尝试实现一个简单的Pygame脚本,它应该:

  • 首先,检查用户何时按下空格键
  • 在空格键上,显示一些文字;然后
  • 暂停2秒钟,然后将屏幕更新为其原始状态
  • 请注意,上述所有事件都必须按顺序发生,不能无序

    我遇到的问题是,程序首先暂停,然后显示文本,在屏幕更新到原始状态之前,文本仅显示一秒钟(或者根本不显示)

    程序似乎跳过了步骤2,并在显示文本之前继续执行步骤3中的暂停。我的代码如下:

    import pygame
    import sys
    from pygame.locals import *
    
    WHITE = (255, 255, 255)
    BLACK = (0, 0, 0)
    
    pygame.init()
    wS = pygame.display.set_mode((500, 500), 0, 32)
    
    
    # Method works as intended by itself
    def create_text(x, y, phrase, color):
        """
        Create and displays text onto the globally-defined `wS` Surface
        (params in docstring omitted)
        """
        # Assume that the font file exists and is successfully found
        font_obj = pygame.font.Font("./roboto_mono.ttf", 32)
        text_surface_obj = font_obj.render(phrase, True, color)
        text_rect_obj = text_surface_obj.get_rect()
        text_rect_obj.center = (x, y)
        wS.blit(text_surface_obj, text_rect_obj)
    
    
    while True:
        wS.fill(BLACK)
        for event in pygame.event.get():
            if event.type == KEYDOWN and event.key == K_SPACE:
    
                # Snippet containing unexpected behavior
                create_text(250, 250, "Hello world!", WHITE)
                pygame.display.update()
                pygame.time.delay(2000)
                # Snippet end
    
            if event.type == QUIT:
                pygame.quit()
                sys.exit(0)
        pygame.display.update()
    
    提前谢谢

    您应该尝试以下方法:

    import pygame
    import sys
    from pygame.locals import *
    
    WHITE = (255, 255, 255)
    BLACK = (0, 0, 0)
    
    pygame.init()
    wS = pygame.display.set_mode((500, 500), 0, 32)
    clock = pygame.time.Clock()
    
    showing = False
    timer = 0
    # Method works as intended by itself
    def create_text(x, y, phrase, color):
        """
        Create and displays text onto the globally-defined `wS` Surface
        (params in docstring omitted)
        """
        # Assume that the font file exists and is successfully found
        font_obj = pygame.font.Font("./roboto_mono.ttf", 32)
        text_surface_obj = font_obj.render(phrase, True, color)
        text_rect_obj = text_surface_obj.get_rect()
        text_rect_obj.center = (x, y)
        wS.blit(text_surface_obj, text_rect_obj)
    
    
    while True:
        wS.fill(BLACK)
        for event in pygame.event.get():
            if event.type == KEYDOWN and event.key == K_SPACE:
                showing = True
                timer = 0
    
            if event.type == QUIT:
                pygame.quit()
                sys.exit(0)
    
        if showing:
            timer += 1
            create_text(250, 250, "Hello world!", WHITE)
    
        if timer == 20:
            timer = 0
            showing = False
    
        pygame.display.update()
        clock.tick(100)
    

    每次按空格键时,它都会显示文本2秒钟,先显示2000毫秒,然后不显示。

    出于某种原因,该程序对我有效,我唯一更改的是字体。这与@Omega0x013的操作相同,但您有一个无限制的帧速率。它之所以有效是因为
    FPS.tick()

    import pygame
    import sys
    from pygame.locals import *
    displayText = False
    WHITE = (255, 255, 255)
    BLACK = (0, 0, 0)
    
    pygame.init()
    wS = pygame.display.set_mode((500, 500), 0, 32)
    
    
    # Method works as intended by itself
    def create_text(x, y, phrase, color):
        """
        Create and displays text onto the globally-defined `wS` Surface
        (params in docstring omitted)
        """
        # Assume that the font file exists and is successfully found
    
        font_obj = pygame.font.Font(None,30)
        text_surface_obj = font_obj.render(phrase, True, color)
        text_rect_obj = text_surface_obj.get_rect()
        text_rect_obj.center = (x, y)
        wS.blit(text_surface_obj, text_rect_obj)
    
    FPS = pygame.time.Clock()
    while True:
        wS.fill(BLACK)
        for event in pygame.event.get():
            if event.type == KEYDOWN and event.key == K_SPACE:
                totalTime = 0
                FPS.tick()
                displayText = True
    
            if event.type == QUIT:
                pygame.quit()
                sys.exit(0)
        if displayText:
            totalTime += FPS.tick()
            create_text(250, 250, "Hello world!", WHITE)
            if totalTime >= 2000:
                displayText = False
        pygame.display.update()
    

    尝试删除
    pygame.time.delay(2000)
    下的两行。看起来它们是不必要的,可能会导致问题。@skrx一旦我删除了
    delay()
    方法调用下面的两行,我就会看到
    Hello World文本被显示;然而,它只显示一瞬间(一帧?),而不是预期的2秒。这很奇怪。在
    延迟
    调用后,应停止程序的执行。顺便说一句,我一开始很难复制这个bug。我想我曾经在很短的时间内看过一次,但再也无法重现。也许重新构造程序并使用其中一个会更好。缩进有点偏,您可能需要修复它。另外,我知道问题中没有具体说明这一点,但是
    pygame.Clock.tick()
    的缺点是帧速率有限。我更倾向于不涉及此类限制的解决方案。如果我将最后2个
    if
    子句取消为与
    for event
    循环相同的级别,则此解决方案有效;我对你的答案投了赞成票。但我也在寻找一个更优雅的解决方案,它不依赖于pygame.Clock.tick()
    。我同意pygame.Clock.tick()@Jerrybibibo有一些限制,但它使所需的时间保持不变,精确到两秒钟。哇,这个解决方案非常适合我的使用。谢谢(另外,如果从事件循环中删除了
    FPS.tick()
    调用,这不是很正常吗?)FPS.tick()返回自上次调用以来的时间量。如果我按空格键,5秒后我再次按空格键并调用FPS.tick(),它将返回5秒,这意味着屏幕将立即变黑,因为它将保持在事件循环中,每当我按空格键时,时间都会重置。