Document windows 7 permissions workaround
[tabakrolletjie.git] / tabakrolletjie / obstacles.py
1 """ Obstacles for light and space mould. """
2
3 import pygame.locals as pgl
4
5 import pymunk
6 import pymunk.pygame_util
7 import pygame.draw
8 import pygame.surface
9 from pygame.math import Vector2
10
11 from .constants import (SCREEN_SIZE, OBSTACLE_CATEGORY)
12 from .loader import loader
13
14 OBSTACLE_FILTER = pymunk.ShapeFilter(categories=OBSTACLE_CATEGORY)
15
16
17 class ObstacleManager(object):
18     """ Manages a set of obstacles. """
19
20     def __init__(self, space, gamestate):
21         self._space = space
22         self._obstacles = [
23             BaseObstacle.load(cfg) for cfg in gamestate.station["obstacles"]]
24         for obs in self._obstacles:
25             obs.add(self._space)
26
27     def render(self, surface):
28         for obs in self._obstacles:
29             obs.render(surface)
30
31
32 class BaseObstacle(object):
33     def __init__(self):
34         self.body = pymunk.Body(0, 0, pymunk.body.Body.STATIC)
35         self.shapes = []
36
37     def add(self, space):
38         if self.body.space is not None:
39             space.remove(self.body, *self.body.shapes)
40         for shape in self.shapes:
41             shape.filter = OBSTACLE_FILTER
42         space.add(self.body, *self.shapes)
43
44     def render(self, surface):
45         raise NotImplementedError("Obstacles should implement .render().")
46
47     @classmethod
48     def load(cls, config):
49         kw = config.copy()
50         obstacle_type = kw.pop("type")
51         [obstacle_class] = [
52             c for c in cls.__subclasses__()
53             if c.__name__.lower() == obstacle_type]
54         return obstacle_class(**kw)
55
56
57 class Wall(BaseObstacle):
58
59     def __init__(self, vertices):
60         super(Wall, self).__init__()
61         self.shapes.append(pymunk.Poly(self.body, vertices))
62         self._image = None
63
64     def get_image(self):
65         if self._image is None:
66             self._image = pygame.surface.Surface(SCREEN_SIZE).convert_alpha()
67             self._image.fill((0, 0, 0, 0))
68
69             for shape in self.shapes:
70                 pygame_poly = [
71                     pymunk.pygame_util.to_pygame(v, self._image) for v in
72                     shape.get_vertices()]
73                 pygame.draw.polygon(self._image, (255, 255, 255), pygame_poly)
74
75             wall_texture = loader.load_image(
76                 "textures", "stone.png").convert_alpha()
77             self._image.blit(wall_texture, (0, 0), None, pgl.BLEND_RGBA_MULT)
78
79         return self._image
80
81     def render(self, surface):
82         surface.blit(self.get_image(), (0, 0), None, 0)
83
84
85 class Shrub(BaseObstacle):
86
87     def __init__(self, shrublets):
88         super(Shrub, self).__init__()
89         for (x, y, r) in shrublets:
90             vec = Vector2(0, int(r))
91             STEPS = 18
92             vertices = [
93                 vec.rotate(angle) + (x, y)
94                 for angle in range(0, 360, 360/STEPS)]
95             vertices = [(v.x, v.y) for v in vertices]
96
97             self.shapes.append(pymunk.Poly(self.body, vertices))
98         self.shrublets = shrublets
99         self._image = None
100
101     def get_image(self):
102         if self._image is None:
103             self._image = pygame.surface.Surface(SCREEN_SIZE).convert_alpha()
104             self._image.fill((0, 0, 0, 0))
105
106             for (x, y, r) in self.shrublets:
107                 centre = pymunk.pygame_util.to_pygame((x, y), self._image)
108                 pygame.draw.circle(self._image, (255, 255, 255), centre, r)
109
110             shrub_texture = loader.load_image(
111                 "textures", "shrub.png").convert_alpha()
112             self._image.blit(shrub_texture, (0, 0), None, pgl.BLEND_RGBA_MULT)
113
114         return self._image
115
116     def render(self, surface):
117         surface.blit(self.get_image(), (0, 0), None, 0)