I have created a day and nigh cycle in a game of mine by drawing a rectangle over the screen and having it's alpha change constantly. However, I obviously want to add some lighting to the game. Is there a way to kind of set the alpha of a particular part of a rectangle to 0 using pygame? Or is there perhaps another way of going about this whole lighting thing?
1 Answer
You can edit the transparency of Surface objects pixel-by-pixel with the surfarray module. The surfarray module is dependent on Numpy.
# SRCALPHA flag means that blit uses source alpha blending.
# It is required for pixels_alpha().
image = pygame.Surface((width, height), pygame.SRCALPHA)
# Create a 2d array that contains per-pixel transparency values of the Surface. (0-255)
# This is a reference, so it affects original
transparency_array = pygame.surfarray.pixels_alpha(image)
You can then access the transparency value of each pixel and create light sources.
# single pixel to fully opaque
x, y = 10, 10 # position of the pixel
transparency_array[x, y] = 255
# rectangle 100*100 to fully opaque
width, height = 100, 100 # width and height of the light source
x, y = 200, 200 # x and y position of the center of the light source
transparency_array[x-width/2:x+width/2, y-width/2:y+width/2] = 255
Note that this example is not very efficient, at least not for moving light sources.
If you have a tile-based map you could change your transparencies on a sprite-by-sprite basis. This will be much faster, albeit a little blocky.
-
\$\begingroup\$ Am I just to simply blit the
image
to the screen? I get and error saying that it must be locked. How do I actually display this on the screen? \$\endgroup\$– GoodPieJul 23, 2013 at 9:36 -
\$\begingroup\$ The problem is that pixels_alpha locks the Surface since it is a reference. A fast hack (if you just wish to see it in action) is to delete the array right after use:
del transparency_array
Or you can just put it in a update function so that when you leave the function scope the Surface isn't locked anymore. \$\endgroup\$– bradurJul 24, 2013 at 19:36 -
\$\begingroup\$ Here's a little demo of it using the update function method(warning: uncommented code): gist.github.com/bradur/6073890 \$\endgroup\$– bradurJul 24, 2013 at 19:49