Transparent Sprites in Pygame

2019-05-23 21:24发布

问题:

I'm working on some Python code that uses Pygame, trying to display a small sprite (a ball) on top of a background. I have that part working, but I'm trying to get the background of the ball sprite to be transparent so it doesn't show up as a "ball within a black square" sprite, but instead shows up with the black pixels not being blitted to the display surface.

Here is my code:

# For sys.exit()
import sys

# Pygame imports
import pygame
from pygame.locals import *

# Initialize all the Pygame Modules
pygame.init()

# Build a screen (640 x 480, 32-bit color)
screen = pygame.display.set_mode((640,480)) 

# Create and Convert image files
# Use JPG files for lots of color, and use conver()
# Use PNG files for transparency, and use convert_alpha()
background = pygame.image.load("bg.jpg").convert()
ball = pygame.image.load("ball.png").convert_alpha()
ball.set_colorkey(-1, RLEACCEL) # Use the upper-left pixel color as transparent

# The main loop
while True:

    # 1 - Process all input events
    for event in pygame.event.get():

        # Make sure to exit if the user clicks the X box
        if event.type == QUIT:
            pygame.quit()
            sys.exit()

    # 2 - Blit images to screen (main display window)
    screen.blit(background, (0,0))
    x,y = pygame.mouse.get_pos()
    x = x - ball.get_width()/2
    y = y - ball.get_height()/2
    screen.blit(ball, (x,y))

    # 3 - Update the main screen (redraw)
    pygame.display.update()

I must be making an obvious mistake, but I can't figure it out. Calling ball.set_colorkey(-1, RLEACCEL) should pick up the color of the upper-left corner of the ball sprite (which happens to be black) and use that as the pixel color "not to blit". Am I missing a step?

Thanks for your help.

回答1:

There's per-pixel alpha, colorkey alpha, and per-surface alpha. You're asking for colorkey.

When you call convert_alpha() it creates a new surface for per-pixel alpha.

And from set_colorkey

The colorkey will be ignored if the Surface is formatted to use per pixel alpha values.

So: Load image with .convert() Since you want to use a color key. Then call set_colorkey.

Also, I saw nothing in the docs about passing "-1" as first argument to set_colorkey.

That's probably from a tutorial, which has a load_image function to grab the topleft pixel's color value.



回答2:

How is your image created? Pygame transparecy for blitting should work if your "ball.png" file i s a ball on transparent background, and not a ball on a black square. That said, from Pygame's surface documentation for "set_colorkey":

"The colorkey will be ignored if the Surface is formatted to use per pixel alpha values. The colorkey can be mixed with the full Surface alpha value."

So, the idea of colorkey is to use it when yiour image does not have per pixel alpha - and you are just ensuring it does have when you call "convert alpha". Also, I saw nothing in the docs about passing "-1" as first argument to set_colorkey.

In short: My advice is to use proper transparent images to start with - and forget about "convert", "convert_alpha", "set_colorkey" and so on. If you have some reason for not using per pixel alpha from the PNG file, then check this answer a the right way to do it (and even for one reason not to want per pixel alpha when blitting to the screen): PyGame: Applying transparency to an image with alpha?



标签: python pygame