PythonPygame赢了';不要退出

PythonPygame赢了';不要退出,python,pygame,exit,Python,Pygame,Exit,代码一个接一个地给一个像素上色,基本上就是打印一张图片。我不能让它退出,但如果我按X关闭或如果我按Esc。我已经将所有pg.event.get()代码放在主while循环之外、主while循环之内、次for循环之内、第三for循环之内。我用IDLE和Spyder运行过它,同样的问题,无论我把它放在哪里,我都无法让它退出。我怎样才能让它工作 loop = True while loop: #Event Management for exiting the screen for e

代码一个接一个地给一个像素上色,基本上就是打印一张图片。我不能让它退出,但如果我按X关闭或如果我按Esc。我已经将所有pg.event.get()代码放在主while循环之外、主while循环之内、次for循环之内、第三for循环之内。我用IDLE和Spyder运行过它,同样的问题,无论我把它放在哪里,我都无法让它退出。我怎样才能让它工作

loop = True
while loop:
    #Event Management for exiting the screen 
    for event in pg.event.get():
            keys = pg.key.get_pressed()
            if event.type == pg.QUIT:
                    loop = False
            elif keys[pg.K_ESCAPE]:
                    loop = False
    pg.event.pump()

    #Setup pixel transformation loop
    for i in range(0,463):
            for u in range (0,600):
                    screen.set_at((u,i),reddat[u,i]-greendat[u,i]-bluedat[u,i])
                    pg.display.flip()

    loop = False

您正在进行整个像素转换,而不检查事件。以下是伪代码中的流程:

loop until break:

    check events
    loop through pixels
        transform pixels
    break
相反,您应该放弃
while循环
,使
check\u for\u quit
成为一个函数,然后将该函数嵌套在转换循环中

def check_for_quit():
    """Event Management for exiting the screen"""

    for event in pg.event.get():
        keys = pg.key.get_pressed()
        if event.type == pg.QUIT:
            return True
        elif keys[pg.K_ESCAPE]:
            return True
    pg.event.pump()
    return False


def draw():
    """Setup pixel transformation loop"""

    for i in range(0,463):
        for u in range (0,600):
            if check_for_quit():
                return

            screen.set_at((u,i),reddat[u,i]-greendat[u,i]-bluedat[u,i])
            pg.display.flip()
不使用while循环,您可以让
check\u\u quit
return
True
False
来指示是否退出,然后您可以在每个循环中测试它,并在循环结束时提前退出
return


请注意,我不使用pygame,因此虽然这应该可以工作,但它可能不是在尝试检查事件时运行代码的最佳解决方案。

在像素转换循环期间,您没有运行任何东西来检测事件。你在正确的轨道上移动循环

如果将事件检查代码移入像素转换循环,则可以在生成像素时轮询事件

例如:

for i in range(0,463):
    for u in range (0,600):
        screen.set_at((u,i),reddat[u,i]-greendat[u,i]-bluedat[u,i])
        for event in pg.event.get():
            if event.type == pg.QUIT:
                break
            elif event.type == py.KEYDOWN:
                if event.key == py.K_SPACE:
                    break
        pg.display.flip()

这也消除了对while循环的需要。

首先,事件循环看起来很奇怪。我认为您应该在pg.event.get()中为event使用
keys=pg.key.get\u pressed()
,但不能同时使用两者

我不确定您是否只是想创建一个背景曲面或一个增强效果。此外,您还应该解释变量
reddat
等是什么

如果你只是想要一个背景图像,你只需要在主循环之前创建一个表面,在表面上点显像素,然后在主循环的屏幕上点显

如果需要构建,可以使用生成器获取像素,然后使用
itertools.islice
获取像素块。下面是一个构建的示例:

import sys
import pygame as pg
from itertools import islice


def generate_pixels(width, height):
    """Generate pixel coords for the build-up effect."""
    for i in range(height):
        for u in range(width):
            yield i, u


def main():
    clock = pg.time.Clock()
    width, height = (640, 480)
    screen = pg.display.set_mode((width, height))
    pixels = generate_pixels(width, height)
    done = False
    while not done:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                done = True
            if event.type == pg.KEYDOWN:
                if event.key == pg.K_ESCAPE:
                    done = True

        # Change the second arg of islice to adjust the speed.
        for i, u in islice(pixels, 2000):
            screen.set_at((u, i), (i % 256, u % 256, (i + u) % 256))

        pg.display.flip()
        clock.tick(30)


