Peter Shinners wrote:
Thanks for everyone's suggestions and advices. Ironically, I did think of the alpha blitting approach almost immediately after posting, so maybe I should've thought a little bit more about the problem before posting ;-)On Tue, 2005-12-20 at 22:45 +0100, Troels Therkelsen wrote:arr = surfarray.array3d(surf) arr = maximum(zeros(arr.shape), arr - 200)) surfarray.blit_array(surf, arr) I dunno, perhaps there just isn't a significantly faster way of doing this? Please prove me wrong!This could be sped up a few ways. If your image uses an 8bit palette you can quickly modify the palette colors in realtime and blit the new background. You can optimize the Numeric mojo a bit by not worrying about the clamping. def multiply(surface, value): "Value is 0 to 255. So 128 would be 50% darken" arr = pygame.surfarray.array3d(surface) * value arr >>= 8 pygame.surfarray.blit_array(surface, arr) I have gotten away with also creating all black images, setting the alpha level and blitting. I can't guess if this would be slower of faster than the Numeric version. If you are going to redo this many times with the same sized images, you could reuse the "dark" Surface for more speed. def darken(surface, value): "Value is 0 to 255. So 128 would be 50% darken" dark = pygame.Surface(surface.get_size(), 32) dark.set_alpha(value, pygame.RLEACCEL) surface.blit(dark, (0, 0)) For those curious about the outcome, the alpha blitting approach is about 8 times faster than the Numeric approach (using Pete's optimisations above) for my game. It's about 13 times faster than my original code. On my 'slow' setup (1GHz linux server sending X over the network to a 2.6GHz windows box running an X emulator), this means that the delay goes from "noticable, but not unbearably so" to "unnoticable". On my 'fast' (1.7GHz Intel M linux laptop) setup the delay wasn't really noticable in the first place. But I always test on the slow setup, too, because that tends to reveal performance issues pretty early in the process. My game is a level-based puzzle game and everytime you beat (or are defeated by) a level, I want the level area darkened so I can print a game over / level won notice on top of it. However, there's a lot of other elements (score, level name, timers, etc) on the screen that I don't want touched by this darkening. In addition, each level is not necessarily the same size. Since I don't need this done a lot (it's an event that happens exactly once for every level) the speed of the alpha blitting is fast enough for me. Yes, it is tile-based; however many of the tiles are animated on different timers and/or generated runtime so I don't really have a fixed colour palette for all tiles. So I thought that simply telling everything on the level to stop animating/reacting to user input and then darkening the appropriate area of the display would be the simplest approach. My hax0r solution's lack of speed of course disappointed me, hence my original post to this list :-) Anyway, I've ranted on for long enough. Thanks again for the help! ;-) /Troels Therkelsen |
begin:vcard fn:Troels Therkelsen n:Therkelsen;Troels org:Nitram Lexa adr:;;Danmarksvej 5A;Kongens Lyngby;;2800;Denmark email;internet:tt@xxxxxxxxxxxxxx title:Programmer tel;work:+45 70 25 24 23 tel;fax:+45 70 25 29 23 tel;home:+45 38 81 33 66 tel;cell:+45 25 39 14 69 x-mozilla-html:FALSE url:http://www.nitramlexa.com version:2.1 end:vcard