pybeamshow/effects/spiro.py
2023-02-23 02:10:50 +01:00

94 lines
2.9 KiB
Python

from typing import Any, Optional
import pygame as pg
from effects.effect import MovingEffect
from util.color import Colors, DynamicColor
from util.transform import PositionGenerator
import random
import math
class Spiro(MovingEffect):
def __init__(
self,
bounds: pg.Rect,
color: DynamicColor,
sizes=(100, 500),
velocity=(0.1, 1),
segments=100,
mover: Optional[PositionGenerator] = None,
*groups: pg.sprite.Group,
) -> None:
self.min_size = sizes[0]
self.max_size = sizes[1]
self.min_velocity = velocity[0]
self.max_velocity = velocity[1]
self.velocity = 0.1 # random.uniform(self.min_velocity, self.max_velocity)
self.ticks = 0.0
self.color = color
self.size = self.max_size
image = pg.Surface((self.max_size, self.max_size))
image.fill(Colors.Black)
image.set_colorkey(Colors.Black)
self.R = random.randint(self.max_size / 6, self.max_size / 2)
self.a = 3 / random.randint(4, 10) # random.uniform(0, 1)
self.k = 3 / random.randint(4, 10) # random.uniform(0, 1)
self.scan_speed = random.randint(1, 100)
self.one_minus_k = 1 - self.k
self.one_minus_k_div_k = self.one_minus_k / self.k
self.ak = self.a * self.k
print(f"R:{self.R} l:{self.a} k:{self.k}")
self.background = pg.Surface((self.max_size, self.max_size))
self.background.fill(Colors.Black)
# self.background.set_alpha(4)
self.background.set_alpha(random.randint(1, 30))
super().__init__(
image,
pg.Rect(
bounds.centerx - self.size / 2,
bounds.centery - self.size / 2,
self.size,
self.size,
),
mover,
*groups,
)
self.bounds = bounds
next(self.mover)
self.cursor = self.calc_pos()
self.update(is_beat=False)
def calc_pos(self):
x = self.max_size / 2 + self.R * (
self.one_minus_k * math.cos(self.ticks)
+ self.ak * math.cos(self.one_minus_k_div_k * self.ticks)
)
y = self.max_size / 2 + self.R * (
self.one_minus_k * math.sin(self.ticks)
- self.ak * math.sin(self.one_minus_k_div_k * self.ticks)
)
return x, y
def update(self, *args: Any, **kwargs: Any) -> None:
self.rect.center = self.mover.send((self.rect.size, kwargs["is_beat"]))
self.image.blit(self.background, (0, 0))
for _ in range(self.scan_speed):
new_cursor = self.calc_pos()
pg.draw.line(
self.image,
self.color if isinstance(self.color, pg.Color) else next(self.color),
self.cursor,
new_cursor,
width=15,
)
self.cursor = new_cursor
self.ticks += self.velocity