有什么方法可以加快Python和Pygame的速度吗?

17 投票
7 回答
33248 浏览
提问于 2025-04-16 19:49

我正在用Pygame写一个简单的自上而下的角色扮演游戏,但发现运行速度挺慢的……虽然我知道Python和Pygame的速度不可能和用C/C++这样的编译语言做的游戏比,但现在Pygame的帧率(FPS)只有15。我尝试用16色的位图代替PNG或24位的位图,这样速度稍微快了一点。后来我绝望之下,把所有图像都换成了黑白单色位图,这样帧率提高到了35,但还是不够。根据我读过的大多数游戏开发书籍,2D游戏的帧率至少要达到40,玩家才能对游戏画面感到满意。那么,有没有什么办法可以提高Pygame的速度呢?

7 个回答

4

在使用图片的时候,重要的一点是要用图片的convert()函数来转换它们。我听说使用convert()会禁用透明度,这样通常会比较慢。在我使用16位色深和convert函数处理我的图片之前,我也遇到过速度问题。现在即使我把一张大图像显示到屏幕上,我的每秒帧数(FPS)也能达到150。

image = image.convert()#video system has to be initialed

另外,旋转和缩放图像的计算也需要花费很多时间。如果一个经过变换的大图像是不可变的,可以把它保存到另一个图像中。

所以这个想法就是只计算一次,然后多次重复使用这个结果。

6

这些都是很好的建议,效果也不错,但你还需要记住两件事:

1) 把一个图像叠加到另一个图像上比直接绘制要快。所以最好在游戏主循环之外,先把固定的图像绘制到一个表面上,然后再把这个表面显示到主屏幕上,这样会更高效。例如:

# pre-draw image outside of main game loop
image_rect = get_image("filename").get_rect()
image_surface = pygame.Surface((image_rect.width, image_rect.height))
image_surface.blit(get_image("filename"), image_rect)
......
# inside main game loop - blit surface to surface (the main screen)
screen.blit(image_surface, image_rect)

2) 确保你没有浪费资源去绘制用户看不见的东西。例如:

if point.x >= 0 and point.x <= SCREEN_WIDTH and point.y >= 0 and point.y <= SCREEN_HEIGHT:
    # then draw your item

这些是一些帮助我保持游戏流畅度(FPS高)的基本概念。

22

使用Psyco,适用于Python2:

import psyco
psyco.full()

另外,开启双缓冲。比如:

from pygame.locals import *
flags = FULLSCREEN | DOUBLEBUF
screen = pygame.display.set_mode(resolution, flags, bpp)

如果你不需要透明效果,也可以关闭透明选项:

screen.set_alpha(None)

不要每次都刷新整个屏幕,而是记录下变化的区域,只更新那些部分。比如,主循环大概可以这样写:

events = pygame.events.get()
for event in events:
    # deal with events
pygame.event.pump()
my_sprites.do_stuff_every_loop()
rects = my_sprites.draw()
activerects = rects + oldrects
activerects = filter(bool, activerects)
pygame.display.update(activerects)
oldrects = rects[:]
for rect in rects:
    screen.blit(bgimg, rect, rect)

大多数(可能所有)绘图函数都会返回一个矩形区域。

你还可以只设置一些允许的事件,这样可以更快地处理事件:

pygame.event.set_allowed([QUIT, KEYDOWN, KEYUP])

另外,我建议不要手动创建缓冲区,也不要使用HWACCEL这个选项,因为我在某些设备上遇到过问题。

使用这些方法,我在一个小的2D平台游戏中达到了相当不错的帧率和流畅度。

撰写回答