Given a pygame Surface filled with some pixels, I want to programmatically make an alpha-channel "window" in that image (such that the background shows through).
Obviously I realise that this can be trivially done with a bitmap editor, the point of the question is to do this on-the-fly as part of a different, more-complex operation.
So I made a sprite that switches between the "full-red" and "red-with-hole" images, and tried to dynamically make the bitmap-window by blitting a fully-transparent image onto the base-bitmap.
I think what is happening, is that PyGame is not painting the fully-transparent pixels because, well they're transparent! Is there a way to blit them such that the window is made?
I tried adding pygame.BLEND_RGBA_MIN
and others (as per the suggestion in Need to blit transparency on a surface in Pygame ), but failed to achieve the desired result.
All I ever get is a black square, centred in the red, rather than a window to the background.
import pygame
# Window size
WINDOW_WIDTH = 400
WINDOW_HEIGHT = 400
FPS = 60
# background colours
INKY_BLACK = (128, 128, 128)
class HoleSprite( pygame.sprite.Sprite ):
def __init__( self ):
pygame.sprite.Sprite.__init__( self )
# Make a full-image (no hole)
self.base_image = pygame.Surface( ( 32, 32 ), pygame.SRCALPHA )
self.base_image.fill( ( 255,0,0 ) )
# Make an image with a see-through window
self.hole_image = pygame.Surface( ( 32, 32 ), pygame.SRCALPHA )
self.hole_image.fill( ( 255,0,0 ) )
self.hole = pygame.Surface( ( 10, 10 ), pygame.SRCALPHA )
self.hole.fill( ( 0, 0, 0, 255 ) ) # transparent
self.hole_image.blit( self.hole, [ 10,10, 10,10 ] ) # punch the middle out?
# sprite housekeeping
self.image = self.base_image
self.rect = self.image.get_rect()
self.rect.x = WINDOW_WIDTH // 2 # centred
self.rect.y = WINDOW_HEIGHT // 2
self.last = 0
def update( self ):
time_ms = pygame.time.get_ticks()
# FLip the images each second
if ( time_ms - self.last > 1000 ):
if ( self.image == self.hole_image ):
self.image = self.base_image
else:
self.image = self.hole_image
self.last = time_ms
### MAIN
pygame.init()
pygame.font.init()
SURFACE = pygame.HWSURFACE|pygame.DOUBLEBUF|pygame.RESIZABLE
WINDOW = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ), SURFACE )
pygame.display.set_caption("Hole Srite Test")
anims = pygame.sprite.GroupSingle()
holey = HoleSprite( )
anims.add( holey )
clock = pygame.time.Clock()
done = False
while not done:
# Handle user-input
for event in pygame.event.get():
if ( event.type == pygame.QUIT ):
done = True
# Repaint the screen
anims.update()
WINDOW.fill( INKY_BLACK )
anims.draw( WINDOW )
pygame.display.flip()
# Update the window, but not more than 60fps
clock.tick_busy_loop( FPS )
pygame.quit()