You are mixing two things together that you do not need to (and cannot mix). However you do not need to use set_alpha()
to achieve what you want.
SRCALPHA
tells it that you are going to use per pixel alpha on this surface. If you read the docs here you will find it says 'SRCALPHA the pixel format will include a per-pixel alpha'. Here you see that the docs for set_alpha()
indicate it is incompatible with per-pixel alpha 'For a surface with per pixel alpha, blanket alpha is ignored' (unless you are using pygame 2 which I doubt).
From your description of the problem, I doubt that you need set_alpha though. If you have created your upper surface to use per pixel alpha with "SRCALPHA" then the pixels you do not draw will already be transparent. when you blit it over the other surface only the polygon you drew should be transferred.
Here is an example:
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()
It draws a polygon outline on the transparent polysurf
and then blits that onto the normal lowersurf
.
Then it blits the resulting lowersurf
onto the screen.
Edit:
In a comment the OP asked how to draw the polygon onto the lowersurf
with transparency so that it would have 50% transparency. One way that can be done by drawing the images onto the polysurf
with as partially transparent. Like this:
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()
This creates a color transparent_red
that is 50% transparent. The fourth parameter in the color is the alpha value and it ranges from 0 (fully transparent) to 255 (fully opaque), and so 125 is halfway.
A further approach, which is likely what you really want, is to do this with the entire polysurf
and not just specific things drawn onto it. Draw the entire polysurf as originally done and then adjust the alpha of the entire surface before drawing it. Like this:
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()
In this example I copied the polysurf
and then used the fill()
using special_flags=pygame.BLEND_RGBA_MULT (see docs here) on the copy to make it partially transparent before blit'ing the copy. I did that so the original is unaffected, but if you don't care, then you can do the blending fill()
directly on polysurf
without making a copy.
As I said, you likely want to go with the last approach since it blends everything from polysurf
with the same level of transparency. The other approach is useful if you want to blend different things drawn to polysurf
with different transparency levels.