Pygame necesita “para el evento en pygame.event.get ()” para no bloquearse

El progtwig funciona bien así, pero no entiendo por qué necesita lo inútil for event in pygame.event.get(): None en gameOver mientras está dentro de game_loop . Si pudiera encontrar una forma de eliminarlo o explicar por qué no se ejecuta sin él, ¡sería genial!

 import pygame, time, random pygame.init() # SOUND/TEXTURES icon = pygame.image.load("textures\snakeicon.png") pygame.display.set_icon(icon) # VARIABLES white = (255, 255, 255) black = (0, 0, 0) red = (200, 0, 0) green = (0, 155, 0) bright_green = (0, 250, 0) bright_red = (255, 0, 0) font_size = 50 font = pygame.font.SysFont(None, font_size) # FUNCTIONS def text_objects(text, font): textSurface = font.render(text, True, black) return textSurface, textSurface.get_rect() def button(msg, x, y, w, h, ic, ac, action=None): mouse = pygame.mouse.get_pos() click = pygame.mouse.get_pressed() if x + w > mouse[0] > x and y + h > mouse[1] > y: pygame.draw.rect(gameWindow, ac, (x, y, w, h)) if click[0] == 1 and action != None: if action == "play": game_loop() elif action == "quit": gameRun = False gameWindow.fill(white) message_to_screen("Closing Game...", black, 280, 280) pygame.display.update() time.sleep(1) pygame.quit() quit() else: pygame.draw.rect(gameWindow, ic, (x, y, w, h)) smallText = pygame.font.Font("freesansbold.ttf", 20) textSurf, textRect = text_objects(msg, smallText) textRect.center = ((x + (w / 2)), (y + (h / 2))) gameWindow.blit(textSurf, textRect) def snake(rect_x, rect_y, block_size): pygame.draw.rect(gameWindow, green, [rect_x, rect_y, block_size, block_size]) def message_to_screen(msg, color, x, y): screen_text = font.render(msg, True, color) gameWindow.blit(screen_text, [x, y]) # WINDOW/SURFACE display_w = 800 display_h = 600 window_title = "Window" gameWindow = pygame.display.set_mode((display_w, display_h)) pygame.display.set_caption(window_title) # FPS/Clock clock = pygame.time.Clock() # Game Loop def game_loop(): # RECT OPTIONS moveSpeed = 10 block_size = 10 rect_x = display_w / 2 rect_y = display_h / 2 change_x = 0 change_y = 0 randApplex = round(random.randrange(0, display_w - block_size) / 10.0) * 10.0 randAppley = round(random.randrange(0, display_h - block_size) / 10.0) * 10.0 global gameRun, gameOver gameRun = True gameOver = False while gameRun: while gameOver: gameRun = False gameWindow.fill(white) # button(msg, x, y, w, h, ic, ac, action=None) message_to_screen("Game Over!", red, 300, 300) button("Restart", 150, 450, 100, 50, green, bright_green, "play") button("Quit", 550, 450, 100, 50, red, bright_red, "quit") pygame.display.update() # RIGHT HERE! for event in pygame.event.get(): None # RIGHT THERE! for event in pygame.event.get(): if event.type == pygame.QUIT: gameRun = False gameOver = False gameWindow.fill(white) message_to_screen("Closing Game...", black, 280, 280) pygame.display.update() time.sleep(1) pygame.quit() quit() if event.type == pygame.KEYDOWN: if event.key == pygame.K_w: change_y = -moveSpeed change_x = 0 elif event.key == pygame.K_s: change_y = moveSpeed change_x = 0 elif event.key == pygame.K_a: change_x = -moveSpeed change_y = 0 elif event.key == pygame.K_d: change_x = moveSpeed change_y = 0 # BOARDER CRASH if rect_x >= display_w or rect_x = display_h or rect_y < 0: gameOver = True # LOGIC rect_x += change_x rect_y += change_y if rect_x == randApplex and rect_y == randAppley: randApplex = round(random.randrange(0, display_w - block_size) / 10.0) * 10.0 randAppley = round(random.randrange(0, display_h - block_size) / 10.0) * 10.0 # RENDER gameWindow.fill(white) pygame.draw.rect(gameWindow, red, [randApplex, randAppley, block_size, block_size]) snake(rect_x, rect_y, block_size) pygame.display.update() clock.tick(15) message_to_screen("You Lose!", red, 325, 300) pygame.display.update() time.sleep(1) message_to_screen("Closing Game!", black, 280, 350) pygame.display.update() time.sleep(1) # QUIT pygame.quit() quit() game_loop() 

