tags:

views:

720

answers:

4

I've just started working with pygame and I'm trying to make a semi-transparent sprite, and the sprite's source file is a non-transparent bitmap file loaded from the disk. I don't want to edit the source image if I can help it. I'm sure there's a way to do this with pygame code, but Google is of no help to me.

+1  A: 

After loading the image, you will need to enable an alpha channel on the Surface. that will look a little like this:

background = pygame.Display.set_mode()
myimage = pygame.image.load("path/to/image.bmp").convert_alpha(background)

This will load the image and immediately convert it to a pixel format suitable for alpha blending onto the display surface. You could use some other surface if you need to blit to some other, off screen buffer in another format.

You can set per-pixel alpha simply enough, say you have a function which takes a 3-tuple for rgb color value and returns some desired 4tuple of rgba color+alpha, you could alter the surface per pixel:

def set_alphas(color):
    if color == (255,255,0): # magenta means clear
        return (0,0,0,0)
    if color == (0,255,255): # cyan means shadow
        return (0,0,0,128)
    r,g,b = color
    return (r,g,b,255) # otherwise use the solid color from the image.

for row in range(myimage.get_height()):
    for col in range(myimage,get_width()):
        myimage.set_at((row, col), set_alphas(myimage.get_at((row, col))[:3]))

There are other, more useful ways to do this, but this gives you the idea, I hope.

TokenMacGuy
A: 

you might consider switching to using png images where you can do any kind of transparency you want directly in the image.

DShook
A: 

If your image has a solid color background that you want it to became transparent you can set it as color_key value, and pygame will make it transparent when blitting the image.

eg:

color = image.get_at((0,0)) #we get the color of the upper-left corner pixel
image.set_colorkey(color)
Lucas S.
A: 

I may have not been clear in my original question, but I think I figured it out on my own. What I was looking for turns out to be Surface's set_alpha() method, so all I had to do was make sure that translucent images were on their own surface.

Here's an example with my stripped down code:

import pygame, os.path
from pygame.locals import *

class TranslucentSprite(pygame.sprite.Sprite):
  def __init__(self):
    pygame.sprite.Sprite.__init__(self, TranslucentSprite.container)
    self.image = pygame.image.load(os.path.join('data', 'image.bmp'))
    self.image = self.image.convert()
    self.image.set_colorkey(-1, RLEACCEL)
    self.rect = self.image.get_rect()
    self.rect.center = (320,240)

def main():
  pygame.init()
  screen = pygame.display.set_mode((640,480))
  background = pygame.Surface(screen.get_size())
  background = background.convert()
  background.fill((250,250,250))
  clock = pygame.time.Clock()
  transgroups = pygame.sprite.Group()
  TranslucentSprite.container = transgroups

  """Here's the Translucency Code"""
  transsurface = pygame.display.set_mode(screen.get_size())
  transsurface = transsurface.convert(screen)
  transsurface.fill((255,0,255))
  transsurface.set_colorkey((255,0,255))
  transsurface.set_alpha(50)

  TranslucentSprite()
  while 1:
    clock.tick(60)
    for event in pygame.event.get():
      if event.type == QUIT:
        return
      elif event.type == KEYDOWN and event.key == K_ESCAPE:
        return
    transgroups.draw(transsurface)
    screen.blit(background,(0,0))
    screen.blit(transsurface,(0,0))
    pygame.display.flip()

if __name__ == '__main__' : main()

Is this the best technique? It seems to be the most simple and straightforward.

jjackson