"Lit sprite" functionality in Pygame/SDL?

Started by
6 comments, last by Kylotan 17 years, 1 month ago
I've used this function in Allegro, but cannot seem to find something similar in the documentation that I've come across. I'm using PyGame, and I'm trying to figure out a way to gradually increase the RGB values of an entire sprite. The effect that I'm going for is that the sprite image will gradually brighten, with the whole image eventually turning completely white. I'm looking for a way to increase the RGB value of the image by set values, without going pixel by pixel. Is there any way to do this in PyGame? Thanks!
Advertisement
I seem to remember something about this but haven't been able to verify my recollection. Here's my attempt to explain it:

The reason there is not a function like this in PyGame is that Python supports this functionality internally. You just have to get the surface array and add 0x0111 to it to increase the red, green, and blue bytes of each pixel as one unit rather than pixel-by-pixel. (Note that I did NOT say to use loops to access each pixel individually. The operator overload of the SurfArray should handle this.)

-edit-
The above method doesn't clamp the resultant added values to 255 when an overflow occurs. A safer and easier method would be to create a second surface with a white color and an alpha blend of the amount of white you want added to your sprite color. This may be a little slower but not by much and you get more consistent results.

[Edited by - samuraicrow on March 1, 2007 10:13:44 AM]
Thanks for the response!

I looked into surfarray and tried your method, and you were right. It works, but will crash out if any color value exceeds the 0-255 range. Quite the problem.

I've thought about your second suggestion as well, but I should have mentioned that my original sprite has transparent areas. Blitting a semi-transparent white image over that would ignore these, as far as I can tell. I could theoretically create new trimmed-to-fit sprites to overlay to achieve the desired effect, but that seems like more work than it's worth. I think I may unfortunately have to go this route if there are no other solutions.

It seems like a common operation, and surfarray seems to be designed with this in mind, so you'd figure there'd be a built in function to safely do this.
It's a common operation, but a slow one when dealing with software rendering. Therefore most people would just delegate to OpenGL or Direct3D for such things.
Quote:Original post by Kylotan
It's a common operation, but a slow one when dealing with software rendering. Therefore most people would just delegate to OpenGL or Direct3D for such things.

Hrm, is it possible/common to mix pygame code and openGL code (pyOpenGL I'm guessing)? Are there any tutorials on working with the two in tandem? I have limited openGL experience, but I could run through a few tutorials and learn the basics, but my main confusion would be on how I could work it into my current project (which is 100% pygame). This sounds like it would be very valuable in the future, what's the best way for me to proceed (in learning or in practice)?

Thanks!
I saw a PyGame/PyOpenGL tutorial once, but it was a long time ago. Both of those projects are in limbo at the moment - PyGame 1.8 having been postponed indefinitely from a release date of last December, and PyOpenGL undergoing a complete rewrite for version 3.

You may wish to look at http://www.pygame.org/gamelets/ which has some PyGame/OpenGL tutorials based on the NeHe OpenGL tutorials. I can't vouch for their quality, however.

Since you already have the surfarray method working, I would recommend that you use that for this project, putting in safety checks to avoid the crashes. eg. You may be able to use the 'clip' function to reduce the brightest parts of the image down by an amount equal to that which you'll be adding on, so that the maximum will always end up at 255.

Just try to keep your rendering code as separate from your game code as possible, and eventually you can consider migrating the rendering to PyOpenGL if you need, preferably once the new versions of each are released!
Thanks all, good advice here.

I found a pygame/pyopengl version of the NeHe examples:
http://www.pygame.org/gamelets/#NEHE

And another pygame/pyopengl tutorial dealing with pretty much exactly what I was asking about:
http://disruption.ca/gutil/introduction.html

I think I'll finish my current project as I've already written it, and then look into incorporating openGL into my future outings. I had originally thought that it was mostly used in 3D development, but it definately seems like a valuable asset for 2d game dev as well.

---------------------------------

It seems that I was premature in thinking that I had worked the kinks out of using surfarray. I have an image of a red square, with each pixel being (160,10,10), or close to it.

The following code works:

redsquare = pygame.image.load("red.jpg").convert()a =  pygame.surfarray.array3d(redsquare)redsquare = pygame.surfarray.make_surface(a)


It basically just converts the image surface to an array, and then back to a surface.

The following code breaks:


redsquare = pygame.image.load("red.jpg").convert()a =  pygame.surfarray.array3d(redsquare)a = a + 1redsquare = pygame.surfarray.make_surface(a)


and throws:

Traceback (most recent call last):
redsquare = pygame.surfarray.make_surface(a)
ValueError: unsupported datatype for array


I've compared both arrays (a and a + 1), and it looks like it should be right. a gives me a list of RGB values, and a+1 gives me the same list, with each value incremented by 1 (like I wanted). The two arrays look identical in format, so I'm not sure what the issue is. The only solutions I've found online are "update pygame to the latest version", but it already is.

Thanks again for any help, it's appreciated.
It might be because "a = a + 1" yields values greater than 255.

This topic is closed to new replies.

Advertisement