From 5b75d2f6a5714e9a278da2447c9d07ac1f6c1eb2 Mon Sep 17 00:00:00 2001 From: Anthony Samms Date: Fri, 5 Sep 2025 23:09:57 -0400 Subject: [PATCH] add fever bouncers --- libs/background.py | 13 +++++++++-- libs/bg_objects/fever.py | 49 ++++++++++++++++++++++++++++++++++++++++ scenes/game.py | 8 +++++-- scenes/song_select.py | 2 +- 4 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 libs/bg_objects/fever.py diff --git a/libs/background.py b/libs/background.py index 875eb33..5521026 100644 --- a/libs/background.py +++ b/libs/background.py @@ -3,31 +3,40 @@ import random from libs.bg_objects.bg_fever import BGFever from libs.bg_objects.bg_normal import BGNormal from libs.bg_objects.don_bg import DonBG +from libs.bg_objects.fever import Fever from libs.texture import TextureWrapper class Background: - def __init__(self, player_num: int): + def __init__(self, player_num: int, bpm: float): self.tex_wrapper = TextureWrapper() self.tex_wrapper.load_animations('background') self.donbg = DonBG.create(self.tex_wrapper, random.randint(0, 5), player_num) self.bg_normal = BGNormal.create(self.tex_wrapper, random.randint(0, 4)) self.bg_fever = BGFever.create(self.tex_wrapper, random.randint(0, 3)) self.footer = Footer(self.tex_wrapper, random.randint(0, 2)) + self.fever = Fever.create(self.tex_wrapper, random.randint(0, 3), bpm) self.is_clear = False - def update(self, current_time_ms: float, is_clear: bool): + self.is_rainbow = False + def update(self, current_time_ms: float, bpm: float, is_clear: bool, is_rainbow: bool): if not self.is_clear and is_clear: self.bg_fever.start() + if not self.is_rainbow and is_rainbow: + self.fever.start() self.is_clear = is_clear + self.is_rainbow = is_rainbow self.donbg.update(current_time_ms, self.is_clear) self.bg_normal.update(current_time_ms) self.bg_fever.update(current_time_ms) + self.fever.update(current_time_ms, bpm) def draw(self): self.bg_normal.draw(self.tex_wrapper) if self.is_clear: self.bg_fever.draw(self.tex_wrapper) self.footer.draw(self.tex_wrapper) self.donbg.draw(self.tex_wrapper) + if self.is_rainbow: + self.fever.draw(self.tex_wrapper) def unload(self): self.tex_wrapper.unload_textures() diff --git a/libs/bg_objects/fever.py b/libs/bg_objects/fever.py new file mode 100644 index 0000000..ad1b1a6 --- /dev/null +++ b/libs/bg_objects/fever.py @@ -0,0 +1,49 @@ +from libs.animation import Animation +from libs.texture import TextureWrapper + +class Fever: + + @staticmethod + def create(tex: TextureWrapper, index: int, bpm: float): + map = [Fever0, Fever1, Fever2, Fever3] + selected_obj = map[index] + return selected_obj(tex, index, bpm) + +class BaseFever: + def __init__(self, tex: TextureWrapper, index: int, bpm: float): + self.name = 'fever_' + str(index) + tex.load_zip('background', f'fever/{self.name}') + self.bounce_up = Animation.create_move((60000 / bpm) / 2, total_distance=50, ease_out='quadratic') + self.bounce_down = Animation.create_move((60000 / bpm) / 2, total_distance=50, ease_in='quadratic', delay=self.bounce_up.duration) + + def start(self): + self.bounce_down.start() + self.bounce_up.start() + + def update(self, current_time_ms: int, bpm: float): + self.bounce_up.update(current_time_ms) + self.bounce_down.update(current_time_ms) + if self.bounce_down.is_finished: + self.bounce_up.duration = (60000 / bpm) / 2 + self.bounce_down.duration = (60000 / bpm) / 2 + self.bounce_up.restart() + self.bounce_down.restart() + +class Fever0(BaseFever): + def draw(self, tex: TextureWrapper): + tex.draw_texture(self.name, 'overlay_l', y=self.bounce_down.attribute-self.bounce_up.attribute) + tex.draw_texture(self.name, 'overlay_r', y=self.bounce_down.attribute-self.bounce_up.attribute) + +class Fever1(BaseFever): + def draw(self, tex: TextureWrapper): + tex.draw_texture(self.name, 'overlay_l', y=self.bounce_down.attribute-self.bounce_up.attribute) + tex.draw_texture(self.name, 'overlay_r', y=self.bounce_down.attribute-self.bounce_up.attribute) + +class Fever2(BaseFever): + def draw(self, tex: TextureWrapper): + tex.draw_texture(self.name, 'overlay_l', y=self.bounce_down.attribute-self.bounce_up.attribute) + tex.draw_texture(self.name, 'overlay_r', y=self.bounce_down.attribute-self.bounce_up.attribute) + +class Fever3(BaseFever): + def draw(self, tex: TextureWrapper): + tex.draw_texture(self.name, 'overlay', y=self.bounce_down.attribute-self.bounce_up.attribute) diff --git a/scenes/game.py b/scenes/game.py index 75aad20..be4979e 100644 --- a/scenes/game.py +++ b/scenes/game.py @@ -86,15 +86,17 @@ class GameScreen: self.movie = None self.song_music = None tex.load_screen_textures('game') - self.background = Background(global_data.player_num) self.load_sounds() self.init_tja(global_data.selected_song, session_data.selected_difficulty) self.song_info = SongInfo(session_data.song_title, 'TEST') self.result_transition = ResultTransition(global_data.player_num) + self.bpm = 0 if self.tja is not None: subtitle = self.tja.metadata.subtitle.get(global_data.config['general']['language'].lower(), '') + self.bpm = self.tja.metadata.bpm else: subtitle = '' + self.background = Background(global_data.player_num, self.bpm) self.transition = Transition(session_data.song_title, subtitle, is_second=True) self.transition.start() @@ -154,7 +156,9 @@ class GameScreen: if self.movie is not None: self.movie.update() else: - self.background.update(get_current_ms(), self.player_1.gauge.gauge_length > self.player_1.gauge.clear_start[min(self.player_1.difficulty, 3)]) + if len(self.player_1.current_bars) > 0: + self.bpm = self.player_1.current_bars[0].bpm + self.background.update(get_current_ms(), self.bpm, self.player_1.gauge.gauge_length > self.player_1.gauge.clear_start[min(self.player_1.difficulty, 3)], self.player_1.gauge.gauge_length == 87) self.player_1.update(self) self.song_info.update(get_current_ms()) diff --git a/scenes/song_select.py b/scenes/song_select.py index 9f4c502..cad6289 100644 --- a/scenes/song_select.py +++ b/scenes/song_select.py @@ -1699,7 +1699,7 @@ class FileNavigator: tja_files = self._get_tja_files_for_directory(dir_path) # Create SongFile objects - for i, tja_path in enumerate(tja_files): + for tja_path in sorted(tja_files): song_key = str(tja_path) if song_key not in self.all_song_files: song_obj = SongFile(tja_path, tja_path.name, texture_index)