3
\$\begingroup\$

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?

\$\endgroup\$
2
\$\begingroup\$

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.

\$\endgroup\$
  • \$\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\$ – ReallyGoodPie Jul 23 '13 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\$ – bradur Jul 24 '13 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\$ – bradur Jul 24 '13 at 19:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.