重复平铺背景pygame

6
在pygame中是否有类似的功能?
screen.fill(pygame.image.load('brick.bmp').convert()) 

我希望将一张图片填充到窗口(背景)中,以产生类似于以下效果的效果: enter image description here 我的唯一想法是把每个砖块绘制到屏幕上,但我认为这会减慢游戏速度。 有人有什么想法如何做到这一点(并提供一些示例代码)吗?
这是一个有效但速度较慢的方法的代码片段。
    While True:
        for y in range(0,600,32):
            for x in range(0,800,32):
                screen.blit( self.img,(x,y))
        ...
        pygame.display.flip()

1
你在评论中说这个程序“慢”了,那么有多慢?你是如何测量的? - SingleNegationElimination
我在屏幕上有一个玩家,可以用箭头键移动。当我加入这段代码后,他的移动速度变慢了。 - user1357159
FPS会改变吗?这个低分辨率和少量的瓷砖应该很快。你所有的表面都在绘制循环之外加载和转换了吗? - ninMonkey
3个回答

5
blitting是将每个砖块绘制到屏幕上,但我认为这会减慢游戏的速度。实际上它不会像你想象的那样减慢速度。blitting非常快速。即使有某种“填充”命令,它仍然相当于将图像复制到一个表面上,直到表面被覆盖。如果背景图片是静态的,你可以在程序启动时渲染到一个离屏表面,并且不需要通过使用纯色填充来清空屏幕,而是只需将预先渲染的背景 blit 到屏幕上即可。

我正在使用pygame.display.flip(),我认为它正在删除我在主循环之前创建的砖块。当我将生成的代码放入主循环中时,速度变慢但可以工作。我该如何预渲染? - user1357159
1
flip不会擦除屏幕,它只会显示自上次翻转以来绘制的内容(有点像...)。 - SingleNegationElimination
1
如果你真的很担心速度的话,就不要使用pygame.display.flip() ——那会浪费很多时间。只需将你的更新blit到屏幕上(并“修复”移开的背景),然后只更新你改变的矩形区域。在大型画布和少量图块的情况下,这样做可以极大地提高性能。 - kratenko
@kratenko:由于pygame使用双缓冲,如果我不使用pygame.display.flip(),那么我将永远看不到任何被绘制的内容,那么如何避免使用它呢? - MestreLion
根据我在其他讨论中发现的,使用双缓冲在pygame中不值得麻烦(没有参考资料支持,也没有自己的经验 - 我不使用pygame进行我的项目,因为我需要一些GUI支持...)。每帧翻转一次可能适用于您的项目,具体取决于您正在做什么。但是,如果您只更新巨大屏幕上的很少几个部分,则使用update(rect_list)会更快。如果您使用opengl,所有内容都将不同,我从未尝试过。 - kratenko
实际上,.display.flip()display.update() 都使用了双缓冲区。 除非您将“脏” rect_list 传递给 update(),否则它们的表现完全相同。 当您最初说“不要使用 flip()”时,我认为您的意思是“根本不要使用”。 因此,我想完整的措辞应该是“不要使用 pygame.display.flip(),而是使用pygame.display.update(rect_list)”。 - MestreLion

2

我在Pygame中找不到这个功能。但是,我有一种方法可以提高你的方法的性能。 你可以先创建一个表面,称之为bgSurface。然后使用你的双层循环方法将所有砖块都 blit 到 bgSurface 上。然后在主循环中,你可以执行 screen.blit(bgSurface, (0, 0))。试一试吧。


0
我有这个非常简单的函数,可以在可调整大小的窗口上工作:
def tileBackground(screen: pygame.display, image: pygame.Surface) -> None:
    screenWidth, screenHeight = screen.get_size()
    imageWidth, imageHeight = image.get_size()
    
    # Calculate how many tiles we need to draw in x axis and y axis
    tilesX = math.ceil(screenWidth / imageWidth)
    tilesY = math.ceil(screenHeight / imageHeight)
    
    # Loop over both and blit accordingly
    for x in range(tilesX):
        for y in range(tilesY):
            screen.blit(image, (x * imageWidth, y * imageHeight))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接