--- /dev/null
+# Boyd, the friendly, misunderstood turnip loving, light hating space mould
+
+import pymunk
+import pymunk.pygame_util
+import pygame.draw
+import pygame.surface
+import pygame.display
+
+import pygame.locals as pgl
+
+from .constants import SCREEN_SIZE, MOULD_CATEGORY, OBSTACLE_CATEGORY
+
+MOULD_FILTER = LIGHT_FILTER = pymunk.ShapeFilter(
+ mask=MOULD_CATEGORY | OBSTACLE_CATEGORY,
+ categories=MOULD_CATEGORY)
+
+
+class Mould(pymunk.Body):
+ """A segment of Boyd"""
+
+ def __init__(self, gamestate, space, pos):
+ super(Mould, self).__init__(0, 0, pymunk.Body.STATIC)
+ self.position = pos
+ self._shape = pymunk.Circle(self, 16)
+ space.add(self, self._shape)
+ self._shape.filter = MOULD_FILTER
+ self._resistances = {}
+ self._age = 0
+ self._img = None
+
+ def get_image(self):
+ if not self._img:
+ img = pygame.surface.Surface((32, 32))
+ img.convert_alpha(pygame.display.get_surface())
+ img.fill((0, 0, 0, 0))
+ pygame.draw.circle(img, (255, 255, 255, 255), (16, 16), 16)
+ self._img = img
+ return self._img
+
+ def tick(self, gamestate, space, moulds):
+ """Grow and / or Die"""
+ self._age += 1
+
+ refresh = False
+
+ if (self._age % 15) == 0 and len(moulds) < 1000:
+ # Spawn a new child, if we can
+ spawn = True
+ import random
+ choice = random.randint(0, 4)
+ if choice == 0:
+ pos = self.position + (0, 24)
+ elif choice == 1:
+ pos = self.position + (24, 0)
+ elif choice == 2:
+ pos = self.position + (-24, 0)
+ else:
+ pos = self.position + (0, -24)
+ # check for bounds
+ if pos[0] < 0 or pos[0] >= SCREEN_SIZE[0]:
+ spawn = False
+ if pos[1] < 0 or pos[1] >= SCREEN_SIZE[1]:
+ spawn = False
+ # Check for free space
+ # We allow some overlap, hence not checking full radius
+ query = space.point_query(pos, 8, MOULD_FILTER)
+ if query:
+ # for x in query:
+ # if not isinstance(x.shape.body, Mould):
+ # print x.shape, x.shape.body
+ spawn = False
+ if spawn:
+ child = Mould(gamestate, space, pos)
+ moulds.append(child)
+ refresh = True
+
+ if self._age > 120:
+ # We die of old age
+ space.remove(self, self._shape)
+ moulds.remove(self)
+ refresh = True
+ return refresh
+
+ def damage(self, light_color, intensity):
+ """Take damage for light, adjusted for resistances."""
+
+
+class Boyd(object):
+
+ def __init__(self, gamestate, space):
+ seed = Mould(gamestate, space, (400, 400))
+ self._moulds = [seed]
+ self._image = pygame.surface.Surface(SCREEN_SIZE)
+ self._image.convert_alpha(pygame.display.get_surface())
+ self._image.fill((0, 0, 0, 0))
+
+ def tick(self, gamestate, space):
+ redraw = False
+ for mould in self._moulds[:]:
+ if mould.tick(gamestate, space, self._moulds):
+ redraw = True
+ if redraw:
+ self._image.fill((0, 0, 0, 0))
+ for mould in self._moulds:
+ pos = pymunk.pygame_util.to_pygame(mould.position, self._image)
+ self._image.blit(mould.get_image(), pos, None,
+ pgl.BLEND_RGBA_ADD)
+
+ def render(self, surface):
+ """Draw ourselves"""
+ surface.blit(self._image, (0, 0), None, pgl.BLEND_RGBA_ADD)
import pygame.locals as pgl
import pymunk
+import time
from .base import BaseScene
from ..lights import BaseLight
from ..obstacles import BaseObstacle
+from ..enemies import Boyd
from ..events import SceneChangeEvent
+from ..constants import DEBUG
+
class NightScene(BaseScene):
def enter(self, gamestate):
for light in self._lights:
light.add(self._space)
+ self._mould = Boyd(gamestate, self._space)
+
def render(self, surface, gamestate):
+ start_time = time.time()
surface.fill((0, 0, 155))
for light in self._lights:
light.render_light(surface)
obs.render(surface)
for light in self._lights:
light.render(surface)
+ self._mould.render(surface)
+
+ end_time = time.time()
+ if DEBUG:
+ print "Night Render", end_time - start_time
def event(self, ev, gamestate):
if ev.type == pgl.KEYDOWN:
if ev.key in (pgl.K_q, pgl.K_ESCAPE):
from .menu import MenuScene
SceneChangeEvent.post(scene=MenuScene())
+
+ def tick(self, gamestate):
+ start_time = time.time()
+ self._mould.tick(gamestate, self._space)
+ end_time = time.time()
+ if DEBUG:
+ print "Night Tick", end_time - start_time