コード例 #1
0
ファイル: sat.py プロジェクト: overdev/SpaceGame
def get_separating_axis(poly1: list, poly2: list) -> dict:

    axes = get_axes(poly1, poly2)
    sep_dist = float('-inf')
    sep_axis = None

    t = 0
    for axis in axes:
        amin, amax = get_projection(poly1, axis)
        bmin, bmax = get_projection(poly2, axis)
        ax = Vector(*axis)
        pygame.draw.line(pygame.display.get_surface(), (192, 32, 32),
                         (ax * amin) + (400, 300), (ax * amax) + (400, 300))
        pygame.draw.line(pygame.display.get_surface(), (32, 32, 192),
                         (ax * bmin) + (400, 300), (ax * bmax) + (400, 300))
        t += 1

        dist = max(amin, bmin) - min(bmax, amax)
        # dist =  max(bmin, amin) - min(amax, bmax)
        if (amax < bmin) or (bmax < amin):
            return {0: False, 1: Vector(*axis), 2: dist}

        if 0 > dist > sep_dist:
            sep_dist = dist
            sep_axis = axis

    return {0: True, 1: Vector(*sep_axis), 2: sep_dist}
コード例 #2
0
 def __init__(self, actors: list):
     self.actors = []
     self.visible = []
     self.minimum = Vector.zero()
     self.maximum = Vector.one()
     self.view = View(self)
     self.add_actors(actors)
コード例 #3
0
    def play(cls, game: type) -> None:

        dispatcher = Dispatcher([
            SceneOption.BackButton(Vec(100, 540), Vec(100, 40), "Back", None)
        ])
        room = Room([cls.Starship(Vector(300, 200), 0, Vector(50, 50))])

        textcolor = (0, 0, 92)
        fillcolor = (0, 0, 16)
        BitmapFont.set_colors(BitmapFont.large, fillcolor, textcolor)

        while game.scene is cls:
            Display.clear(fillcolor)
            surface = Display.surface()

            events = pygame.event.get()
            keys = pygame.key.get_pressed()
            dispatcher.process_events(events, keys, game)
            room.update(events, keys, room.view, game)

            BitmapFont.render(surface, "Game", BitmapFont.large, (0, 0))

            room.view.render(surface)
            for actor in room.actors:
                actor.default_render(surface, room.view)

            for gui in dispatcher.listeners:
                gui.basic_render(surface)

            Display.on_screen(60)
コード例 #4
0
 def __init__(self, room: 'Room'):
     super(View, self).__init__(Vector.zero(), 0.0, Vector(*self.size),
                                View.refpoints)
     self.motion = Vector.zero()
     self.room = room
     self.anchor = Anchor.top_left
     self.paths = {}
     self.set_path('transition', View.transition, AssignMode.direct_value,
                   0)
     self.parallaxes = [
         BackScroller(View.starfield, self.size, [77, 14]),
         BackScroller(View.starfield, self.size, [28, 56]),
     ]
コード例 #5
0
ファイル: assets.py プロジェクト: overdev/SpaceGame
 def get_position(self, ratio: float, from_angle: float = 0.0) -> Vector:
     """Returns a position in this path relative to given ratio."""
     ratio %= 1.0
     ratio += from_angle / 360.0
     ratio %= 1.0
     angle = 360.0 * ratio
     return Vector.length_angle(self.radius, angle)
コード例 #6
0
ファイル: assets.py プロジェクト: overdev/SpaceGame
 def __init__(self, position: Vector, rotation: float, scale: Vector,
              refpoints: list):
     super(Polygon, self).__init__()
     self.position = position
     self.rotation = rotation
     self.scale = scale
     self.refpoints = refpoints
     self.points = [Vector(*point) for point in refpoints]
     self.draw_points = [v.ixy for v in self.points]
コード例 #7
0
ファイル: assets.py プロジェクト: overdev/SpaceGame
    def __init__(self,
                 bgi: pygame.Surface,
                 surface_size: tuple,
                 view_position=(0, 0)):
        self.back = bgi
        self.view_w, self.view_h = surface_size
        self.view_x, self.view_y = view_position
        self.image_w, self.image_h = bgi.get_size()

        self.origin_x = 0
        self.origin_y = 0
        self.widths = []
        self.heights = []

        self.update(Vector.zero())
