[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] Masking Test: Simulated Lighting



On Sunday 21 January 2007 22:47, Kris Schnee wrote:
> I was thinking about how to simulate a lighting effect in Pygame: a
> character with a portable light source in a dark room. The code below
> does something like that by creating a black "mask" covering the screen,
> then cutting a partially-transparent hole in it around a certain point.
> For extra fanciness it's not just a circle of "light" but a bunch of
> inefficiently-drawn concentric circles of varying alpha. By applying the
> mask to a blue screen with a few white squares, you get a scene that
> looks dark except where a light source has been drawn.
>
> Besides moving the light sources, using this in a game would probably
> require blitting pre-drawn circles/gradients onto a fresh mask each
> frame, rather than calling pygame.draw.circle over and over. It'd also
> look funny unless you either ordered the light sources to draw the
> brightest last, or somehow summed the RGBA values at each pixel from
> every light source. The second method would be more realistic, since
> that way colored lights would merge rather than one overriding the
> other. It'd also be possible to draw a hole in a non-black background
> like a layer of vines or clouds.
>
> Does this method make sense? Is there a better way of doing it short of
> using OpenGL?
>
> Kris
>
> ------
>
>
> ## <code>
> SCREEN_SIZE = (800,600)
>
> light_size = 100
> light_location = (200,200)
>
> ## Setup
> import pygame
> pygame.init()
> screen = pygame.display.set_mode(SCREEN_SIZE)
>
> ## A black mask for the screen.
> mask = pygame.surface.Surface(SCREEN_SIZE).convert_alpha()
> mask.fill((0,0,0,255))
>
> ## An inefficiently-drawn shaded "light"
> radius = 200
> t = 255
> delta = 3
> while radius > 50:
>      pygame.draw.circle(mask,(0,0,0,t),light_location,radius)
>      t -= delta
>      radius -= delta
> pygame.draw.circle(mask,(0,0,0,95),light_location,radius)
>
> ## A sharp-edged white "light"
> pygame.draw.circle(mask,(0,0,0,0),(400,275),50)
>
> ## A red-tinted "light"
> pygame.draw.circle(mask,(192,0,0,128),(300,375),50)
>
> ## A blue screen with a couple of white squares
> screen.fill((0,0,255))
> pygame.draw.rect(screen,(255,255,255),(100,100,100,100))
> pygame.draw.rect(screen,(255,255,255),(300,250,100,100))
>
> ## Cover the screen with the partly-translucent mask
> screen.blit(mask,(0,0))
>
> ## Make it so
> pygame.display.update()
> ## </code>