[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
Re: [pygame] Masking Test: Simulated Lighting (Follow-Up)
Kris Schnee wrote:
But a problem appeared in trying to make the process more efficient, by
drawing a lightmask on its own, once, then each blitting it onto the
black mask, then blitting the black mask onto the screen. Doing it that
way would be better for complex, gradient lights such as the big one
seen in my previous code. That is, you'd make a (radius*2,radius*2)
surface that's black with a gradually-shaded circle of translucency,
once, then blit it onto solid black each frame. But when I tried that,
Pygame took me too literally.
Try the following code. It uses a gradient light.
import pygame
SCREENSIZE = [800, 600]
LIGHTSIZE = 400
NIGHTCOLOR = [0, 0, 0, 200]
def CreateLight():
gradient = pygame.Surface([LIGHTSIZE, LIGHTSIZE], 0, 8)
gradient.set_palette([[x, x, x] for x in range(256)])
a = NIGHTCOLOR[3]
gradient.fill((a, a, a))
r = LIGHTSIZE/2
for i in range(r):
c = (a * (r-i))/r
pygame.draw.circle(gradient, [c, c, c], [r, r], r-i)
c -= 1
return gradient
def CreateBackground():
bg = pygame.Surface(SCREENSIZE, pygame.SRCALPHA, 32).convert_alpha()
bg.fill((0, 0, 128, 255))
bg.fill((255, 0, 0, 255), (50, 50, 100, 100))
return bg
def CreateNight():
pic = pygame.Surface(SCREENSIZE, pygame.SRCALPHA, 32).convert_alpha()
pic.fill(NIGHTCOLOR)
return pic
def CreateAlpha():
pic = pygame.Surface(SCREENSIZE, 0, 8)
pic.set_palette([[x, x, x] for x in range(256)])
a = NIGHTCOLOR[3]
pic.fill([a, a, a])
return pic
def RefreshNight(night, alpha, light, x, y):
a = NIGHTCOLOR[3]
alpha.fill([a, a, a])
r = LIGHTSIZE/2
alpha.blit(light, [x-r, y-r])
pygame.surfarray.pixels_alpha(night)[:, :] =
pygame.surfarray.pixels2d(alpha)
def main():
pygame.init()
screen = pygame.display.set_mode(SCREENSIZE, 0, 32)
bg = CreateBackground()
circle = CreateLight()
night = CreateNight()
alpha = CreateAlpha()
done = 0
x, y = 400, 300
while not done:
RefreshNight(night, alpha, circle, x, y)
screen.blit(bg, (0, 0))
screen.blit(night, (0, 0))
pygame.display.flip()
pygame.event.pump()
for event in pygame.event.get():
if (event.type == pygame.QUIT) or \
(event.type == pygame.KEYDOWN and event.key ==
pygame.K_ESCAPE):
done = True
break
elif event.type == pygame.MOUSEMOTION:
x, y = event.pos
pygame.quit()
main()