From: Simon Cross Date: Sun, 4 Sep 2016 20:42:31 +0000 (+0200) Subject: Merge branch 'master' of ctpug.org.za:tabakrolletjie X-Git-Tag: tabakrolletjie-v1.0.0~244 X-Git-Url: https://git.ctpug.org.za/?a=commitdiff_plain;h=d4c6abebe81ab103a61c3d7269e982d9ed8a939a;hp=26b52ca902b0a22f30009fb61bc222601e7775fb;p=tabakrolletjie.git Merge branch 'master' of ctpug.org.za:tabakrolletjie --- diff --git a/data/stations/station-alpha.json b/data/stations/station-alpha.json index cf0936a..259f665 100644 --- a/data/stations/station-alpha.json +++ b/data/stations/station-alpha.json @@ -16,6 +16,12 @@ "vertices": [ [800, 400], [850, 400], [850, 450], [800, 450] ] + }, + { + "type": "wall", + "vertices": [ + [200, 350], [250, 350], [250, 400], [200, 400] + ] } ], "lights": [ diff --git a/tabakrolletjie/constants.py b/tabakrolletjie/constants.py index 6f2af9c..d5aebb6 100644 --- a/tabakrolletjie/constants.py +++ b/tabakrolletjie/constants.py @@ -8,3 +8,7 @@ SCREEN_SIZE = (1024, 704) # Frame per second FPS = 60 + +# Pymunk categories +OBSTACLE_CATEGORY = 1 << 0 +LIGHT_CATEGORY = 1 << 1 diff --git a/tabakrolletjie/lights.py b/tabakrolletjie/lights.py index 81740d8..a22ea14 100644 --- a/tabakrolletjie/lights.py +++ b/tabakrolletjie/lights.py @@ -5,6 +5,52 @@ import pymunk import pymunk.pygame_util import pygame.draw +from .constants import SCREEN_SIZE, LIGHT_CATEGORY + +LIGHT_FILTER = pymunk.ShapeFilter( + mask=pymunk.ShapeFilter.ALL_MASKS ^ LIGHT_CATEGORY, + categories=LIGHT_CATEGORY) + + +def screen_rays(pos): + """ An iterable that returns ordered rays from pos to the edge of the + screen, starting with the edge point (0, 0) and continuing clockwise + in pymunk coordinates. + """ + w, h = SCREEN_SIZE + left, right, bottom, top = 0, w, 0, h + for y in range(h): + yield pymunk.Vec2d(left, y) + for x in range(w): + yield pymunk.Vec2d(x, top) + for y in range(top, -1, -1): + yield pymunk.Vec2d(right, y) + for x in range(right, -1, -1): + yield pymunk.Vec2d(x, bottom) + + +def calculate_ray_polys(space, body, position): + position = pymunk.Vec2d(position) + vertices = [position] + ray_polys = [] + for ray in screen_rays(position): + info = space.segment_query_first(position, ray, 1, LIGHT_FILTER) + point = ray if info is None else info.point + vertices.append(point) + if len(vertices) > 3: + trial_poly = pymunk.Poly(None, vertices) + trial_poly.update(pymunk.Transform.identity()) + query_prev = trial_poly.point_query(vertices[-2]) + query_pos = trial_poly.point_query(position) + if query_prev.distance < -0.01 or query_pos.distance < -0.01: + new_poly = pymunk.Poly(body, vertices[:-1]) + vertices = [position, vertices[-1]] + ray_polys.append(new_poly) + if len(vertices) > 2: + ray_polys.append(pymunk.Poly(body, vertices)) + print "NUM POLYS: ", len(ray_polys) + return ray_polys + class BaseLight(object): """ Common light functionality. """ @@ -17,10 +63,13 @@ class BaseLight(object): def add(self, space): if self.body.space is not None: space.remove(self.body, *self.body.shapes) - shapes = self.determine_ray_polys(space) + shapes = self.shapes_for_ray_polys( + calculate_ray_polys(space, self.body, self.position)) + for shape in shapes: + shape.filter = LIGHT_FILTER space.add(self.body, *shapes) - def determine_ray_polys(self, space): + def shapes_for_ray_polys(self, space): raise NotImplementedError( "Lights should implement .determine_ray_polys.") @@ -40,18 +89,26 @@ class SpotLight(BaseLight): super(SpotLight, self).__init__(colour, position) self.direction = direction self.spread = spread + self.i = 0 - def determine_ray_polys(self, space): - x, y = self.position - return [pymunk.Poly(self.body, [ - self.position, [x + 50, y], [x, y + 50]])] + def shapes_for_ray_polys(self, ray_polys): + return ray_polys def render(self, surface): + subsurface = surface.copy() + pygame.draw.circle( + surface, (255, 255, 0), + pymunk.pygame_util.to_pygame(self.position, surface), 5) for shape in self.body.shapes: pygame_poly = [ pymunk.pygame_util.to_pygame(v, surface) for v in shape.get_vertices()] - pygame.draw.polygon(surface, (255, 255, 255), pygame_poly) + pygame.draw.polygon( + subsurface, (200, 200, 200), pygame_poly, 0) + pygame.draw.aalines( + subsurface, (200, 200, 200), True, pygame_poly, 1) + subsurface.set_alpha(200) + surface.blit(subsurface, (0, 0), None) class Lamp(BaseLight): diff --git a/tabakrolletjie/obstacles.py b/tabakrolletjie/obstacles.py index d187a59..32df5b4 100644 --- a/tabakrolletjie/obstacles.py +++ b/tabakrolletjie/obstacles.py @@ -4,6 +4,10 @@ import pymunk import pymunk.pygame_util import pygame.draw +from .constants import OBSTACLE_CATEGORY + +OBSTACLE_FILTER = pymunk.ShapeFilter(categories=OBSTACLE_CATEGORY) + class BaseObstacle(object): def __init__(self): @@ -13,6 +17,8 @@ class BaseObstacle(object): def add(self, space): if self.body.space is not None: space.remove(self.body, *self.body.shapes) + for shape in self.shapes: + shape.filter = OBSTACLE_FILTER space.add(self.body, *self.shapes) def render(self, surface): diff --git a/tabakrolletjie/scenes/night.py b/tabakrolletjie/scenes/night.py index 330530b..bb362b5 100644 --- a/tabakrolletjie/scenes/night.py +++ b/tabakrolletjie/scenes/night.py @@ -23,7 +23,7 @@ class NightScene(BaseScene): light.add(self._space) def render(self, surface, gamestate): - surface.fill((0, 0, 255)) + surface.fill((0, 0, 155)) for obs in self._obstacles: obs.render(surface) for light in self._lights: