我正在使用 Pygame 制作一个简单的游戏,您必须(通过将光标移到它们上面)获得屏幕上出现的所有圆圈(每秒都会出现更多圆圈)。代码比较长,所以我做了一个示例代码。这段代码工作正常,Pygame 窗口根本不会变得无响应:
import pygame, random, sys
pygame.init()
window=pygame.display.set_mode((480,360))
end_program=False
while not end_program:
for event in pygame.event.get():
if event.type==pygame.QUIT or pygame.key.get_pressed()[pygame.K_ESCAPE]: #If the user either click the "x", or pressed the "esc" key
end_program=True
pass
pygame.quit()
sys.exit()
但是,在我的游戏中,为了让用户可以选择再次玩游戏,我需要将 end_program
内的所有内容包装在另一个循环中。在所示示例中,这是 break_from_second_loop
:
import pygame, random, sys
pygame.init()
window=pygame.display.set_mode((480,360))
end_program=False
while not end_program:
for event in pygame.event.get():
if event.type==pygame.QUIT or pygame.key.get_pressed()[pygame.K_ESCAPE]: #If the user either click the "x", or pressed the "esc" key
end_program=True
break_from_second_loop=False
while not break_from_second_loop:
pass
pygame.quit()
sys.exit()
现在,如果运行此命令,窗口将变得无响应!有人知道为什么像将代码包装在另一个循环中(根本不改变代码)这样简单的事情会这样做吗?
最佳答案
问题是,如果您不运行事件循环,游戏将无法响应,或者根本无法执行任何操作。在另一个循环中,您没有运行事件循环。
这是基于事件循环的编程的一个普遍问题。您不能做任何需要很长时间的事情,也不能做任何必须跨多个事件运行的事情。
因此,您必须将循环分解为多个步骤,并且每次通过事件循环只执行一个步骤(或其中几个步骤)。
在这种特殊情况下,它实际上非常简单:只需将 while
更改为 if
(并将 has_got_all_circles=False
移到主循环),并且您的逻辑现在每次通过事件循环都运行一次。
或者,将其更改为 if
并也将其移至 for
内,因此现在每个事件只运行一次,而不是每个事件循环迭代一次。
第三种选择是将整个事情分解到一个函数中,并将其设置为空闲或计时器函数,该函数在事件循环空闲时运行,或者每帧运行一次,或者每 20 毫秒运行一次,等等。
很难知道这三个中的哪一个适合您的情况,但它们的基本思想都是相同的,所以我只展示第二个:
end_program=False
break_from_second_loop=False
while not end_program:
for event in pygame.event.get():
if event.type==pygame.QUIT or pygame.key.get_pressed()[pygame.K_ESCAPE]: #If the user either click the "x", or pressed the "esc" key
end_program=True
if not break_from_second_loop:
pass
This blog post更详细地解释了一般问题 - 尽管其中大部分内容并不真正适合这个特定问题。
关于python - 添加额外的循环会导致无响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19435732/