From e6bbddb01dc99ffc035182480593a49ceb119c04 Mon Sep 17 00:00:00 2001 From: Patrick Moessler Date: Sun, 19 Feb 2023 16:03:54 +0100 Subject: [PATCH] Add rotating polygon effect --- effects/rotatingpoly.py | 97 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 effects/rotatingpoly.py diff --git a/effects/rotatingpoly.py b/effects/rotatingpoly.py new file mode 100644 index 0000000..28657ab --- /dev/null +++ b/effects/rotatingpoly.py @@ -0,0 +1,97 @@ +from typing import Any, Tuple +import pygame as pg +from effects.effect import Effect, Colors, transform_bounce +import random +import math +from typing import Union, Generator + + +def calc_radii(size, f): + r_c = size / (5 * f + 2) + r_a = size / 2 - r_c + return r_c, r_a + + +class RotatingPoly(Effect): + def __init__( + self, + bounds: pg.Rect, + color: Union[pg.Color, Generator[pg.Color, None, None]], + beat_color: bool = False, + size: int = 100, + velocity: Tuple[float, float] = (1, 10), + rot_speed: float = 5, + outer: int = 5, + x_factor: Tuple[float, float] = (0.1, 1), + y_factor: Tuple[float, float] = (0.1, 1), + *groups: pg.sprite.Group + ) -> None: + # self.min_velocity = velocity[0] + # self.max_velocity = velocity[1] + + self.rot_speed = rot_speed + self.rotation = 0.0 + # self.velocity = random.uniform(self.min_velocity, self.max_velocity) + self.color = color + self.beat_color = beat_color + self.o_count = outer + + self.o_f = 1 / math.sin(math.pi / self.o_count) + + self.spot_radius, self.o_radius = calc_radii(size, self.o_f) + # self.i_radius = (self.o_radius - self.spot_radius) * 0.5 + + image = pg.Surface((size, size)) + image.fill(Colors.Black) + image.set_colorkey(Colors.Black) + super().__init__( + image, + pg.Rect( + bounds.centerx - size / 2, + bounds.centery - size / 2, + size, + size, + ), + *groups + ) + self.bounds = bounds + self.bouncer = transform_bounce( + bounds=bounds, velocity=velocity, x_factor=x_factor, y_factor=y_factor + ) + next(self.bouncer) + self.o_color = ( + self.color if isinstance(self.color, pg.Color) else next(self.color) + ) + self.update(is_beat=False) + + def update(self, *args: Any, **kwargs: Any) -> None: + self.rect.center = self.bouncer.send(self.rect.size) + + self.image.fill(Colors.Black) + + if not self.beat_color or kwargs["is_beat"]: + if isinstance(self.color, Generator): + self.o_color = next(self.color) + + node_positions = [] + for phi in range(0, 360, 360 // self.o_count): + rads = math.pi * (phi + self.rotation) / 180 + pos_x = int(self.rect.width // 2 + self.o_radius * math.cos(rads)) + pos_y = int(self.rect.height // 2 + self.o_radius * math.sin(rads)) + node_positions.append((pos_x, pos_y)) + + pg.draw.polygon( + self.image, self.o_color, node_positions, width=int(self.spot_radius*1.5) + ) + + for pos_x, pos_y in node_positions: + pg.draw.circle( + self.image, + Colors.White, + (pos_x, pos_y), + self.spot_radius, + ) + + self.rotation += self.rot_speed + # self.ticks += int(self.velocity / 180 * math.pi) + # self.velocity = random.uniform(self.min_velocity, self.max_velocity)