Hook up lights and refactor obstacle loading.
[tabakrolletjie.git] / tabakrolletjie / lights.py
1 """ May it be a light for you in dark places, when all other lights go out.
2 """
3
4 import pymunk
5 import pymunk.pygame_util
6 import pygame.draw
7
8
9 class BaseLight(object):
10     """ Common light functionality. """
11
12     def __init__(self, colour, position):
13         self.body = pymunk.Body(0, 0, pymunk.body.Body.STATIC)
14         self.colour = colour
15         self.position = position
16
17     def add(self, space):
18         if self.body.space is not None:
19             space.remove(self.body, *self.body.shapes)
20         shapes = self.determine_ray_polys(space)
21         space.add(self.body, *shapes)
22
23     def determine_ray_polys(self, space):
24         raise NotImplementedError(
25             "Lights should implement .determine_ray_polys.")
26
27     @classmethod
28     def load(cls, config):
29         kw = config.copy()
30         light_type = kw.pop("type")
31         [light_class] = [
32             c for c in cls.__subclasses__()
33             if c.__name__.lower() == light_type]
34         return light_class(**kw)
35
36
37 class SpotLight(BaseLight):
38     def __init__(
39             self, colour="white", position=None, direction=90.0, spread=45.0):
40         super(SpotLight, self).__init__(colour, position)
41         self.direction = direction
42         self.spread = spread
43
44     def determine_ray_polys(self, space):
45         x, y = self.position
46         return [pymunk.Poly(self.body, [
47             self.position, [x + 50, y], [x, y + 50]])]
48
49     def render(self, surface):
50         for shape in self.body.shapes:
51             pygame_poly = [
52                 pymunk.pygame_util.to_pygame(v, surface) for v in
53                 shape.get_vertices()]
54             pygame.draw.polygon(surface, (255, 255, 255), pygame_poly)
55
56
57 class Lamp(BaseLight):
58     def __init__(self, colour="white", position=None, radius=100.0):
59         super(Lamp, self).__init__(colour, position)
60         self.radius = radius