コード例 #1
0
    def testTwoIntersections(self):
        c = Circle(Point(0.0, 0.0), 1.0)

        p = Ray(Point(-2.0, 0.0), Vector(1.0, 0.0)).intersect(c)
        self.assertEqual(p, Point(-1.0, 0.0))

        c = Circle(Point(0.0, 0.0), 2.0)
        p = Ray(Point(100.0, 100.0), Vector(-1.0, -1.0)).intersect(c)
        self.assertEqual(p, Point(2**0.5, 2**0.5))

        c = Circle(Point(10.0, 10.0), 4.0)
        p = Ray(Point(0.0, 0.0), Vector(1.0, 1.0)).intersect(c)
        self.assertEqual(p, Point(10.0 - 2 * 2**0.5, 10.0 - 2 * 2**0.5))
コード例 #2
0
ファイル: Flipper.py プロジェクト: leordsong/pygame-pinball
    def __init__(self, center: np.ndarray, head_pos: np.ndarray, angle: float, material: Material, name="Flipper",
                 center_r: float = 12.0, head_r: float = 7.0):
        assert type(angle) is float

        self.head = Circle(head_r, Transform(head_pos))
        self.body = ConvexPolygon(self._calculate_points(center, center_r, head_pos, head_r), Transform(center))
        self.tail = Circle(center_r, Transform(center))
        super().__init__(self.tail, material, 100, name=name)

        self.angle = angle
        self.center = center
        self.head_position = head_pos
        self.state = False
        self.prev_time = 0
        self.step = 0
        self.max_step = 20
コード例 #3
0
    def testNoIntersection(self):
        c = Circle(Point(10.0, 10.0), 1.0)

        p = Ray(Point(0.0, 0.0), Vector(1.0, 0.0)).intersect(c)
        self.assertIsNone(p)

        p = Ray(Point(0.0, 0.0), Vector(-1.0, -1.0)).intersect(c)
        self.assertIsNone(p)
コード例 #4
0
    def testOneIntersectionWithOrigInsideCircle(self):
        c = Circle(Point(0.0, 0.0), 1.0)

        p = Ray(Point(0.0, 0.0), Vector(1.0, 0.0)).intersect(c)
        self.assertEqual(p, Point(1.0, 0.0))

        p = Ray(Point(0.0, 0.0), Vector(1.0, 1.0)).intersect(c)
        self.assertEqual(p, Point(0.5 * 2**0.5, 0.5 * 2**0.5))
コード例 #5
0
ファイル: Ball.py プロジェクト: leordsong/pygame-pinball
 def __init__(self,
              position: np.ndarray,
              r: float,
              material: Material,
              mass=1,
              name="TheBall"):
     super().__init__(Circle(r, Transform(position)), material, mass,
                      np.array([0, 0]), np.array([0, 0]), name)
     self.original_position = position
コード例 #6
0
    def testOneIntersectionWithIncidentRay(self):
        c = Circle(Point(0.0, 0.0), 1.0)

        p = Ray(Point(-10.0, 1.0), Vector(1.0, 0.0)).intersect(c)
        self.assertEqual(p, Point(0.0, 1.0))

        p = Ray(Point(-10.0 - 0.5 * 2**0.5, -10.0 + 0.5 * 2**0.5),
                Vector(1.0, 1.0)).intersect(c)
        self.assertEqual(p, Point(-0.5 * 2**0.5, 0.5 * 2**0.5))
コード例 #7
0
ファイル: Flipper.py プロジェクト: leordsong/pygame-pinball
class Flipper(Entity):

    def __init__(self, center: np.ndarray, head_pos: np.ndarray, angle: float, material: Material, name="Flipper",
                 center_r: float = 12.0, head_r: float = 7.0):
        assert type(angle) is float

        self.head = Circle(head_r, Transform(head_pos))
        self.body = ConvexPolygon(self._calculate_points(center, center_r, head_pos, head_r), Transform(center))
        self.tail = Circle(center_r, Transform(center))
        super().__init__(self.tail, material, 100, name=name)

        self.angle = angle
        self.center = center
        self.head_position = head_pos
        self.state = False
        self.prev_time = 0
        self.step = 0
        self.max_step = 20

    def rotate(self, active: bool):
        if active != self.state:
            self.prev_time = pygame.time.get_ticks()
        self.state = active

    def reset(self):
        self.step = 0
        self.state = False
        self.prev_time = 0

    def collide_ball(self, ball) -> bool:
        if ball.shape.collide(self.head):
            self.shape = self.head
            self.material.restitution = 1.5 if self.state else 0.9
            return True
        elif ball.shape.collide(self.body):
            self.shape = self.body
            self.material.restitution = 1.2 if self.state else 0.9
            return True
        elif ball.shape.collide(self.tail):
            self.shape = self.tail
            self.material.restitution = 0.7
            return True
        return False

    def update(self, delta_time: float):
        if self.state:
            if self.step == self.max_step:
                return
            delta_time = pygame.time.get_ticks() - self.prev_time
            steps = int(delta_time / 10)
            self.step = self.step + steps
            if self.step > self.max_step:
                self.step = self.max_step
        else:
            if self.prev_time <= 0 or self.step == 0:
                return
            delta_time = pygame.time.get_ticks() - self.prev_time
            steps = int(delta_time / 10)
            self.step = self.step - steps
            if self.step < 0:
                self.step = 0

        angle = self.angle * self.step / self.max_step
        head_position = self.head_position if angle == 0 else self._rotate(self.center, self.head_position, angle)
        self.head.transform.update(head_position)
        points = self._calculate_points(self.center, self.tail.r, head_position, self.head.r)
        self.body.points = points

    @staticmethod
    def _calculate_points(center, center_r, head, head_r):
        result = []
        length = math.sqrt((head[0] - center[0]) ** 2 + (head[1] - center[1]) ** 2)
        sin_angle = (head[1] - center[1]) / length
        cos_angle = (head[0] - center[0]) / length
        result.append([center[0] - sin_angle * center_r, center[1] + cos_angle * center_r])
        result.append([center[0] + sin_angle * center_r, center[1] - cos_angle * center_r])
        result.append([head[0] + sin_angle * head_r, head[1] - cos_angle * head_r])
        result.append([head[0] - sin_angle * head_r, head[1] + cos_angle * head_r])
        return np.array(result)

    @staticmethod
    def _rotate(origin: np.ndarray, point: np.ndarray, angle: float) -> np.ndarray:
        """
        Rotate a point counterclockwise by a given angle around a given origin.

        The angle should be given in radians.
        """
        p: np.ndarray = point - origin
        qx = math.cos(angle) * p[0] - math.sin(angle) * p[1]
        qy = math.sin(angle) * p[0] + math.cos(angle) * p[1]
        return origin + np.array([qx, qy])

    def draw(self, screen):
        self.head.render(screen, self.material)
        self.body.render(screen, self.material)
        self.tail.render(screen, self.material)
