Reputation: 424
I have a sprite in Pygame that is a blue circle. I want this image to be drawn to the screen "faded", e.g. translucent. However, I don't want a translucent rectangle to be drawn over it; instead, I want the actual image to be modified and made translucent. Any help is greatly appreciated!
Right now I have:
Class Circle(pygame.sprite.Sprite):
self.image = self.image = pygame.image.load("circle.png")
circle = Circle()
and eventually...
window.blit(pygame.transform.scale(circle.image, (zoom, zoom)), (100, 100))
How the circle.png looks:
How I want the image to look after making it transparent:
I am blitting the image onto the window, which is a white background.
Upvotes: 4
Views: 5335
Reputation: 20488
First, your image/surface needs to use per-pixel alpha, therefore call the convert_alpha()
method when you load it. If you want to create a new surface (as in the example), you can also pass pygame.SRCALPHA
to pygame.Surface
.
The second step is to create another surface (called alpha_surface
here) which you fill with white and the desired alpha value (the fourth element of the color tuple).
Finally, you have to blit the alpha_surface
onto your image and pass pygame.BLEND_RGBA_MULT
as the special_flags
argument. That will make
the opaque parts of the image translucent.
import pygame as pg
pg.init()
screen = pg.display.set_mode((800, 600))
clock = pg.time.Clock()
BLUE = pg.Color('dodgerblue2')
BLACK = pg.Color('black')
# Load your image and use the convert_alpha method to use
# per-pixel alpha.
# IMAGE = pygame.image.load('circle.png').convert_alpha()
# A surface with per-pixel alpha for demonstration purposes.
IMAGE = pg.Surface((300, 300), pg.SRCALPHA)
pg.draw.circle(IMAGE, BLACK, (150, 150), 150)
pg.draw.circle(IMAGE, BLUE, (150, 150), 130)
alpha_surface = pg.Surface(IMAGE.get_size(), pg.SRCALPHA)
# Fill the surface with white and use the desired alpha value
# here (the fourth element).
alpha_surface.fill((255, 255, 255, 90))
# Now blit the transparent surface onto your image and pass
# BLEND_RGBA_MULT as the special_flags argument.
IMAGE.blit(alpha_surface, (0, 0), special_flags=pg.BLEND_RGBA_MULT)
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
screen.fill((50, 50, 50))
pg.draw.rect(screen, (250, 120, 0), (100, 300, 200, 100))
screen.blit(IMAGE, (150, 150))
pg.display.flip()
clock.tick(60)
pg.quit()
Upvotes: 4
Reputation: 1485
As the Surface.set_alpha()
documentation says, you can have surfaces with "homogeneous alpha" or per pixel alpha, but not both, wich I believe is what you want. It might work with colorkey transparency, but I'm not sure (I didn't tested that yet). Any non RGBA (without active alpha channel) pixel format might work if you use set_colorkey()
and set_alpha()
before blitting.
So, the code might look like:
class Circle(pygame.sprite.Sprite):
def __init__(self)
self.image = pygame.image.load("circle.png")
# get the surface's top-left pixel color and use it as colorkey
colorkey = self.image.get_at((0, 0))
self.image.set_colorkey(colorkey)
At some point in your code (immediately before rendering) you might want to set the transparency by calling:
circle.image.set_alpha(some_int_val)
And then you can scale and blit it as intended.
Upvotes: 1
Reputation: 263
Create a new Surface with per-pixel alpha.
surf = pygame.Surface((circle_width, circle_height), pygame.SRCALPHA)
Make the surface transparent
surf.set_alpha(128) # alpha value
Draw the circle to that surface at (x=0, y=0)
surf.blit(pygame.transform.scale(circle.image, (zoom, zoom)), (0, 0))
Draw the surface to the window
window.blit(surf, (circle_x, circle_y))
Upvotes: 0