Well, wouldn't you know it? By changing:
bgsurface = pygame.display.get_surface()
to:
bgsurface = pygame.display.get_surface().copy()
i.e. blitting a copy of the window instead of the window to the
window, alpha transparency works perfectly. I probably should have
known, but I didn't realize that the window was blitting itself to itself.
But now I have a question: What exactly happens when you blit a
surface to itself? It seems pretty clear that it caused alpha
transparency for something else being blitted to it to not work in
this case, but I still don't quite understand why. Sorry, but I just
like to understand why things happen. :)
------------------------------------------------------------------------
*From:* Lenard Lindstrom <len-l@xxxxxxxxx>
*To:* pygame-users@xxxxxxxx
*Sent:* Sun, October 10, 2010 1:46:36 PM
*Subject:* Re: [pygame] Surface blitting not effective
There are a couple of things happening in this program which make it
hard to know what is happening with the alpha blit. First, the display
surface is blitted to itself:
class Game(object):
....
def __init__(self):
....
self.window = pygame.display.set_mode(self.rect.size)
....
def menu(self, options, cursor, anim_wait,
color=pygame.Color(0,0,0,155), border=16, sep=8):
....
#Create background surface
bgsurface = pygame.display.get_surface()
....
#Begin menu loop
while 1:
....
#Draw
self.window.blit(bgsurface, self.rect)
....
Second, the menu surface is of an unknown format:
#Create menu surface
dlgsurface = pygame.Surface((xsize,ysize)).convert()
dlgsurface.fill(color)
dlgsurface.set_alpha(color.a)
Surface.convert() makes dlgsurface have the same properties as the
display. If the display has per-pixel-alpha (Is that possible?) then
so will dlgsurface. Blanket alpha, as set by Surface.set_alpha(), is
ignored in this case. Better to create the menu surface with a known
format:
dlgsurface = pygame.Surface((xsize, ysize), 0, 24) # no
per-pixel alpha
Lenard Lindstrom
On 09/10/10 08:31 PM, B W wrote:
> Your blits were copying the source to positions outside the target
surface. I always suspect this if I can't see my graphics. You can
insert statements like
"dlgsurface.get_rect().collidepoint(choicerect.topleft)" or "print
dlgsurface.get_rect().colliderect(choicerect)" to tell whether the
source rect intersects the target rect.
>
> I has a sneaking suspicion about the alpha problem and it paid off.
Someone who understands the internals of color alphas and surface
alphas would have to explain the why. :)
>
> #Create menu surface
> dlgsurface = pygame.Surface((xsize,ysize)).convert()
> ##change
> # dlgsurface.fill(color)
> dlgsurface.fill(*color[3:])
> dlgsurface.set_alpha(color.a)
> dlgrect = dlgsurface.get_rect(center=self.rect.center)
> ##new
> drawrect = dlgsurface.get_rect()
>
> cursor_rect = []
> ypos = border
>
> for option in options:
> ##change
> # choicerect = option.get_rect(centerx=dlgrect.centerx, \
> # top=dlgrect.top + ypos)
> choicerect = option.get_rect(centerx=drawrect.centerx, \
> top=drawrect.top + ypos)
> dlgsurface.blit(option, choicerect)
> ##change
> #
cursor_rect.append(cursor[0].get_rect(centery=choicerect.centery, \
> # left =
dlgrect.left+border))
> cursor_rect.append(cursor[0].get_rect(
> centery=dlgrect.top+choicerect.centery,
> left=dlgrect.left+border))
> ypos += option.get_height() + sep
>