Básicamente, el sistema operativo espera que Pygame maneje eventos durante su progtwig. Si el sistema operativo nota que los eventos no se manejan, alertará al usuario. El progtwig realmente no se bloquea ni se congela, el sistema operativo solo está diciendo que su progtwig no responde (lo que ocurre porque no está respondiendo a ningún evento de usuario), pero aún funciona.

Cuando su juego ingresa a escenas pequeñas, puede pensar que no necesita manejar eventos, pero hay un evento que siempre debe buscar: el evento pygame.QUIT (se envía cuando el usuario presiona el botón de cerrar en la esquina superior) . En su ejemplo, no está permitiendo que el usuario salga durante la secuencia del juego (le está dando al jugador un botón para hacer clic, pero el usuario también esperaría que hacer clic en el botón de cerrar también cerraría el juego).

Otra razón es que la cola de eventos se está llenando constantemente. Por lo tanto, si el usuario enviara correo electrónico con varias teclas y presionara varias áreas con el mouse, no pasaría nada hasta que él / ella ingrese al juego nuevamente (donde tenga un bucle de eventos). Entonces todos los eventos serían ejecutados. Por lo tanto, es importante vaciar regularmente la cola. La cola se vacía cada vez que llamas pygame.event.get() o pygame.event.clear() .

La función pygame.event.pump() es la función que coloca todos los eventos en la cola de eventos (no borra los eventos anteriores, solo agrega). La cola de eventos no se llenará / actualizará con ningún evento si no se llama a la función. Sin embargo, la función se llama implícitamente dentro de las funciones pygame.event.get() , pygame.event.clear() , pygame.event.poll() , pygame.event.wait() y pygame.event.peek() , por lo que rara vez hay una razón para llamarlo explícitamente. Si está seguro de que no desea manejar eventos en algún momento, puede usar pygame.event.clear() para que la cola de eventos esté vacía cuando comience a procesar los eventos nuevamente. Si no desea manejar eventos, use pygame.event.pump() .

Cada proceso con una GUI necesita mantener un Message Pump (al menos en Windows es crítico)

La mayoría de las veces, su marco de GUI (QT, por ejemplo) mantendrá la bomba por usted y enviará eventos coincidentes para sus devoluciones de llamada (clics del ratón, teclado, etc.).

Supongo que pygame quiere darte un mejor control sobre cómo manejas los mensajes (si no me equivoco, los motores de juego querrían esperar y bombear todos los eventos con cada renderización de un solo fotogtwig).

Puedes reemplazarlo con pygame.event.pump() . La documentación explica por qué necesita llamar a esto o tiene que usar un bucle de eventos en cada fotogtwig.

Para cada cuadro de tu juego, necesitarás hacer algún tipo de llamada a la cola de eventos. Esto asegura que su progtwig pueda interactuar internamente con el rest del sistema operativo. Si no está utilizando otras funciones de eventos en su juego, debe llamar a pygame.event.pump () para permitir que pygame maneje acciones internas.

Esta función no es necesaria si su progtwig está procesando eventos en la cola a través del otro módulo pygame.eventpygame para interactuar con las funciones de eventos y colas.

Hay cosas importantes que deben tratarse internamente en la cola de eventos. La ventana principal puede necesitar ser repintada o responder al sistema. Si no hace una llamada a la cola de eventos por mucho tiempo, el sistema puede decidir que su progtwig se ha bloqueado.