Remove extra LIGHT_FILTER from mould.
[tabakrolletjie.git] / tabakrolletjie / enemies.py
1 # Boyd, the friendly, misunderstood turnip loving, light hating space mould
2
3 import pymunk
4 import pymunk.pygame_util
5 import pygame.draw
6 import pygame.surface
7 import pygame.display
8
9 import pygame.locals as pgl
10
11 from .constants import SCREEN_SIZE, MOULD_CATEGORY, OBSTACLE_CATEGORY
12
13 MOULD_FILTER = pymunk.ShapeFilter(
14     mask=MOULD_CATEGORY | OBSTACLE_CATEGORY,
15     categories=MOULD_CATEGORY)
16
17
18 class Mould(pymunk.Body):
19     """A segment of Boyd"""
20
21     def __init__(self, gamestate, space, pos):
22         super(Mould, self).__init__(0, 0, pymunk.Body.STATIC)
23         self.position = pos
24         self._shape = pymunk.Circle(self, 16)
25         space.add(self, self._shape)
26         self._shape.filter = MOULD_FILTER
27         self._resistances = {}
28         self._age = 0
29         self._img = None
30
31     def get_image(self):
32         if not self._img:
33             img = pygame.surface.Surface((32, 32))
34             img.convert_alpha(pygame.display.get_surface())
35             img.fill((0, 0, 0, 0))
36             pygame.draw.circle(img, (255, 255, 255, 255), (16, 16), 16)
37             self._img = img
38         return self._img
39
40     def tick(self, gamestate, space, moulds):
41         """Grow and / or Die"""
42         self._age += 1
43
44         refresh = False
45
46         if (self._age % 15) == 0 and len(moulds) < 1000:
47             # Spawn a new child, if we can
48             spawn = True
49             import random
50             choice = random.randint(0, 4)
51             if choice == 0:
52                 pos = self.position + (0, 24)
53             elif choice == 1:
54                 pos = self.position + (24, 0)
55             elif choice == 2:
56                 pos = self.position + (-24, 0)
57             else:
58                 pos = self.position + (0, -24)
59             # check for bounds
60             if pos[0] < 0 or pos[0] >= SCREEN_SIZE[0]:
61                 spawn = False
62             if pos[1] < 0 or pos[1] >= SCREEN_SIZE[1]:
63                 spawn = False
64             # Check for free space
65             # We allow some overlap, hence not checking full radius
66             query = space.point_query(pos, 8, MOULD_FILTER)
67             if query:
68                 # for x in query:
69                 #     if not isinstance(x.shape.body, Mould):
70                 #         print x.shape, x.shape.body
71                 spawn = False
72             if spawn:
73                 child = Mould(gamestate, space, pos)
74                 moulds.append(child)
75                 refresh = True
76
77         if self._age > 120:
78             # We die of old age
79             space.remove(self, self._shape)
80             moulds.remove(self)
81             refresh = True
82         return refresh
83
84     def damage(self, light_color, intensity):
85         """Take damage for light, adjusted for resistances."""
86
87
88 class Boyd(object):
89
90     def __init__(self, gamestate, space):
91         seed = Mould(gamestate, space, (400, 400))
92         self._moulds = [seed]
93         self._image = pygame.surface.Surface(SCREEN_SIZE)
94         self._image.convert_alpha(pygame.display.get_surface())
95         self._image.fill((0, 0, 0, 0))
96
97     def tick(self, gamestate, space):
98         redraw = False
99         for mould in self._moulds[:]:
100             if mould.tick(gamestate, space, self._moulds):
101                 redraw = True
102         if redraw:
103             self._image.fill((0, 0, 0, 0))
104             for mould in self._moulds:
105                 pos = pymunk.pygame_util.to_pygame(mould.position, self._image)
106                 self._image.blit(mould.get_image(), pos, None,
107                                  pgl.BLEND_RGBA_ADD)
108
109     def render(self, surface):
110         """Draw ourselves"""
111         surface.blit(self._image, (0, 0), None, pgl.BLEND_RGBA_ADD)