【问题标题】:drawing lines from a list in pygame从pygame中的列表中绘制线条
【发布时间】:2013-07-05 19:39:10
【问题描述】:

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

    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 条线同时绘制。

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

谢谢! 奥马尔

【问题讨论】:

  • 这不可能是您的实际代码,因为至少有一个SyntaxError。此外,它不是完整 代码。 SSCCE 更容易提供帮助,因为人们可以运行它来查看它的作用,而不是试图理解您的描述、调试它、使用它等等。
  • Pygame 有一个内置的 get_ticks 函数pygame.time.get_ticks()
  • 感谢您的提示。从现在开始我会尝试使用SSCCE。
  • @monkey:我假设他已经在使用它,因为 stdlib time 模块没有time 类型,也没有get_ticks() 函数或方法。

标签: python pygame draw lines


【解决方案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

附带说明一下,您几乎不需要在 Python 中对 range(len(foo)) 进行循环。只需循环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。绘制每条线需要几微秒的时间,并且试图以比您的显示器和/或您的眼睛检测到的速度更快的速度翻转是一种浪费。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-06
    • 1970-01-01
    • 2013-09-13
    相关资源
    最近更新 更多