pybeamshow/effects/spiro.py
2023-02-24 18:21:40 +01:00

93 lines
2.8 KiB
Python

from typing import Any, Optional
import pygame as pg
from effects.effect import MovingEffect
from util.color import Colors, ColorGenerator
from util.transform import PositionGenerator
import random
import math
class Spiro(MovingEffect):
def __init__(
self,
bounds: pg.Rect,
color: ColorGenerator,
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
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,
next(self.color),
self.cursor,
new_cursor,
width=15,
)
self.cursor = new_cursor
self.ticks += self.velocity