首页 > 解决方案 > 仅多边形中的 Pygame alpha

问题描述

我目前正在制作一个在现有 JPG 之上绘制多边形的 pygame 代码。

我所做的是绘制 2 个表面,一个用于底部的背景 JPG,另一个用于顶部的多边形。对于多边形表面,我需要为表面赋予“SRCALPHA”属性,这样没有背景填充会阻挡背景 JPG 的视图。但是,当我这样做时,我不能使用多边形 surface.set_alpha 来控制多边形的透明度。

这样做的方法是什么,或者我应该完全改变我的方法?

编辑:这个问题解决后,我在类似的事情中遇到了另一个问题,请在文本中查看 Python pygame alpha,如果您知道解决方案,请帮助我。非常感谢。

标签: pythonpython-3.xpygame

解决方案


您将两种不需要(也不能混合)的东西混合在一起。但是你不需要使用set_alpha()来实现你想要的。

SRCALPHA告诉它你将在这个表面上使用每个像素的 alpha。如果您阅读此处的文档,您会发现它说“SRCALPHA 像素格式将包括每个像素的 alpha”。在这里,您会看到文档set_alpha()表明它与每像素 alpha 不兼容“对于具有每像素 alpha 的表面,忽略覆盖 alpha”(除非您使用的是我怀疑的 pygame 2)。

根据您对问题的描述,我怀疑您是否需要 set_alpha 。如果您创建了上表面以使用“SRCALPHA”的每像素 alpha,那么您未绘制的像素将已经是透明的。当你在另一个表面上粘贴它时,只有你绘制的多边形应该被转移。

这是一个例子:

GREEN = pygame.Color('green')
RED = pygame.Color('red')

size = (800, 400)
    
pygame.init()
screen = pygame.display.set_mode(size)

lowersurf = pygame.Surface(size)
lowersurf.fill(GREEN)

polysurf = pygame.Surface(size, flags=pygame.SRCALPHA)
pygame.draw.polygon(polysurf, RED, ((100, 100), (600, 100), (600, 200), (350, 300), (100, 200)), 4)

lowersurf.blit(polysurf, (0, 0))

screen.blit(lowersurf, (0, 0))
pygame.display.flip()

它在透明对象上绘制多边形轮廓polysurf,然后将其粘贴到正常对象上lowersurf

然后它将结果blitlowersurf到屏幕上。

编辑:

在评论中,OP 询问如何将多边形绘制到lowersurf具有透明度的多边形上,以使其具有 50% 的透明度。可以通过将图像绘制到polysurf部分透明的方式来完成的一种方法。像这样:

GREEN = pygame.Color('green')
RED = pygame.Color('red')

transparent_red = RED
transparent_red[3] = 125

size = (800, 400)
    
pygame.init()
screen = pygame.display.set_mode(size)

lowersurf = pygame.Surface(size)
lowersurf.fill(GREEN)

polysurf = pygame.Surface(size, flags=pygame.SRCALPHA)
pygame.draw.polygon(polysurf, transparent_red, ((100, 100), (600, 100), (600, 200), (350, 300), (100, 200)), 4)

lowersurf.blit(polysurf, (0, 0))

screen.blit(lowersurf, (0, 0))
pygame.display.flip()

这将创建transparent_red50% 透明的颜色。颜色中的第四个参数是 alpha 值,范围从 0(完全透明)到 255(完全不透明),所以 125 是一半。

另一种可能是您真正想要的方法是使用整个polysurf而不只是特定的东西来执行此操作。像最初那样绘制整个 polysurf,然后在绘制之前调整整个表面的 alpha。像这样:

GREEN = pygame.Color('green')
RED = pygame.Color('red')

size = (800, 400)

blend_alpha = 125
    
pygame.init()
screen = pygame.display.set_mode(size)

lowersurf = pygame.Surface(size)
lowersurf.fill(GREEN)

polysurf = pygame.Surface(size, flags=pygame.SRCALPHA)
pygame.draw.polygon(polysurf, RED, ((100, 100), (600, 100), (600, 200), (350, 300), (100, 200)), 4)

transparent_polysurf = polysurf.copy()
transparent_polysurf.fill((255, 255, 255, blend_alpha), special_flags=pygame.BLEND_RGBA_MULT)

lowersurf.blit(transparent_polysurf, (0, 0))

screen.blit(lowersurf, (0, 0))
pygame.display.flip()

在此示例中,我复制了polysurf然后在副本上使用了fill()using special_flags=pygame.BLEND_RGBA_MULT(请参阅此处的文档),以使其在复制副本之前部分透明。我这样做是为了不影响原件,但如果您不在乎,则可以fill()直接进行混合polysurf而无需制作副本。

正如我所说,您可能希望采用最后一种方法,因为它融合polysurf了相同级别的透明度。如果您想混合polysurf使用不同透明度级别绘制的不同事物,则另一种方法很有用。


推荐阅读