more refactor to mover

This commit is contained in:
Patrick Moessler 2023-02-23 01:56:05 +01:00
parent 5324cfb186
commit 42abc269b2
9 changed files with 262 additions and 125 deletions

View file

@ -41,13 +41,16 @@ class Beamshow:
self.beat_reactive = beat_reactive
self.beat_factor = 1
self.beat_skip_counter = 0
self.last_preset = ""
pg.display.init()
self.window, self.background = self.initialize()
self.audio = AudioProcess()
def initialize(self) -> Tuple[pg.Surface, pg.Surface]:
recreate_effect = not self.effects or pg.display.is_fullscreen == self.windowed
recreate_effect = (
not self.effects or pg.display.is_fullscreen() == self.windowed
)
displays = pg.display.get_desktop_sizes()
if not 0 <= self.display_id < len(displays):
raise ValueError(
@ -72,10 +75,14 @@ class Beamshow:
self.presets = Presets(
bounds=win.get_rect(), beat_reactive=self.beat_reactive
)
if self.randomize:
self.effects = self.presets.randomize()
if self.last_preset and self.last_preset in self.presets:
self.effects = self.presets[self.last_preset]
else:
self.effects = self.presets.default()
if self.randomize:
self.last_preset = self.presets.randomize()
self.effects = self.presets[self.last_preset]
else:
self.effects = self.presets.default()
return win, background
@ -254,8 +261,10 @@ class Beamshow:
while new_preset == self.effects:
new_preset = self.presets.randomize()
print(new_preset)
self.last_preset = new_preset
self.effects.clear()
self.effects.extend(new_preset)
self.effects.extend(self.presets[self.last_preset])
current_fps = self.clock.get_fps()
fps_slidewindow.append(current_fps)

View file

@ -1,22 +1,22 @@
from effects.effect import Effect
from typing import Any
from effects.effect import MovingEffect
from typing import Any, Optional
from typing import Union, Generator
from util.color import Colors
from util.transform import transform_bounce
import math
import pygame as pg
import random
from util.transform import PositionGenerator
class BouncingSpot(Effect):
class BouncingSpot(MovingEffect):
def __init__(
self,
bounds: pg.Rect,
color: Union[pg.Color, Generator[pg.Color, None, None]],
sizes=(10, 100),
velocity=(1, 10),
x_factor=(0.1, 1),
y_factor=(0.1, 1),
mover: Optional[PositionGenerator] = None,
*groups: pg.sprite.Group
) -> None:
self.min_size = sizes[0]
@ -41,13 +41,11 @@ class BouncingSpot(Effect):
size,
size,
),
mover,
*groups
)
self.bounds = bounds
self.bouncer = transform_bounce(
bounds=bounds, velocity=velocity, x_factor=x_factor, y_factor=y_factor
)
next(self.bouncer)
next(self.mover)
self.update(is_beat=False)
def update(self, *args: Any, **kwargs: Any) -> None:
@ -56,9 +54,11 @@ class BouncingSpot(Effect):
) + self.min_size
new_scale = new_size - self.rect.width
if kwargs["is_beat"]:
new_scale *= 1.5
self.rect.inflate_ip(new_scale, new_scale)
self.rect.center = self.bouncer.send((self.rect.size, kwargs["is_beat"]))
self.rect.center = self.mover.send((self.rect.size, kwargs["is_beat"]))
self.image.fill(Colors.Black)
pg.draw.ellipse(

View file

@ -27,6 +27,7 @@ class Moonflower(MovingEffect):
size: int = 100,
rot_speed: float = 5,
outer: int = 5,
inner_factor: float = 1,
*groups: pg.sprite.Group
) -> None:
self.rot_speed = rot_speed
@ -37,7 +38,7 @@ class Moonflower(MovingEffect):
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
self.i_radius = (self.o_radius - self.spot_radius) * 0.5 * inner_factor
image = pg.Surface((size, size))
image.fill(Colors.Black)
@ -54,9 +55,6 @@ class Moonflower(MovingEffect):
*groups,
)
self.bounds = bounds
# self.bouncer = transform_bounce(
# bounds=bounds, velocity=velocity, x_factor=x_factor, y_factor=y_factor, on_beat_random_phase=True
# )
next(self.mover)
self.o_color = (
self.colors[0]

View file

@ -1,12 +1,12 @@
from typing import Any, Tuple
from typing import Any, Optional, Tuple
import pygame as pg
from effects.effect import Effect
from effects.effect import MovingEffect
from util.color import Colors, rainbow_surface
from util.transform import transform_oscillate
from util.transform import PositionGenerator, transform_oscillate
import math
class MovingWave(Effect):
class MovingWave(MovingEffect):
def __init__(
self,
bounds: pg.Rect,
@ -16,24 +16,20 @@ class MovingWave(Effect):
hue: int = 0,
color_inc: int = 1,
start_phase: int = 0,
start_pos: Tuple[int, int] = (-1, -1),
scroll_speed: float = 5,
mover: Optional[PositionGenerator] = None,
*groups: pg.sprite.Group
) -> None:
image = pg.Surface(bounds.size)
image.fill(Colors.Black)
image.set_colorkey(Colors.Black)
super().__init__(image, bounds, *groups)
super().__init__(image, bounds, mover, *groups)
self.subrect = pg.rect.Rect(0, 0, bounds.width, bounds.height)
if not wave_height:
self.wave_height = bounds.height
self.oscillator = None
else:
self.wave_height = wave_height
self.oscillator = transform_oscillate(bounds, 60, start_pos)
next(self.oscillator)
self.wave_height = wave_height or bounds.height
self.bounds = bounds
self.scroll_speed = scroll_speed
next(self.mover)
self.rainbow = pg.Surface((bounds.width, self.wave_height))
rainbow_surface(self.rainbow, "h", hue, color_inc)
@ -79,23 +75,20 @@ class MovingWave(Effect):
# rainbow_surface(self.image)
if self.oscillator:
pos = self.oscillator.send(
((self.bounds.width, self.wave_height), kwargs["is_beat"])
)
# pg.draw.rect(self.image, Colors.Black, (0, 0, self.bounds.width, pos[1]))
# pg.draw.rect(
# self.image,
# Colors.Black,
# (
# 0,
# pos[1] + self.wave_height,
# self.bounds.width,
# self.bounds.height - pos[1] + self.wave_height,
# ),
# )
else:
pos = (0, 0)
pos = self.mover.send(
((self.bounds.width, self.wave_height), kwargs["is_beat"])
)
# pg.draw.rect(self.image, Colors.Black, (0, 0, self.bounds.width, pos[1]))
# pg.draw.rect(
# self.image,
# Colors.Black,
# (
# 0,
# pos[1] + self.wave_height,
# self.bounds.width,
# self.bounds.height - pos[1] + self.wave_height,
# ),
# )
self.image.blit(self.rainbow, pos)
self.image.blit(self.wave_image, pos, self.subrect, pg.BLEND_MULT)

View file

@ -1,8 +1,8 @@
import pygame as pg
from typing import List
from typing import Iterator, List
from random import choice, randint
from random import choice, randint, randrange
from effects.effect import Effect
from util.color import color_darken, color_randomize, color_wheel, Colors
@ -17,7 +17,12 @@ from effects.rotatingpoly import RotatingPoly
from effects.scanreticle import ScanReticle
from effects.spiro import Spiro
from effects.starfield import Starfield
from util.transform import transform_bounce
from util.transform import (
transform_bounce,
transform_falling,
transform_oscillate,
transform_static,
)
class Presets:
@ -26,19 +31,29 @@ class Presets:
self.beat_reactive = beat_reactive
def default(self) -> List[Effect]:
return self.Moonflower()
return self.FallingWave()
def randomize(self) -> List[Effect]:
return getattr(
self,
choice(
[
func
for func in dir(self)
if callable(getattr(self, func)) and not func.startswith("__")
]
),
)()
def __getitem__(self, idx: str) -> List[Effect]:
return getattr(self, idx)()
def __contains__(self, idx: str) -> bool:
return hasattr(self, idx)
def __iter__(self) -> Iterator[str]:
return (
func
for func in dir(self)
if callable(getattr(self, func)) and not func.startswith("__")
)
def randomize(self) -> str:
return choice(
[
func
for func in dir(self)
if callable(getattr(self, func)) and not func.startswith("__")
]
)
def DoubleSpotRandomColor(self) -> List[Effect]:
return [
@ -59,11 +74,25 @@ class Presets:
bounds=self.bounds,
color=color_wheel(),
sizes=(self.bounds.height / 12, self.bounds.height / 10),
mover=transform_bounce(
bounds=self.bounds,
velocity=(1, 1),
x_factor=(1, 1),
y_factor=(2.2, 2.2),
on_beat_phase=90,
),
),
BouncingSpot(
bounds=self.bounds,
color=color_wheel(hue=180),
sizes=(self.bounds.height / 12, self.bounds.height / 10),
mover=transform_bounce(
bounds=self.bounds,
velocity=(1, 1),
x_factor=(1, 1),
y_factor=(2.2, 2.2),
on_beat_phase=180,
),
),
]
@ -74,6 +103,7 @@ class Presets:
wave_count=5,
wave_height=self.bounds.height // 6,
thickness=20,
mover=transform_oscillate(self.bounds, 60, (0, 0)),
),
MovingWave(
bounds=pg.rect.Rect(0, 0, self.bounds.width, self.bounds.height),
@ -81,8 +111,31 @@ class Presets:
wave_count=5,
wave_height=self.bounds.height // 6,
start_phase=120,
start_pos=(0, self.bounds.height * 5 // 6),
thickness=20,
mover=transform_oscillate(
self.bounds, 60, (0, self.bounds.height * 5 // 6)
),
),
]
def FallingWave(self) -> List[Effect]:
bounds = pg.rect.Rect(0, 0, self.bounds.width, self.bounds.height // 3)
return [
MovingWave(
bounds=bounds,
wave_count=8,
wave_height=self.bounds.height // 8,
thickness=20,
hue=30 * randrange(0, 12),
color_inc=0,
scroll_speed=0,
mover=transform_falling(
bounds,
acceleration=0.8,
initial_pos=(0, 0),
initial_velocity=0.01,
on_beat_reset=True,
),
),
]
@ -91,11 +144,15 @@ class Presets:
BouncingSpot(
bounds=self.bounds,
color=Colors.White,
# color=color_wheel(),
sizes=(self.bounds.height / 8, self.bounds.height / 8),
velocity=(1, 1),
x_factor=(1, 1),
y_factor=(2.2, 2.2),
mover=transform_bounce(
bounds=self.bounds,
velocity=(1, 1),
x_factor=(1, 1),
y_factor=(2.2, 2.2),
on_beat_random_phase=180,
),
),
]
@ -135,6 +192,94 @@ class Presets:
)
]
def DoubleMoonflower(self) -> List[Effect]:
hue_left = randrange(0, 360)
hue_right = randrange(0, 360)
size = int(self.bounds.height * 0.75)
return [
Moonflower(
bounds=self.bounds,
colors=(
color_wheel(
hue=hue_left, increase=(75 if self.beat_reactive else 0)
),
color_wheel(
hue=180 + hue_left, increase=(75 if self.beat_reactive else 0)
),
),
beat_color=self.beat_reactive,
size=size,
outer=7,
inner_factor=0.5,
rot_speed=-1.5,
mover=transform_static(position=(size // 2, self.bounds.height // 2)),
),
Moonflower(
bounds=self.bounds,
colors=(
color_wheel(
hue=hue_right, increase=(75 if self.beat_reactive else 0)
),
color_wheel(
hue=180 + hue_right, increase=(75 if self.beat_reactive else 0)
),
),
beat_color=self.beat_reactive,
size=size,
outer=7,
inner_factor=0.5,
rot_speed=1.7,
mover=transform_static(
position=(self.bounds.width - size // 2, self.bounds.height // 2)
),
),
]
def NestedMoonflower(self) -> List[Effect]:
hue_left = randrange(0, 360)
hue_right = randrange(0, 360)
size = int(self.bounds.height * 0.8)
return [
Moonflower(
bounds=self.bounds,
colors=(
color_wheel(
hue=hue_left, increase=(75 if self.beat_reactive else 0)
),
color_wheel(
hue=180 + hue_left, increase=(75 if self.beat_reactive else 0)
),
),
beat_color=self.beat_reactive,
size=size,
outer=7,
inner_factor=0.5,
rot_speed=-1.5,
mover=transform_static(
position=(self.bounds.width // 2, self.bounds.height // 2)
),
),
Moonflower(
bounds=self.bounds,
colors=(
color_wheel(
hue=hue_right, increase=(75 if self.beat_reactive else 0)
),
color_wheel(
hue=180 + hue_right, increase=(75 if self.beat_reactive else 0)
),
),
beat_color=self.beat_reactive,
size=int(size * 0.7),
outer=7,
inner_factor=0.5,
rot_speed=1,
mover=transform_static(
position=(self.bounds.width // 2, self.bounds.height // 2)
),
),
]
def WhiteStarfield(self) -> List[Effect]:
return [
Starfield(
@ -180,9 +325,12 @@ class Presets:
ScanReticle(
self.bounds,
(Colors.Red, Colors.White),
velocity=(1, 1),
x_factor=(0.4, 1),
y_factor=(0.2, 1),
mover=transform_bounce(
bounds=self.bounds,
velocity=(0.5, 1),
x_factor=(3, 3),
y_factor=(0.5, 1),
),
)
]
@ -193,7 +341,12 @@ class Presets:
color=color_wheel(increase=2),
sizes=(self.bounds.height, self.bounds.height),
velocity=(0.1, 0.4),
y_factor=(0.5, 1.5),
mover=transform_bounce(
self.bounds,
velocity=(0.1, 0.4),
x_factor=(1, 1),
y_factor=(0.5, 1.5),
),
),
]

View file

@ -1,13 +1,13 @@
from typing import Any, Tuple
from typing import Any, Optional, Tuple
import pygame as pg
from effects.effect import Effect
from effects.effect import MovingEffect
from util.color import Colors
from util.transform import transform_bounce
import random
from typing import Union, Generator
from util.transform import PositionGenerator
class ScanReticle(Effect):
class ScanReticle(MovingEffect):
def __init__(
self,
bounds: pg.Rect,
@ -15,16 +15,9 @@ class ScanReticle(Effect):
Union[pg.Color, Generator[pg.Color, None, None]],
Union[pg.Color, Generator[pg.Color, None, None]],
],
velocity=(1, 10),
x_factor=(0.1, 1),
y_factor=(0.1, 1),
mover: Optional[PositionGenerator] = None,
*groups: pg.sprite.Group
) -> None:
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.colors = colors
self.bounds = bounds
self.rect_size = min(self.bounds.width // 8, self.bounds.height // 8)
@ -32,18 +25,13 @@ class ScanReticle(Effect):
image = pg.Surface(self.bounds.size)
image.fill(Colors.Black)
image.set_colorkey(Colors.Black)
super().__init__(image, bounds, *groups)
self.bouncer = transform_bounce(
bounds=bounds, velocity=velocity, x_factor=x_factor, y_factor=y_factor
)
next(self.bouncer)
super().__init__(image, bounds, mover, *groups)
next(self.mover)
self.update(is_beat=False)
def update(self, *args: Any, **kwargs: Any) -> None:
target = self.bouncer.send(
((self.rect_size, self.rect_size), kwargs["is_beat"])
)
target = self.mover.send(((self.rect_size, self.rect_size), kwargs["is_beat"]))
self.image.fill(Colors.Black)
@ -66,7 +54,7 @@ class ScanReticle(Effect):
self.rect_size,
self.rect_size,
),
10,
0 if kwargs["is_beat"] else 10,
)
pg.draw.line(
@ -83,6 +71,3 @@ class ScanReticle(Effect):
(target[0], self.bounds.height),
10,
)
# self.ticks += int(self.velocity / 180 * math.pi)
# self.velocity = random.randint(self.min_velocity, self.max_velocity)

View file

@ -1,23 +1,22 @@
from typing import Any
from typing import Any, Optional
import pygame as pg
from effects.effect import Effect
from effects.effect import MovingEffect
from util.color import Colors
from util.transform import transform_bounce
from util.transform import PositionGenerator, transform_bounce
import random
import math
from typing import Union, Generator
class Spiro(Effect):
class Spiro(MovingEffect):
def __init__(
self,
bounds: pg.Rect,
color: Union[pg.Color, Generator[pg.Color, None, None]],
sizes=(100, 500),
velocity=(0.1, 1),
x_factor=(0.1, 1),
y_factor=(0.1, 1),
segments=100,
mover: Optional[PositionGenerator] = None,
*groups: pg.sprite.Group,
) -> None:
self.min_size = sizes[0]
@ -58,13 +57,11 @@ class Spiro(Effect):
self.size,
self.size,
),
mover,
*groups,
)
self.bounds = bounds
self.bouncer = transform_bounce(
bounds=bounds, velocity=velocity, x_factor=x_factor, y_factor=y_factor
)
next(self.bouncer)
next(self.mover)
self.cursor = self.calc_pos()
self.update(is_beat=False)
@ -81,14 +78,7 @@ class Spiro(Effect):
return x, y
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.center = self.bouncer.send((self.rect.size, kwargs["is_beat"]))
self.rect.center = self.mover.send((self.rect.size, kwargs["is_beat"]))
self.image.blit(self.background, (0, 0))
@ -99,9 +89,7 @@ class Spiro(Effect):
self.color if isinstance(self.color, pg.Color) else next(self.color),
self.cursor,
new_cursor,
width=10,
width=15,
)
self.cursor = new_cursor
self.ticks += self.velocity
# self.velocity = random.randint(self.min_velocity, self.max_velocity)

