pybeamshow/effects/rotatingpoly.py

88 lines
2.5 KiB
Python
Raw Normal View History

2023-02-24 18:59:24 +01:00
from typing import Any, Optional
2023-02-19 16:03:54 +01:00
import pygame as pg
2023-02-24 18:21:21 +01:00
from effects.effect import MovingEffect
from util.color import Colors, ColorGenerator
2023-02-24 18:59:24 +01:00
from util.transform import PositionGenerator
2023-02-19 16:03:54 +01:00
import math
2023-02-23 02:10:50 +01:00
from typing import Generator
2023-02-19 16:03:54 +01:00
def calc_radii(size, f):
r_c = size / (5 * f + 2)
r_a = size / 2 - r_c
return r_c, r_a
2023-02-24 18:21:21 +01:00
class RotatingPoly(MovingEffect):
2023-02-19 16:03:54 +01:00
def __init__(
self,
bounds: pg.Rect,
2023-02-24 18:21:21 +01:00
color: ColorGenerator,
2023-02-19 16:03:54 +01:00
beat_color: bool = False,
size: int = 100,
rot_speed: float = 5,
outer: int = 5,
2023-02-24 17:23:22 +01:00
spot_factor: float = 0.5,
2023-02-24 18:21:21 +01:00
mover: Optional[PositionGenerator] = None,
2023-02-19 16:03:54 +01:00
*groups: pg.sprite.Group
) -> None:
self.rot_speed = rot_speed
self.rotation = 0.0
self.color = color
self.beat_color = beat_color
self.o_count = outer
2023-02-24 17:23:22 +01:00
self.spot_factor = spot_factor
2023-02-19 16:03:54 +01:00
self.o_f = 1 / math.sin(math.pi / self.o_count)
self.spot_radius, self.o_radius = calc_radii(size, self.o_f)
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,
),
2023-02-24 18:21:21 +01:00
mover,
2023-02-19 16:03:54 +01:00
*groups
)
self.bounds = bounds
2023-02-24 18:21:21 +01:00
self.o_color = next(self.color)
2023-02-19 16:03:54 +01:00
self.update(is_beat=False)
def update(self, *args: Any, **kwargs: Any) -> None:
2023-02-24 18:21:21 +01:00
self.rect.center = self.mover.send((self.rect.size, kwargs["is_beat"]))
2023-02-19 16:03:54 +01:00
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(
2023-02-20 02:00:35 +01:00
self.image, self.o_color, node_positions, width=int(self.spot_radius * 1.5)
2023-02-19 16:03:54 +01:00
)
for pos_x, pos_y in node_positions:
pg.draw.circle(
self.image,
Colors.White,
(pos_x, pos_y),
2023-02-24 17:23:22 +01:00
self.spot_radius * self.spot_factor,
2023-02-19 16:03:54 +01:00
)
self.rotation += self.rot_speed