一段时间不刷新时,Pygame 窗口没有响应 [英] Pygame window not responding when not refreshing for some time
问题描述
我正在尝试使用我制作的游戏"进行一些强化学习.
I'm trying to do some reinforcement learning with a "game" I made.
在我的主循环中,当我只是玩游戏时,如果窗口定期刷新,一切都会正常.
In my main loop, when I just play my game everything works fine if the window is refreshed regularly.
然而,在一集之后,我想训练我的代理,但如果训练时间太长,pygame 窗口只显示控制栏"(带有 X 的栏用于关闭窗口),如果我尝试关闭它,程序就会崩溃.
However, after an episode, I would like to train my agent, but if the training takes too long, the pygame window then only shows the "control bar" (the bar with the X for closing the window) and if I try to close it, the program simply crashes.
有什么简单的方法可以解决吗?其他解决方案告诉我应该定期调用一些 pygame 函数,但是如果我不得不暂停我的训练只是为了不时地执行它,代码会变得有点混乱.
Is there a simple way I can deal with it? Other solutions tell me I should call some pygame function regularly, but if I have to suspend my training just to do it from time to time, the code would become a bit messy.
推荐答案
是的,你必须定期调用pygame.event.get
;否则事件队列将填满,您的窗口将停止响应.
Yes, you have to call pygame.event.get
regularly; otherwise the event queue will fill up and your window will stop responsing.
如果您必须在游戏中运行长时间运行的任务,您有以下选择:
If you have to run a long running task in your game, you have the following options:
如果您的长时间运行的任务可以分解为更小、更快速的步骤,您可以使用协程使用 yield 将控制权交还给您的主循环:
If your long running task can be broken up into smaller, fast steps, you can use a cooroutine to give the control back your main loop using 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()
这可能对您有用,也可能不起作用,但是当您有一个计算结果的算法并且您想在该算法的步骤之间绘制屏幕时,这是一个不错的解决方案.
This may or may not work you, but it's a nice solution when you have an algorithm that calculates a result and you want to draw your screen in between steps of that algorithm.
Python 使得在另一个进程中运行一个函数变得非常容易.这是一个使用 multiprocessing
包的简单示例.
Python makes it quite easy to run a function in another process. Here's a simple example using the multiprocessing
package.
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()
这篇关于一段时间不刷新时,Pygame 窗口没有响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!