View file

@ -1,6 +1,6 @@
from dataclasses import dataclass
import random
from typing import Generator, Literal
from typing import Generator, Iterable, Literal, Sequence
import pygame as pg
@ -23,7 +23,7 @@ class Colors:
def color_wheel(hue=0, increase=1) -> Generator[pg.Color, None, None]:
color = copy_color(Colors.Red)
h, s, l, a = color.hsla
h = hue
h = hue % 360
while True:
color.hsla = h, s, l, a
@ -84,6 +84,17 @@ def color_fade(
a_f += a_inc
def color_cycle(seq: Sequence[pg.Color]) -> Generator[pg.Color, None, None]:
it = iter(seq)
while True:
yield next(it)
def color_shuffle(seq: Sequence[pg.Color]) -> Generator[pg.Color, None, None]:
while True:
yield random.choice(seq)
def color_darken(color: pg.Color, factor: float) -> pg.Color:
h, s, l, a = color.hsla
new_color = pg.Color(0, 0, 0, 255)

View file

@ -19,6 +19,7 @@ def transform_bounce(
x_factor: Tuple[float, float],
y_factor: Tuple[float, float],
on_beat_random_phase: int = 0,
on_beat_phase: int = 0,
) -> PositionGenerator:
min_velocity = velocity[0]
max_velocity = velocity[1]
@ -43,6 +44,8 @@ def transform_bounce(
inc = current_velocity
if on_beat_random_phase and is_beat:
inc += random.randrange(0, on_beat_random_phase)
if on_beat_phase and is_beat:
inc += on_beat_phase
phase += inc / 180 * math.pi
@ -55,9 +58,6 @@ def transform_oscillate(
pos_y = float(initial_pos[1] if initial_pos[1] > 0 else bounds.top)
direction = "+"
pos_x = bounds.left
pos_y = bounds.top
while True:
(size_x, size_y), _ = yield (int(pos_x), int(pos_y))
@ -103,6 +103,6 @@ def transform_falling(
pos_y += velocity
velocity += acceleration
if (pos_y > range_y) or (on_beat_reset and is_beat):
if (not on_beat_reset and (pos_y > range_y)) or (on_beat_reset and is_beat):
pos_y = initial_pos[1]
velocity = initial_velocity