Hi Julian,
A self blit works like other blits. What happened in your program was
that the self blit did not clear the background. So the menu image was
repeatedly blitted onto itself. Blitting a semi-transparent color onto
itself just strengths the color on the target surface until it becomes
totally opaque.
Lenard Lindstrom
On 10/10/10 05:19 PM, Julian Marchant wrote:
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 <le...@telus.net>
*To:* pygame-users@seul.org
*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
>