コード例 #8
0
ファイル: __main__.py プロジェクト: leordsong/pygame-pinball
    def init(self):
        self.text_font = pygame.font.Font('freesansbold.ttf', 13)
        self.text_font2 = pygame.font.Font('freesansbold.ttf', 20)

        self.ball = Ball(np.array([280, 454]), 10.0,
                         Material(THECOLORS['green']))

        wall_material = Material(THECOLORS['black'])
        wall_width = 5.0
        self.walls = [
            Wall(np.array([0, 0]), float(self.width), wall_width,
                 wall_material, "UpperWall"),
            Wall(np.array([0, 0]), wall_width, float(self.height),
                 wall_material, "LeftWall"),
            Wall(np.array([self.width - wall_width, 0]), wall_width,
                 float(self.height), wall_material, "RightWall"),
            Wall(np.array([self.width - 25.0, self.height - 35.0]), 10.0, 35.0,
                 wall_material, "Plunger"),
            Entity(ConvexPolygon(
                np.array([[self.width - 40, 0], [self.width, 0],
                          [self.width, 50], [self.width - 40, 20]]),
                Transform(np.array([self.width, self.height]))),
                   wall_material,
                   100,
                   name="TopRight"),
            Entity(ConvexPolygon(
                np.array([[5, self.height - 69], [5, self.height - 97],
                          [57.91117863822124, 434.5569177391425],
                          [46.08882136177876, 455.4430822608575]]),
                Transform(np.array([5, self.height - 69]))),
                   wall_material,
                   100,
                   name="LeftArm"),
            Entity(ConvexPolygon(
                np.array([[self.width - 40, self.height - 97],
                          [self.width - 40, self.height - 69],
                          [215.91117863822123, 455.4430822608575],
                          [204.08882136177877, 434.5569177391425]]),
                Transform(np.array([self.width - 40, self.height - 97]))),
                   wall_material,
                   100,
                   name="RightArm"),
        ]

        self.valve = Valve(
            Rectangle(5.0, self.height - 100.0,
                      Transform(np.array([self.width - 40, 100]))),
            Rectangle(5.0, float(self.height),
                      Transform(np.array([self.width - 40, 0]))),
            wall_material, "MiddleWall")

        bumper_material = Material(THECOLORS['red'], restitution=1.2)
        p = np.array([60, 100])
        p2 = np.array([200, 150])
        w = np.array([15, 0])
        h = np.array([0, 30])
        self.bumpers = [
            Bumper(ConvexPolygon(np.array([p - w, p + h, p + w, p - h]),
                                 Transform(p)),
                   material=bumper_material,
                   name="Bumper1",
                   points=20),
            Bumper(ConvexPolygon(np.array([p2 - w, p2 + h, p2 + w, p2 - h]),
                                 Transform(p)),
                   material=bumper_material,
                   name="Bumper2",
                   points=20),
            # Bumper(Circle(10.0, Transform(np.array(np.array([70, 320])))), material=bumper_material, name="Bumper3"),
            # Bumper(Circle(10.0, Transform(np.array(np.array([190, 320])))), material=bumper_material, name="Bumper4"),
            Bumper(Circle(20.0, Transform((p + p2) / 2 + 3 * h)),
                   material=bumper_material,
                   name="Bumper5",
                   points=5),
        ]

        flipper_material = Material(THECOLORS['red'], restitution=0.7)
        self.left_flipper = Flipper(np.array([52, self.height - 55]),
                                    np.array([102,
                                              self.height - 25]), -math.pi / 4,
                                    flipper_material, 'LeftFlipper')
        self.right_flipper = Flipper(
            np.array([self.width - 90, self.height - 55]),
            np.array([self.width - 140, self.height - 25]), math.pi / 4,
            flipper_material, 'RightFlipper')