コード例 #8
0
ファイル: assets.py プロジェクト: overdev/SpaceGame
    def circle_poly(cls, circle: 'Circle', poly: 'Polygon') -> dict:

        test_distance = -1
        closest_vector = None

        vector_offset = poly.position - circle.position
        vectors = poly.points

        if len(vectors) == 2:
            temp = (vectors[1] - vectors[0]).perpend()
            round(temp)
            vectors.append(vectors[1] + temp)

        # find closest vertex
        for i in range(len(vectors)):
            vec = poly.position + vectors[i]
            dist = (circle.position - vec).hypot
            if test_distance == -1 or dist < test_distance:
                test_distance = dist
                closest_vector = vec

        normal_axis = (closest_vector - circle.position).normalize()

        # project polygon's points
        min1 = normal_axis.dot(vectors[0])
        max1 = min1

        for j in range(1, len(vectors)):
            med = normal_axis.dot(vectors[j])
            min1 = min(min1, med)
            max1 = max(med, max1)

        # project the circle
        max2 = circle.radius
        min2 = -circle.radius

        offset = normal_axis.dot(vector_offset)
        min1 += offset
        max1 += offset

        a = min1 - max2
        b = min2 - max1
        if a > 0 or b > 0:
            return SAT_NO_COLLISION

        # find the normal axis for each point and project
        for i in range(len(vectors)):
            normal_axis = cls.find_normal_axis(vectors, i)
            min1 = normal_axis.dot(vectors[0])
            max1 = min1

            for j in range(1, len(vectors)):
                med = normal_axis.dot(vectors[j])
                min1 = min(min1, med)
                max1 = max(med, max2)

            max2 = circle.radius
            min2 = -circle.radius

            offset = normal_axis.dot(vector_offset)
            min1 += offset
            max1 += offset

            a = min1 - max2
            b = min2 - max1
            if a > 0 or b > 0:
                return SAT_NO_COLLISION

        return {
            SAT.overlapped:
            True,
            SAT.sep_axis:
            Vector(normal_axis.x * (max2 - min1) * -1,
                   normal_axis.y * (max2 - min1) * -1),
            SAT.face_normal:
            normal_axis
        }
コード例 #9
0
ファイル: assets.py プロジェクト: overdev/SpaceGame
 def __init__(self, image: pygame.Surface, scrollratio: Vector):
     self.image = image
     self.scrollratio = scrollratio
     self.scrollpos = Vector.zero()
コード例 #10
0
    def update(self, events: list, keys: tuple, view: 'View',
               game: type) -> None:
        """Updates all objects."""
        indices = range(len(self.actors))

        # events
        for event in events:
            if event.type == c.KEYDOWN:
                cmd = Room.get_command(event)
                for i in indices:
                    self.actors[i].on_command(cmd, game, self)

            elif event.type == c.KEYUP:
                for i in indices:
                    self.actors[i].on_keyup(event.key, game, self)

            elif event.type == c.MOUSEMOTION:
                rpos = Vector(*event.pos)
                apos = self.view.abs_point(event.pos)
                rel = Vector(*event.rel)
                for i in indices:
                    self.actors[i].on_mouse_move(apos, rpos, rel, game, self)

            elif event.type == c.MOUSEBUTTONDOWN:
                rpos = Vector(*event.pos)
                apos = self.view.abs_point(event.pos)
                for i in indices:
                    {
                        1: self.actors[i].on_left_click,
                        2: self.actors[i].on_middle_click,
                        3: self.actors[i].on_right_click,
                        4: self.actors[i].on_roll_up,
                        5: self.actors[i].on_roll_down,
                    }[event.button](apos, rpos, game, self)

        # motion
        self.view.animate(game)
        for i in indices:
            self.actors[i].on_keydown(keys, game, self)
            self.actors[i].animate(game)
            self.actors[i].update(view)

        # collision
        for j in indices:
            a = self.actors[j]
            for k in indices[j + 1:]:
                b = self.actors[k]

                info = a.collide_with(b)
                BitmapFont.set_colors(BitmapFont.small, (0, 0, 0),
                                      (255, 255, 255))
                BitmapFont.render(pygame.display.get_surface(),
                                  "{}".format(list(info.values())),
                                  BitmapFont.small, Vector(0, 300))

                if info[SAT.overlapped]:
                    a.on_collision(b, info, game, self)
                    b.on_collision(a, info, game, self)

        # select visible
        for actor in self.actors:
            info = self.view.collide_with(actor)
            if info[SAT.overlapped]:
                if actor not in self.visible:
                    self.visible.append(actor)
                    actor.on_enter_view(self.view, game, self)
            else:
                if actor in self.visible:
                    self.visible.remove(actor)
                    actor.on_leave_view(self.view, game, self)

        for actor in self.actors:
            actor.on_prerender(game, self)
コード例 #11
0
 def __init__(self, refpoints):
     super(Actor, self).__init__(Vector.zero(), 0.0, Vector.one(),
                                 refpoints)
     self.motion = Vector.zero()
     self.command = None
     self.paths = {}
コード例 #12
0
 def abs_point(self, point: tuple) -> Vector:
     x, y = self.position
     return Vector(point[0] + x, point[1] + y)
コード例 #13
0
 def rel_point(self, point: tuple) -> Vector:
     x, y = self.position
     return Vector(point[0] - x, point[1] - y)