1 """ May it be a light for you in dark places, when all other lights go out.
5 import pymunk.pygame_util
8 from .constants import SCREEN_SIZE, LIGHT_CATEGORY
10 LIGHT_FILTER = pymunk.ShapeFilter(
11 mask=pymunk.ShapeFilter.ALL_MASKS ^ LIGHT_CATEGORY,
12 categories=LIGHT_CATEGORY)
16 """ An iterable that returns ordered rays from pos to the edge of the
17 screen, starting with the edge point (0, 0) and continuing clockwise
18 in pymunk coordinates.
21 left, right, bottom, top = 0, w, 0, h
23 yield pymunk.Vec2d(left, y)
25 yield pymunk.Vec2d(x, top)
26 for y in range(top, -1, -1):
27 yield pymunk.Vec2d(right, y)
28 for x in range(right, -1, -1):
29 yield pymunk.Vec2d(x, bottom)
32 def calculate_ray_polys(space, body, position):
33 position = pymunk.Vec2d(position)
36 for ray in screen_rays(position):
37 info = space.segment_query_first(position, ray, 1, LIGHT_FILTER)
38 point = ray if info is None else info.point
39 vertices.append(point)
41 trial_poly = pymunk.Poly(None, vertices)
42 trial_poly.update(pymunk.Transform.identity())
43 query_prev = trial_poly.point_query(vertices[-2])
44 query_pos = trial_poly.point_query(position)
45 if query_prev.distance < -0.01 or query_pos.distance < -0.01:
46 new_poly = pymunk.Poly(body, vertices[:-1])
47 vertices = [position, vertices[-1]]
48 ray_polys.append(new_poly)
50 ray_polys.append(pymunk.Poly(body, vertices))
51 print "NUM POLYS: ", len(ray_polys)
55 class BaseLight(object):
56 """ Common light functionality. """
58 def __init__(self, colour, position):
59 self.body = pymunk.Body(0, 0, pymunk.body.Body.STATIC)
61 self.position = position
64 if self.body.space is not None:
65 space.remove(self.body, *self.body.shapes)
66 shapes = self.shapes_for_ray_polys(
67 calculate_ray_polys(space, self.body, self.position))
69 shape.filter = LIGHT_FILTER
70 space.add(self.body, *shapes)
72 def shapes_for_ray_polys(self, space):
73 raise NotImplementedError(
74 "Lights should implement .determine_ray_polys.")
77 def load(cls, config):
79 light_type = kw.pop("type")
81 c for c in cls.__subclasses__()
82 if c.__name__.lower() == light_type]
83 return light_class(**kw)
86 class SpotLight(BaseLight):
88 self, colour="white", position=None, direction=90.0, spread=45.0):
89 super(SpotLight, self).__init__(colour, position)
90 self.direction = direction
94 def shapes_for_ray_polys(self, ray_polys):
97 def render(self, surface):
98 subsurface = surface.copy()
100 surface, (255, 255, 0),
101 pymunk.pygame_util.to_pygame(self.position, surface), 5)
102 for shape in self.body.shapes:
104 pymunk.pygame_util.to_pygame(v, surface) for v in
105 shape.get_vertices()]
107 subsurface, (200, 200, 200), pygame_poly, 0)
109 subsurface, (200, 200, 200), True, pygame_poly, 1)
110 subsurface.set_alpha(200)
111 surface.blit(subsurface, (0, 0), None)
114 class Lamp(BaseLight):
115 def __init__(self, colour="white", position=None, radius=100.0):
116 super(Lamp, self).__init__(colour, position)