From 4eb30dc6fa6a3ba1cdf40f8fe42ff6621a7305d9 Mon Sep 17 00:00:00 2001 From: Yonokid <37304577+Yonokid@users.noreply.github.com> Date: Tue, 2 Sep 2025 22:24:35 -0400 Subject: [PATCH] finish adding fever backgrounds --- PyTaiko.py | 2 +- libs/backgrounds.py | 181 ++++++++++++++++++++++++++++++++++++++++---- libs/tja.py | 2 +- scenes/result.py | 4 +- 4 files changed, 171 insertions(+), 18 deletions(-) diff --git a/PyTaiko.py b/PyTaiko.py index a9bd419..2ad8664 100644 --- a/PyTaiko.py +++ b/PyTaiko.py @@ -83,7 +83,7 @@ def main(): if global_data.config["video"]["fullscreen"]: ray.toggle_fullscreen() - current_screen = Screens.LOADING + current_screen = Screens.DEV_MENU audio.init_audio_device() diff --git a/libs/backgrounds.py b/libs/backgrounds.py index 3b6a3fd..b69b9ef 100644 --- a/libs/backgrounds.py +++ b/libs/backgrounds.py @@ -1,5 +1,8 @@ +import math import random +import pyray as ray + from libs.animation import Animation from libs.texture import TextureWrapper @@ -10,7 +13,7 @@ class Background: 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, 3) + self.bg_fever = BGFever.create(self.tex_wrapper, random.randint(0, 3)) self.footer = Footer(self.tex_wrapper, random.randint(0, 2)) self.is_clear = False def update(self, current_time_ms: float, is_clear: bool): @@ -331,7 +334,7 @@ class BGFever: @staticmethod def create(tex: TextureWrapper, index: int): - map = [BGFever1, BGFever2, None, BGFever4] + map = [BGFever1, BGFever2, BGFever3, BGFever4] selected_obj = map[index] return selected_obj(tex, index) @@ -342,43 +345,195 @@ class BGFeverBase: self.transitioned = False class BGFever1(BGFeverBase): + class Tile: + def __init__(self): + self.expansion = Animation.create_move(166, total_distance=360) + self.expansion.start() + def update(self, current_time_ms): + self.expansion.update(current_time_ms) + def draw(self, tex: TextureWrapper, name: str, x: int, frame: int): + tex.draw_texture(name, 'background', frame=frame, x=x, y2=-360+self.expansion.attribute, y=360+(180-self.expansion.attribute/2)) def __init__(self, tex: TextureWrapper, index: int): super().__init__(tex, index) - pass + self.wait = 0 + self.bg_tiles: list[BGFever1.Tile] = [] + self.corner_move_up = tex.get_animation(29) + self.corner_move_down = tex.get_animation(30) + self.footer_move_up = tex.get_animation(29, is_copy=True) + self.footer_move_down = tex.get_animation(30, is_copy=True) + self.footer_move_up.delay_saved = 100 + self.footer_move_down.delay_saved = 100 + + self.mountain_move_up = tex.get_animation(29, is_copy=True) + self.mountain_move_down = tex.get_animation(30, is_copy=True) + self.mountain_move_up.delay_saved = 200 + self.mountain_move_down.delay_saved = 200 + + self.overlay_move_up = tex.get_animation(29, is_copy=True) + self.overlay_move_down = tex.get_animation(30, is_copy=True) + self.overlay_move_up.delay_saved = 300 + self.overlay_move_down.delay_saved = 300 + + self.wave_spin = tex.get_animation(28) + self.circle = { + "center_x": 100, + "center_y": 130, + "radius": 200, + } + self.bg_move = tex.get_animation(16) def start(self): - pass + self.corner_move_up.start() + self.corner_move_down.start() + self.footer_move_up.start() + self.footer_move_down.start() + self.mountain_move_up.start() + self.mountain_move_down.start() + self.overlay_move_up.start() + self.overlay_move_down.start() def update(self, current_time_ms: float): - pass + if len(self.bg_tiles) < 20 and current_time_ms >= self.wait + 66: + self.bg_tiles.append(BGFever1.Tile()) + self.wait = current_time_ms + for tile in self.bg_tiles: + tile.update(current_time_ms) + self.corner_move_up.update(current_time_ms) + self.corner_move_down.update(current_time_ms) + self.footer_move_up.update(current_time_ms) + self.footer_move_down.update(current_time_ms) + self.mountain_move_up.update(current_time_ms) + self.mountain_move_down.update(current_time_ms) + self.overlay_move_up.update(current_time_ms) + self.overlay_move_down.update(current_time_ms) + self.wave_spin.update(current_time_ms) + self.is_transitioned = self.overlay_move_down.is_finished and len(self.bg_tiles) == 20 + self.bg_move.update(current_time_ms) + def draw(self, tex: TextureWrapper): - pass + for i, tile in enumerate(self.bg_tiles): + tile.draw(tex, self.name, (i*128)-self.bg_move.attribute, i % 10) + tex.draw_texture(self.name, 'mountain', y=-self.mountain_move_up.attribute+self.mountain_move_down.attribute) + angle = math.radians(self.wave_spin.attribute*2) + wave_x = self.circle["center_x"] + math.cos(angle) * self.circle["radius"] + wave_y = self.circle["center_y"] + math.sin(angle) * self.circle["radius"] + wave_origin = ray.Vector2(tex.textures[self.name]['wave'].width/2,tex.textures[self.name]['wave'].height/2) + tex.draw_texture(self.name, 'wave', x=wave_x, y=wave_y, origin=wave_origin) + tex.draw_texture(self.name, 'footer', y=-self.footer_move_up.attribute+self.footer_move_down.attribute) + tex.draw_texture(self.name, 'corner', y=-self.corner_move_up.attribute+self.corner_move_down.attribute) + tex.draw_texture(self.name, 'overlay', y=self.overlay_move_up.attribute-self.overlay_move_down.attribute) class BGFever2(BGFeverBase): def __init__(self, tex: TextureWrapper, index: int): super().__init__(tex, index) self.fadein = tex.get_animation(19) self.bg_texture_change = tex.get_animation(20) - self.ship_rotation = Animation.create_fade(1000, initial_opacity=0.0, final_opacity=1.0, reverse_delay=0, loop=True) + self.ship_rotation = tex.get_animation(21) self.ship_rotation.start() + self.move_in = tex.get_animation(22) + self.move_out = tex.get_animation(23) def start(self): self.fadein.start() + self.move_in.start() + self.move_out.start() def update(self, current_time_ms: float): self.fadein.update(current_time_ms) self.bg_texture_change.update(current_time_ms) self.ship_rotation.update(current_time_ms) + self.move_in.update(current_time_ms) + self.move_out.update(current_time_ms) + self.transitioned = self.move_out.is_finished def draw(self, tex: TextureWrapper): tex.draw_texture(self.name, 'background', frame=self.bg_texture_change.attribute, fade=self.fadein.attribute) - tex.draw_texture(self.name, 'footer_3', fade=self.fadein.attribute) - tex.draw_texture(self.name, 'footer_1', fade=self.fadein.attribute) - tex.draw_texture(self.name, 'footer_2', fade=self.fadein.attribute) - tex.draw_texture(self.name, 'bird', index=0, mirror='horizontal') - tex.draw_texture(self.name, 'bird', index=1) - tex.draw_texture(self.name, 'ship', rotation=self.ship_rotation.attribute*100, center=True) + tex.draw_texture(self.name, 'footer_3', y=self.move_in.attribute-self.move_out.attribute, fade=self.fadein.attribute) + tex.draw_texture(self.name, 'footer_1', y=self.move_in.attribute-self.move_out.attribute, fade=self.fadein.attribute) + tex.draw_texture(self.name, 'footer_2', y=self.move_in.attribute-self.move_out.attribute, fade=self.fadein.attribute) + tex.draw_texture(self.name, 'bird', index=0, x=self.move_in.attribute-self.move_out.attribute, mirror='horizontal', y=self.ship_rotation.attribute*180) + tex.draw_texture(self.name, 'bird', index=1, x=-self.move_in.attribute+self.move_out.attribute, y=self.ship_rotation.attribute*180) + origin = ray.Vector2(tex.textures[self.name]['ship'].width/2, tex.textures[self.name]['ship'].height/2) + tex.draw_texture(self.name, 'ship', x=origin.x, y=origin.y + self.move_in.attribute-self.move_out.attribute, origin=origin, rotation=self.ship_rotation.attribute*100, center=True) + +class BGFever3(BGFeverBase): + def __init__(self, tex: TextureWrapper, index: int): + super().__init__(tex, index) + self.fadein = tex.get_animation(19) + self.move_in = tex.get_animation(24) + self.footer_move_up = tex.get_animation(26) + self.bird_tc = tex.get_animation(20) + self.overlay_tc = tex.get_animation(25) + self.circle_rotate = tex.get_animation(27) + self.fish_spin = tex.get_animation(28) + + self.circle = { + "center_x": 500, + "center_y": 300, + "radius": 300, + } + + self.num_fish = 8 + self.fish_spacing = (2 * math.pi) / self.num_fish # 45 degrees in radians + + def start(self): + self.fadein.start() + self.move_in.start() + self.footer_move_up.start() + + def update(self, current_time_ms: float): + self.fadein.update(current_time_ms) + self.move_in.update(current_time_ms) + self.bird_tc.update(current_time_ms) + self.overlay_tc.update(current_time_ms) + self.footer_move_up.update(current_time_ms) + self.circle_rotate.update(current_time_ms) + self.fish_spin.update(current_time_ms) + self.transitioned = self.move_in.is_finished + + def draw(self, tex: TextureWrapper): + tex.draw_texture(self.name, 'background', x=-self.move_in.attribute) + tex.draw_texture(self.name, 'overlay', frame=self.overlay_tc.attribute, fade=self.fadein.attribute) + origin = ray.Vector2(tex.textures[self.name]['circle'].width/2, tex.textures[self.name]['circle'].height/2) + tex.draw_texture(self.name, 'circle', x=origin.x, y=origin.y, fade=self.fadein.attribute, origin=origin, rotation=self.circle_rotate.attribute) + + angle = math.radians(self.fish_spin.attribute*2) + wave_x = self.circle["center_x"] + math.cos(angle) * self.circle["radius"] + wave_y = self.circle["center_y"] + math.sin(angle) * self.circle["radius"] + wave_origin = ray.Vector2(tex.textures[self.name]['wave'].width/2,tex.textures[self.name]['wave'].height/2) + tex.draw_texture(self.name, 'wave', x=wave_x, y=wave_y, fade=self.fadein.attribute, origin=wave_origin) + + for j in range(2): + for i in range(self.num_fish): + fish_phase_offset = i * self.fish_spacing + angle = math.radians(self.fish_spin.attribute) + fish_phase_offset + fish_x = self.circle["center_x"] + math.cos(angle) * self.circle["radius"] + fish_y = self.circle["center_y"] + math.sin(angle) * self.circle["radius"] + + # Fish should face the direction they're swimming (tangent to circle) + swimming_angle = angle + math.pi/2 # Perpendicular to radius + swimming_rotation = math.degrees(swimming_angle) + + fish_origin = ray.Vector2(tex.textures[self.name]['fish'].width/2,tex.textures[self.name]['fish'].height/2) + + tex.draw_texture(self.name, 'fish', x=fish_x, y=fish_y, fade=self.fadein.attribute, + origin=fish_origin, + rotation=swimming_rotation, + index=j + ) + + angle = math.radians(self.fish_spin.attribute*3) + wave_x = self.circle["center_x"] + math.cos(angle) * 20 + wave_y = self.circle["center_y"] + math.sin(angle) * 20 + wave_origin = ray.Vector2(tex.textures[self.name]['wave'].width/2,tex.textures[self.name]['wave'].height/2) + for i in range(3): + tex.draw_texture(self.name, 'footer_2', x=wave_x + (i*600), y=wave_y, fade=self.fadein.attribute, origin=wave_origin) + + for i in range(3): + tex.draw_texture(self.name, 'footer_1', x=i*450, y=-self.footer_move_up.attribute) + tex.draw_texture(self.name, 'bird', frame=self.bird_tc.attribute, index=0, x=-self.move_in.attribute) + tex.draw_texture(self.name, 'bird', frame=self.bird_tc.attribute, index=1, x=-self.move_in.attribute) class BGFever4(BGFeverBase): def __init__(self, tex: TextureWrapper, index: int): diff --git a/libs/tja.py b/libs/tja.py index 3850229..c00e93a 100644 --- a/libs/tja.py +++ b/libs/tja.py @@ -204,7 +204,7 @@ class TJAParser: region_code = 'en' if item[len('SUBTITLE')] != ':': region_code = (item[len('SUBTITLE'):len('SUBTITLE')+2]).lower() - self.metadata.subtitle[region_code] = ''.join(item.split(':')[1:]) + self.metadata.subtitle[region_code] = ''.join(item.split(':')[1:]).replace('--', '') if 'ja' in self.metadata.subtitle and '限定' in self.metadata.subtitle['ja']: self.ex_data.limited_time = True elif item.startswith('TITLE'): diff --git a/scenes/result.py b/scenes/result.py index b41aa59..ab87fd1 100644 --- a/scenes/result.py +++ b/scenes/result.py @@ -153,7 +153,7 @@ class ResultScreen: alpha_value = ray.ffi.new('float*', self.fade_in_bottom.attribute) ray.set_shader_value(self.alpha_shader, alpha_loc, alpha_value, SHADER_UNIFORM_FLOAT) - if get_current_ms() >= self.start_ms + 5000: + if get_current_ms() >= self.start_ms + 5000 and not self.fade_out.is_started: self.handle_input() self.update_score_animation() @@ -404,8 +404,6 @@ class ScoreAnimator: def next_score(self) -> str: if self.digit_index == -1: self.is_finished = True - if self.target_score == '0': - return '0' return str(int(''.join([str(item[0]) for item in self.current_score_list]))) curr_digit, counter = self.current_score_list[self.digit_index] if counter < 9: