Да, вам нужно регулярно звонить pygame.event.get
; в противном случае очередь событий заполнится, и ваше окно перестанет отвечать.
Если вам нужно запустить долгосрочное задание в вашей игре, у вас есть следующие опции:
Ты сопрограмма
Если ваше долгосрочное задание можно разбить на более мелкие, быстрые шаги, вы можете использовать cooroutine, чтобы вернуть элемент управления вашему главному циклу, используя yield:
import pygame
import time
def long_running_task():
i = 0
while i < 300:
time.sleep(0.01)
print(i)
i += 1
yield i
def main():
pygame.init()
screen = pygame.display.set_mode((640, 480))
clock = pygame.time.Clock()
rect = pygame.Rect((10, 250, 32, 32))
direction = 1
generator = None
while True:
events = pygame.event.get()
for e in events:
if e.type == pygame.QUIT:
return
if e.type == pygame.KEYDOWN:
if e.key == pygame.K_SPACE:
generator = long_running_task()
screen.fill(pygame.Color('darkgrey'))
rect.move_ip(5 if direction else -5, 0)
pygame.draw.rect(screen, pygame.Color('dodgerblue'), rect)
if not screen.get_rect().contains(rect):
direction = not direction
if generator:
try: next(generator)
except StopIteration: generator = None
pygame.display.flip()
clock.tick(60)
if __name__ == '__main__':
main()
Это может работать, а может и не работать, но это хорошее решение, когда у вас есть алгоритм, который вычисляет результат, и вы хотите нарисовать экран между этапами этого алгоритма.
Запустите вашу задачу в другом потоке или процессе
Python позволяет довольно легко запускать функцию в другом процессе. Вот простой пример использования пакета multiprocessing
.
import pygame
import time
import multiprocessing
def long_running_task():
i = 0
while i < 50:
time.sleep(0.1)
print(i)
i += 1
return i
def main():
pygame.init()
screen = pygame.display.set_mode((640, 480))
clock = pygame.time.Clock()
rect = pygame.Rect((10, 250, 32, 32))
direction = 1
process = None
while True:
events = pygame.event.get()
for e in events:
if e.type == pygame.QUIT:
if process:
process.terminate()
process.join()
return
if e.type == pygame.KEYDOWN:
if e.key == pygame.K_SPACE:
process = multiprocessing.Process(target=long_running_task)
process.start()
screen.fill(pygame.Color('darkgrey'))
rect.move_ip(5 if direction else -5, 0)
pygame.draw.rect(screen, pygame.Color('dodgerblue'), rect)
if not screen.get_rect().contains(rect):
direction = not direction
pygame.display.flip()
clock.tick(60)
if __name__ == '__main__':
main()