【问题标题】:Printing small rectangles to the screen in a for loop. (pygame)在 for 循环中将小矩形打印到屏幕上。 (游戏)
【发布时间】:2015-08-13 21:42:04
【问题描述】:

我正在尝试使用 for 循环在 pygame 中的整个屏幕上打印小矩形的代码,但遇到了麻烦。我已经用这段代码解决了部分问题,但它看起来很丑,而且性能很差:

x = 0
y = 0

for y_row in range(60):
    y = y + 10
    pygame.draw.rect(screen, GREEN, [x, y, 5, 5], 0)
    for x_row in range(70):
        pygame.draw.rect(screen, GREEN, [x, y, 5, 5], 0)
        x = x + 10
    x = 0

首先,如果我能弄清楚如何在 x 和 y 的位置实现 y_row 和 x_row 的值,我不相信我必须为 x 和 y 赋值,现在它随着 1 增加,它应该增加 10,而不是我可以实现它。

代码的另一个问题是它在顶部留下了一个空白行,这是因为我必须在 pygame 绘图上方添加 y = y + 10,否则它只会在那里打印一个矩形,使其更明显。

我用来让代码工作的模板你可以找到Here

【问题讨论】:

    标签: python python-3.x for-loop pygame


    【解决方案1】:

    每 60 秒在屏幕上绘制 4,200 个矩形可能是 CPU 的一项重要任务。我怀疑pygame.draw.rect() 函数是相当高级的,调用不是由 pygame 批处理使其次优,文档 (https://www.pygame.org/docs/ref/draw.html#pygame.draw.rect) 中有提示Surface.fill(color, rect=None, special_flags=0) 可以硬件加速并且可能是如果您要填充矩形,则更快的选择。

    注意:下面的代码示例是伪代码......只是意味着您需要填补空白。

    每次循环迭代您只需要调用 1 次 pygame.draw.rect 而不是现在的 2 次,例如

    for row in rows:
        y = ...
        for col in cols:
            x = ...
            ... draw rect ...
    

    一个简单的性能优势是不要在屏幕外绘制任何东西,所以在渲染之前测试你的xy坐标,例如:

    screen_width = 800
    screen_height = 600
    
    for ...
        y = y += 10
        if y > screen_height:
            break
    
        for ...
            x += 10
            if x > screen_width:
                break
    
            ... draw block ...
    

    也可以使用相同的方法(使用continue)来实现偏移(例如,起始offset_xoffset_y 值),其中不呈现具有负xy 值的矩形(但是测试不是x < 0,而是x < -block_size)。

    从循环索引中计算 xy 值并没有错,索引通常很有用(例如,索引 [row][col] 可能会为您提供数据的位置表示游戏图块的 2D 矩阵中的图块)。我会使用乘数从索引中自己计算xy 值(这也解决了第一行空白问题):

    block_size = 10
    
    for row in ...
        y = row * block_size
        if y > screen_height:
            break
    
        for col in ...
            x = col * block_size 
            if x > screen_width:
                break
    
            ... draw block ...
    

    如果您使用的是 Python2,那么您可能会考虑使用xrange 来预定义循环范围以提高性能(尽管我想只有少量并且与优化测试一样,性能差异是关键)。例如:

    rows = xrange(60)
    cols = xrange(70)
    
    for row in rows:
        ...
        for cols in cols:
            ... draw block ...
    

    【讨论】:

      【解决方案2】:

      正如@bshuster13 提到的,您可以使用pythons range() 函数并传递一个可选步骤停止参数 创建一个包含算术级数的列表

      numberOfRows = 60
      numberOfColumns = 70
      
      stepBetweenRects = 10
      
      for y in range(0, numberOfRows * stepBetweenRects, stepBetweenRects):
          for x in range(0, numberOfColumns * stepBetweenRects, stepBetweenRects):
              pygame.draw.rect(screen, GREEN, (x, y, 5, 5), 0)
      

      【讨论】:

        猜你喜欢
        • 2013-12-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多