0

我正在使用像素列表从使用 pygame 中绘制线条。我使用 pygame.time.get_ticks() 函数每秒向列表中添加新像素,以便在程序推进时同时绘制多条线。这是代码中的一个片段:

    screen_size = [self.xsize, self.ysize]
    screen = pygame.display.set_mode(screen_size)
    start_points = list()
    start_points.append(self.get_random_pixel())
    screen.fill((255, 255, 255))

    while True

        if time.time.get_ticks() % 1000 == 0:
            start_points.append(self.get_random_pixel())

        for i in range(len(start_points)):
            old_coord = start_points[i]
            new_coord = self.nearest_neighbor(old_coord)
            pygame.draw.line(screen, self.get_col(old_coord), old_coord, new_coord, 2)
            start_points[i] = new_coord
            pygame.display.flip()

对此的一些看法: 1. 运行此程序时,我只得到一张线条图。2. 随着程序的推进,列表 start_points 似乎随着添加到其中的更多像素而增长。3. 当列表是固定大小时(比如说 100),我确实有 100 条线同时绘制。

那么这里发生了什么?随着时间的流逝,为什么我不能同时画更多的线条?

谢谢!奥马尔

4

1 回答 1

1

考虑一下如果你的循环需要 23 毫秒来运行会发生什么。所以,第一次调用 时get_ticks,你得到 0。然后你得到 23、46、…、989、1012、…、1978、2001、…、2990、3013,…,等等。在您达到第一个可被 1000 整除的数字之前,还有 23 秒!

当然,在现实生活中,你的循环时间不是恒定的,而是高度可变的,但你基本上有同样的问题。

解决这个问题的正确方法是围绕事件循环或固定帧速率循环重新组织程序。

使用事件循环,您可以set_timer每秒触发一次事件。此外,即使什么都没有发生,也不是尽可能快地重绘和翻转屏幕,而是不断消耗 100% 的 CPU,甚至可能让你的游戏对事件响应迟缓,你只会在实际需要时重绘和翻转屏幕,几乎不使用 CPU 并且几乎总是准备好响应。

使用固定的帧速率,例如 20fps,您可以每 20 帧触发一次。再一次,你只会以每秒 20 次而不是尽可能快的速度重绘屏幕,因此你的 CPU 使用率会大大降低,并且可以在 1/20 秒内响应任何事情。

但如果你真的想这样做,你可以。你只需要跟踪下一次开火。例如:

next_line_time = 0

while True:

    while time.time.get_ticks() >= next_line_time:
        start_points.append(self.get_random_pixel())
        next_line_time += 1000

作为旁注,您几乎从不希望range(len(foo))在 Python 中进行循环。只是循环foo; 那么你就不需要foo[i]循环中的所有这些了。如果您确实需要索引和值,则可以随时循环enumerate(foo),这两者都可以。例如:

for i, old_coord in enumerate(start_points):
    new_coord = self.nearest_neighbor(old_coord)
    pygame.draw.line(screen, self.get_col(old_coord), old_coord, new_coord, 2)
    start_points[i] = new_coord
    pygame.display.flip()

此外,您几乎肯定不想flip在每一行之后调用。绘制每条线需要几微秒的时间,并且试图以比显示器和/或眼睛检测到的速度更快的速度翻转是一种浪费。

于 2013-07-05T11:39:10.653 回答