pybeamshow/effects/bouncingspot.py

72 lines
2.3 KiB
Python
Raw Normal View History

2023-02-15 21:08:47 +01:00
from typing import Any
import pygame as pg
from effects.effect import Effect
import random
import math
2023-02-15 22:38:02 +01:00
from typing import Union, Generator
2023-02-15 21:08:47 +01:00
class BouncingSpot(Effect):
def __init__(
self,
bounds: pg.Rect,
2023-02-15 22:38:02 +01:00
color: Union[pg.Color, Generator[pg.Color, None, None]],
2023-02-15 21:08:47 +01:00
sizes=(10, 100),
velocity=(1, 10),
x_factor=(0.1, 1),
y_factor=(0.1, 1),
*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 = random.randint(self.min_velocity, self.max_velocity)
self.ticks = random.randint(0, 360)
self.x_factor = random.uniform(x_factor[0], x_factor[1])
self.y_factor = random.uniform(y_factor[0], y_factor[1])
2023-02-15 22:38:02 +01:00
self.color = color
2023-02-15 21:08:47 +01:00
size = (math.sin(self.ticks) / 2 + 0.5) * (
self.max_size - self.min_size
) + self.min_size
image = pg.Surface((self.max_size, self.max_size), flags=pg.SRCALPHA, depth=32)
super().__init__(
image=image,
rect=pg.Rect(
bounds.centerx - size / 2,
bounds.centery - size / 2,
size,
size,
),
*groups
)
self.bounds = bounds
self.update()
def update(self, *args: Any, **kwargs: Any) -> None:
new_size = (math.sin(self.ticks) / 2 + 0.5) * (
self.max_size - self.min_size
) + self.min_size
new_scale = new_size - self.rect.width
self.rect.inflate_ip(new_scale, new_scale)
self.rect.centerx = (
0.4 * math.cos(self.x_factor * self.ticks) * self.bounds.width
+ self.bounds.centerx
)
self.rect.centery = (
0.4 * math.sin(self.y_factor * self.ticks) * self.bounds.height
+ self.bounds.centery
)
self.image.fill(pg.Color(255, 255, 0, 0))
2023-02-15 22:38:02 +01:00
pg.draw.ellipse(
self.image,
self.color if isinstance(self.color, pg.Color) else next(self.color),
((0, 0), self.rect.size),
)
2023-02-15 21:08:47 +01:00
self.ticks += self.velocity / 180 * math.pi
self.velocity = random.randint(self.min_velocity, self.max_velocity)