如何高效地清除pygame的透明层?
我正在尝试用Python和Pygame写一个2D游戏,每次屏幕刷新时会把几个层叠加在一起。我的基本设置是(从底到顶):
- 背景:一个不透明的表面,滚动速度和其他部分不同
- 中景:一个透明的表面(静态)
- 玩家/精灵/敌人:精灵组
- 前景:一个透明的表面(静态)
现在,我每次屏幕刷新时都会把这四个层叠加在一起。背景的滚动速度和其他三个层不同,所以我把它单独处理。现在我的游戏结构是这样的,它在我的一台配置一般的笔记本电脑上能以60帧每秒的速度运行。
-但是- 我在处理精灵组时遇到了麻烦,我是直接把它们绘制到屏幕上的。每次都要根据当前的视口调整每个精灵的位置,这样编程起来感觉很麻烦,我想找一个更优雅的解决方案。
我希望能把精灵绘制到另一个透明的表面上,这样我就可以更好地管理它们,但这就是我的问题:我找不到一种方法来清除透明层,而不会让我的性能下降一半。我尝试过的一些方法包括:
- 我尝试用一个白色表面填充这个层,使用混合模式rgba_sub(surf.fill((255,255,255,255), area, BLEND_RGBA_SUB))——这个方法超级慢
- 我尝试用一个空白表面的surface.copy()——这个方法快一些,但仍然会让我的帧率减半
- 我尝试把精灵和中景层结合起来,并使用pygame.sprite.LayeredUpdates来更新精灵。这个方法对性能没有影响,但在中景层透明的地方不管用。我会在背景层上看到精灵的拖影。
到目前为止,我找到的最好解决方案就是直接把精灵绘制到屏幕上。效果很好,运行也很快,但管理起来很麻烦,因为我每帧都得确保每个精灵的位置根据视口进行调整。这也让碰撞检测变得困难。
有没有其他快速的方法可以清除Pygame的透明表面?快速的意思是,每秒可以执行60次以上?或者,我是否可以设置我的层,以达到相同的效果?
2 个回答
1
Surface.fill() 这个方法会清空所有的红色、绿色、蓝色和透明度的值。
>>> img = pygame.image.load("hasalpha.png")
>>> print img.get_at((300, 300))
(238, 240, 239, 255)
>>> surface.fill(0)
>>> print img.get_at((300, 300))
(0, 0, 0, 0)
听起来这个方法可以实现你所描述的功能。如果你想对透明度的值做更具体的操作,pygame.surfarray.pixel 这些函数可以给你直接可以编辑的值。这种方法会比较快,但需要依赖一个叫做 numpy 的库。
2
我找到了一个快速清除精灵透明层的方法,就是选择性地应用Peter的解决方案到这个层上:
for s in self.level.sprites:
spritelayer.fill((0), s.rect)
这个方法看起来效果不错(每帧都能清除所有内容),而且仍然能保持60帧每秒的速度。