1 """ May it be a light for you in dark places, when all other lights go out.
5 import pymunk.pygame_util
7 import pygame.locals as pgl
9 from .constants import SCREEN_SIZE, LIGHT_CATEGORY
11 LIGHT_FILTER = pymunk.ShapeFilter(
12 mask=pymunk.ShapeFilter.ALL_MASKS ^ LIGHT_CATEGORY,
13 categories=LIGHT_CATEGORY)
17 """ An iterable that returns ordered rays from pos to the edge of the
18 screen, starting with the edge point (0, 0) and continuing clockwise
19 in pymunk coordinates.
22 left, right, bottom, top = 0, w, 0, h
24 yield pymunk.Vec2d(left, y)
26 yield pymunk.Vec2d(x, top)
27 for y in range(top, -1, -1):
28 yield pymunk.Vec2d(right, y)
29 for x in range(right, -1, -1):
30 yield pymunk.Vec2d(x, bottom)
33 def calculate_ray_polys(space, body, position):
34 position = pymunk.Vec2d(position)
37 for ray in screen_rays(position):
38 info = space.segment_query_first(position, ray, 1, LIGHT_FILTER)
39 point = ray if info is None else info.point
40 vertices.append(point)
42 trial_poly = pymunk.Poly(None, vertices)
43 trial_poly.update(pymunk.Transform.identity())
44 query_prev = trial_poly.point_query(vertices[-2])
45 query_pos = trial_poly.point_query(position)
46 if query_prev.distance < -0.01 or query_pos.distance < -0.01:
47 new_poly = pymunk.Poly(body, vertices[:-1])
48 vertices = [position, vertices[-1]]
49 ray_polys.append(new_poly)
51 ray_polys.append(pymunk.Poly(body, vertices))
52 print "NUM POLYS: ", len(ray_polys)
56 class BaseLight(object):
57 """ Common light functionality. """
59 def __init__(self, colour, position):
60 self.body = pymunk.Body(0, 0, pymunk.body.Body.STATIC)
62 self.position = position
65 if self.body.space is not None:
66 space.remove(self.body, *self.body.shapes)
67 shapes = self.shapes_for_ray_polys(
68 calculate_ray_polys(space, self.body, self.position))
70 shape.filter = LIGHT_FILTER
71 space.add(self.body, *shapes)
73 def shapes_for_ray_polys(self, space):
74 raise NotImplementedError(
75 "Lights should implement .determine_ray_polys.")
78 def load(cls, config):
80 light_type = kw.pop("type")
82 c for c in cls.__subclasses__()
83 if c.__name__.lower() == light_type]
84 return light_class(**kw)
87 class SpotLight(BaseLight):
89 self, colour="white", position=None, direction=90.0, spread=45.0):
90 super(SpotLight, self).__init__(colour, position)
91 self.direction = direction
95 def shapes_for_ray_polys(self, ray_polys):
98 # pymunk.Poly(self.body, [self.position, [x + 50, y], [x, y + 50]])]
100 def render(self, surface):
101 subsurface = surface.copy()
103 surface, (255, 255, 0),
104 pymunk.pygame_util.to_pygame(self.position, surface), 5)
105 for shape in self.body.shapes:
107 pymunk.pygame_util.to_pygame(v, surface) for v in
108 shape.get_vertices()]
110 subsurface, (200, 200, 200), pygame_poly, 0)
112 subsurface, (200, 200, 200), True, pygame_poly, 1)
113 subsurface.set_alpha(200)
114 surface.blit(subsurface, (0, 0), None)
117 class Lamp(BaseLight):
118 def __init__(self, colour="white", position=None, radius=100.0):
119 super(Lamp, self).__init__(colour, position)