if __name__ == '__main__':
    pg.init()
    main()
    pg.quit()
    sys.exit()

编辑:有一种更简单的方法来创建构建效果:您可以将
区域
参数传递给曲面的blit方法。因此,我们可以预先创建最终图像(或加载一个),然后增加要在显示表面上闪烁的图像的百分比

import sys
import pygame as pg


def main():
    clock = pg.time.Clock()
    width, height = (640, 480)
    screen = pg.display.set_mode((width, height))
    # Create the final image beforehand.
    image = pg.Surface((width, height))
    for i in range(height):
        for u in range(width):
            image.set_at((u, i), (i % 256, u % 256, (i + u) % 256))
    image_percent = 0

    done = False
    while not done:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                done = True
            if event.type == pg.KEYDOWN:
                if event.key == pg.K_ESCAPE:
                    done = True

        screen.fill((90, 10, 200))
        # Increase the displayed portion of the image.
        if image_percent < 100:
            image_percent += .5
        # The third argument is the area of the surface on which we'll
        # blit the image.
        screen.blit(image, (0, 0), (0, 0, width/100*image_percent, height))

        pg.display.flip()
        clock.tick(30)


if __name__ == '__main__':
    pg.init()
    main()
    pg.quit()
    sys.exit()
导入系统 导入pygame作为pg def main(): 时钟=pg.time.clock() 宽度,高度=(640480) 屏幕=pg.display.set_模式((宽度、高度)) #事先创建最终图像。 图像=pg.表面((宽度、高度)) 对于范围内的i(高度): 对于范围内的u(宽度): 图像。将_设置为((u,i),(i%256,u%256,(i+u)%256)) 图像百分比=0 完成=错误 虽然没有这样做: 对于pg.event.get()中的事件: 如果event.type==pg.QUIT: 完成=正确 如果event.type==pg.KEYDOWN: 如果event.key==pg.K_转义: 完成=正确 屏幕填充((90,10200)) #增加图像的显示部分。 如果图像百分比<100: 图像百分比+=.5 #第三个参数是曲面的面积 #点击图片。 屏幕显示(图像,(0,0),(0,0,宽度/100*图像百分比,高度)) pg.display.flip() 时钟滴答(30) 如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu': 第init页() main() 第页退出 sys.exit()
谢谢大家的帮助,我确实将事件循环移动到for循环中,并通过如下分离关键事件来重新组织它们。这对我有用。关于图像,这项工作的目标是逐像素显示图像,这就是为什么我在每个循环中都进行了快速显示。无论如何,谢谢你的评论。下次我想退出函数会非常有用,所以我会设置其中一个。 这是对我有用的

for u in range (0,600):
            for i in range(0,463):

                    screen.set_at((i,u),(reddat[u,i],greendat[u,i],bluedat[u,i]))
                    pg.display.flip()
            #Event Management for exiting the screen 
            for event in pg.event.get():
                    if event.type == pg.QUIT:
                            pg.quit()
                    keys = pg.key.get_pressed()
                    if keys[pg.K_ESCAPE]:
                            pg.quit()
            pg.event.pump()

你一次就完成了整个像素变换。在你的循环中没有任何一点可以打破或检测这些事件。解决此问题的最简单方法是使用一个函数,在每次运行内部for循环时检查退出或转义事件。尽管我不确定这是否是最好的流程,因为它可能需要非常长的时间(取决于检查pygame事件所需的时间)。好的,你是建议我不要一次性运行像素转换,还是将整个事件管理移动到for循环中?实际上我已经试过了,但没有成功:-{看看我编辑过的答案。另外,也许标题应该改为“如何在Pygame中创建图像增强效果”或者类似的。哎呀,我在写答案的时候从来没有检查过其他答案。nvmLooks对我来说仍然很奇怪。我不认为嵌套循环中的
pg.display.flip
是个好主意。它会疯狂地刷新显示,而且你的一个cpu内核会很快自行升温。