From 7066dc385b3b943e5c22a4b0c304bfa6bae1906d Mon Sep 17 00:00:00 2001 From: Anthony Samms Date: Mon, 17 Nov 2025 20:10:36 -0500 Subject: [PATCH] this update doubles the fps --- PyTaiko.py | 18 +++++-- libs/file_navigator.py | 3 +- libs/texture.py | 97 +++++++++++++++++++-------------- libs/utils.py | 9 ++-- libs/video.py | 23 +++++--- scenes/game.py | 111 ++++++++++++++++++-------------------- scenes/practice/game.py | 10 ++-- scenes/song_select.py | 3 +- scenes/two_player/game.py | 5 +- 9 files changed, 154 insertions(+), 125 deletions(-) diff --git a/PyTaiko.py b/PyTaiko.py index 97230a6..dacb705 100644 --- a/PyTaiko.py +++ b/PyTaiko.py @@ -20,7 +20,6 @@ from libs.tja import TJAParser from libs.utils import ( force_dedicated_gpu, get_config, - get_key_code, global_data, global_tex ) @@ -208,16 +207,17 @@ def main(): ray.gen_texture_mipmaps(target.texture) ray.set_texture_filter(target.texture, ray.TextureFilter.TEXTURE_FILTER_TRILINEAR) ray.rl_set_blend_factors_separate(RL_SRC_ALPHA, RL_ONE_MINUS_SRC_ALPHA, RL_ONE, RL_ONE_MINUS_SRC_ALPHA, RL_FUNC_ADD, RL_FUNC_ADD) - ray.set_exit_key(get_key_code(global_data.config["keys"]["exit_key"])) + ray.set_exit_key(global_data.config["keys"]["exit_key"]) ray.hide_cursor() logger.info("Cursor hidden") + last_fps = 1 while not ray.window_should_close(): - if ray.is_key_pressed(get_key_code(global_data.config["keys"]["fullscreen_key"])): + if ray.is_key_pressed(global_data.config["keys"]["fullscreen_key"]): ray.toggle_fullscreen() logger.info("Toggled fullscreen") - elif ray.is_key_pressed(get_key_code(global_data.config["keys"]["borderless_key"])): + elif ray.is_key_pressed(global_data.config["keys"]["borderless_key"]): ray.toggle_borderless_windowed() logger.info("Toggled borderless windowed mode") @@ -248,7 +248,15 @@ def main(): global_data.input_locked = 0 if global_data.config["general"]["fps_counter"]: - ray.draw_fps(20, 20) + curr_fps = ray.get_fps() + if curr_fps != 0 and curr_fps != last_fps: + last_fps = curr_fps + if last_fps < 30: + ray.draw_text(f'{last_fps} FPS', 20, 20, 20, ray.RED) + elif last_fps < 60: + ray.draw_text(f'{last_fps} FPS', 20, 20, 20, ray.YELLOW) + else: + ray.draw_text(f'{last_fps} FPS', 20, 20, 20, ray.LIME) ray.end_blend_mode() ray.end_texture_mode() ray.begin_drawing() diff --git a/libs/file_navigator.py b/libs/file_navigator.py index b3e4bb1..f6ba42b 100644 --- a/libs/file_navigator.py +++ b/libs/file_navigator.py @@ -1346,8 +1346,7 @@ class FileNavigator: """Get crowns for a directory, calculating only if needed""" if dir_key in self.crown_cache_dirty or dir_key not in self.directory_crowns: # Calculate crowns on-demand - dir_path = Path(dir_key) - tja_files = self._get_tja_files_for_directory(dir_path) + tja_files = self.directory_contents[dir_key] self._calculate_directory_crowns(dir_key, tja_files) self.crown_cache_dirty.discard(dir_key) diff --git a/libs/texture.py b/libs/texture.py index 14ca9a1..6e6fec8 100644 --- a/libs/texture.py +++ b/libs/texture.py @@ -5,9 +5,10 @@ import logging import tempfile import zipfile from pathlib import Path -from typing import Optional, Union +from typing import Any, Optional -import pyray as ray +import raylib as ray +from pyray import Vector2, Rectangle, Color from libs.animation import BaseAnimation, parse_animations @@ -23,7 +24,7 @@ class Coordinates: class Texture: """Texture class for managing textures and animations.""" - def __init__(self, name: str, texture: Union[ray.Texture, list[ray.Texture]], init_vals: dict[str, int]): + def __init__(self, name: str, texture: Any, init_vals: dict[str, int]): self.name = name self.texture = texture self.init_vals = init_vals @@ -66,13 +67,13 @@ class TextureWrapper: logger.warning(f"Duplicate texture ID {texture.id}: {ids[texture.id]} and {zip}/{file}[{i}]") else: ids[texture.id] = f"{zip}/{file}[{i}]" - ray.unload_texture(texture) + ray.UnloadTexture(texture) else: if tex_object.texture.id in ids: logger.warning(f"Duplicate texture ID {tex_object.texture.id}: {ids[tex_object.texture.id]} and {zip}/{file}") else: ids[tex_object.texture.id] = f"{zip}/{file}" - ray.unload_texture(tex_object.texture) + ray.UnloadTexture(tex_object.texture) self.textures.clear() self.animations.clear() @@ -147,10 +148,10 @@ class TextureWrapper: extracted_path = Path(temp_dir) / tex_name if extracted_path.is_dir(): - frames = [ray.load_texture(str(frame)) for frame in sorted(extracted_path.iterdir(), + frames = [ray.LoadTexture(str(frame).encode('utf-8')) for frame in sorted(extracted_path.iterdir(), key=lambda x: int(x.stem)) if frame.is_file()] else: - frames = [ray.load_texture(str(extracted_path))] + frames = [ray.LoadTexture(str(extracted_path).encode('utf-8'))] self.textures[zip.stem][tex_name] = Texture(tex_name, frames, tex_mapping) self._read_tex_obj_data(tex_mapping, self.textures[zip.stem][tex_name]) elif f"{tex_name}.png" in zip_ref.namelist(): @@ -162,7 +163,7 @@ class TextureWrapper: temp_path = temp_file.name try: - tex = ray.load_texture(temp_path) + tex = ray.LoadTexture(temp_path.encode('utf-8')) self.textures[zip.stem][tex_name] = Texture(tex_name, tex, tex_mapping) self._read_tex_obj_data(tex_mapping, self.textures[zip.stem][tex_name]) finally: @@ -192,25 +193,58 @@ class TextureWrapper: def control(self, tex_object: Texture, index: int = 0): '''debug function''' distance = 1 - if ray.is_key_down(ray.KeyboardKey.KEY_LEFT_SHIFT): + if ray.IsKeyDown(ray.KEY_LEFT_SHIFT): distance = 10 - if ray.is_key_pressed(ray.KeyboardKey.KEY_LEFT): + if ray.IsKeyPressed(ray.KEY_LEFT): tex_object.x[index] -= distance logger.info(f"{tex_object.name}: {tex_object.x[index]}, {tex_object.y[index]}") - if ray.is_key_pressed(ray.KeyboardKey.KEY_RIGHT): + if ray.IsKeyPressed(ray.KEY_RIGHT): tex_object.x[index] += distance logger.info(f"{tex_object.name}: {tex_object.x[index]}, {tex_object.y[index]}") - if ray.is_key_pressed(ray.KeyboardKey.KEY_UP): + if ray.IsKeyPressed(ray.KEY_UP): tex_object.y[index] -= distance logger.info(f"{tex_object.name}: {tex_object.x[index]}, {tex_object.y[index]}") - if ray.is_key_pressed(ray.KeyboardKey.KEY_DOWN): + if ray.IsKeyPressed(ray.KEY_DOWN): tex_object.y[index] += distance logger.info(f"{tex_object.name}: {tex_object.x[index]}, {tex_object.y[index]}") - def draw_texture(self, subset: str, texture: str, color: ray.Color=ray.WHITE, frame: int = 0, scale: float = 1.0, center: bool = False, + def _draw_texture_untyped(self, subset: str, texture: str, color: tuple[int, int, int, int], frame: int, scale: float, center: bool, + mirror: str, x: float, y: float, x2: float, y2: float, + origin: tuple[float, float], rotation: float, fade: float, + index: int, src: Optional[tuple[float, float, float, float]], controllable: bool) -> None: + mirror_x = -1 if mirror == 'horizontal' else 1 + mirror_y = -1 if mirror == 'vertical' else 1 + if fade != 1.1: + final_color = ray.Fade(color, fade) + else: + final_color = color + tex_object = self.textures[subset][texture] + if src is not None: + source_rect = src + else: + source_rect = (0, 0, tex_object.width * mirror_x, tex_object.height * mirror_y) + if center: + dest_rect = (tex_object.x[index] + (tex_object.width//2) - ((tex_object.width * scale)//2) + x, tex_object.y[index] + (tex_object.height//2) - ((tex_object.height * scale)//2) + y, tex_object.x2[index]*scale + x2, tex_object.y2[index]*scale + y2) + else: + dest_rect = (tex_object.x[index] + x, tex_object.y[index] + y, tex_object.x2[index]*scale + x2, tex_object.y2[index]*scale + y2) + + if tex_object.is_frames: + if not isinstance(tex_object.texture, list): + raise Exception("Texture was marked as multiframe but is only 1 texture") + if frame >= len(tex_object.texture): + raise Exception(f"Frame {frame} not available in iterable texture {tex_object.name}") + ray.DrawTexturePro(tex_object.texture[frame], source_rect, dest_rect, origin, rotation, final_color) + else: + if isinstance(tex_object.texture, list): + raise Exception("Texture is multiframe but was called as 1 texture") + ray.DrawTexturePro(tex_object.texture, source_rect, dest_rect, origin, rotation, final_color) + if tex_object.controllable[index] or controllable: + self.control(tex_object) + + def draw_texture(self, subset: str, texture: str, color: Color = Color(255, 255, 255, 255), frame: int = 0, scale: float = 1.0, center: bool = False, mirror: str = '', x: float = 0, y: float = 0, x2: float = 0, y2: float = 0, - origin: ray.Vector2 = ray.Vector2(0,0), rotation: float = 0, fade: float = 1.1, - index: int = 0, src: Optional[ray.Rectangle] = None, controllable: bool = False) -> None: + origin: Vector2 = Vector2(0,0), rotation: float = 0, fade: float = 1.1, + index: int = 0, src: Optional[Rectangle] = None, controllable: bool = False) -> None: """ Wrapper function for raylib's draw_texture_pro(). Parameters: @@ -232,33 +266,14 @@ class TextureWrapper: src (Optional[ray.Rectangle]): The source rectangle of the texture. controllable (bool): Whether the texture is controllable. """ - mirror_x = -1 if mirror == 'horizontal' else 1 - mirror_y = -1 if mirror == 'vertical' else 1 - if fade != 1.1: - final_color = ray.fade(color, fade) - else: - final_color = color - tex_object = self.textures[subset][texture] if src is not None: - source_rect = src + src_data = (src.x, src.y, src.width, src.height) else: - source_rect = ray.Rectangle(0, 0, tex_object.width * mirror_x, tex_object.height * mirror_y) - if center: - dest_rect = ray.Rectangle(tex_object.x[index] + (tex_object.width//2) - ((tex_object.width * scale)//2) + x, tex_object.y[index] + (tex_object.height//2) - ((tex_object.height * scale)//2) + y, tex_object.x2[index]*scale + x2, tex_object.y2[index]*scale + y2) + src_data = None + if isinstance(color, tuple): + color_data = (color[0], color[1], color[2], color[3]) else: - dest_rect = ray.Rectangle(tex_object.x[index] + x, tex_object.y[index] + y, tex_object.x2[index]*scale + x2, tex_object.y2[index]*scale + y2) - - if tex_object.is_frames: - if not isinstance(tex_object.texture, list): - raise Exception("Texture was marked as multiframe but is only 1 texture") - if frame >= len(tex_object.texture): - raise Exception(f"Frame {frame} not available in iterable texture {tex_object.name}") - ray.draw_texture_pro(tex_object.texture[frame], source_rect, dest_rect, origin, rotation, final_color) - else: - if isinstance(tex_object.texture, list): - raise Exception("Texture is multiframe but was called as 1 texture") - ray.draw_texture_pro(tex_object.texture, source_rect, dest_rect, origin, rotation, final_color) - if tex_object.controllable[index] or controllable: - self.control(tex_object) + color_data = (color.r, color.g, color.b, color.a) + self._draw_texture_untyped(subset, texture, color_data, frame, scale, center, mirror, x, y, x2, y2, (origin.x, origin.y), rotation, fade, index, src_data, controllable) tex = TextureWrapper() diff --git a/libs/utils.py b/libs/utils.py index 37d9ad4..8ddffab 100644 --- a/libs/utils.py +++ b/libs/utils.py @@ -10,6 +10,7 @@ from pathlib import Path from typing import Optional import pyray as ray +import raylib as rl import tomlkit from raylib import ( SHADER_UNIFORM_FLOAT, @@ -83,7 +84,7 @@ def get_config() -> Config: config: Config = json.loads(json.dumps(config_file)) for key in config['keys']: - config[key] = get_key_code(config['keys'][key]) + config['keys'][key] = get_key_code(config['keys'][key]) for key in config['keys_1p']: bindings = config['keys_1p'][key] for i, bind in enumerate(bindings): @@ -116,12 +117,12 @@ def is_input_key_pressed(keys: list[int], gamepad_buttons: list[int]): if global_data.input_locked: return False for key in keys: - if ray.is_key_pressed(key): + if rl.IsKeyPressed(key): return True - if ray.is_gamepad_available(0): + if rl.IsGamepadAvailable(0): for button in gamepad_buttons: - if ray.is_gamepad_button_pressed(0, button): + if rl.IsGamepadButtonPressed(0, button): return True return False diff --git a/libs/video.py b/libs/video.py index a6b862a..d6b99fa 100644 --- a/libs/video.py +++ b/libs/video.py @@ -1,7 +1,7 @@ from pathlib import Path import logging -import pyray as ray +import raylib as ray from moviepy import VideoFileClip from libs.audio import audio @@ -52,13 +52,24 @@ class VideoPlayer: frame_data = self.video.get_frame(time_sec) if self.texture is None: - image = ray.Image(frame_data, self.video.w, self.video.h, 1, ray.PixelFormat.PIXELFORMAT_UNCOMPRESSED_R8G8B8) - self.texture = ray.load_texture_from_image(image) + if frame_data is None: + return False + frame_bytes = frame_data.tobytes() + pixels_ptr = ray.ffi.cast('void *', ray.ffi.from_buffer('unsigned char[]', frame_bytes)) + + image = ray.ffi.new('Image *', { + 'data': pixels_ptr, + 'width': self.video.w, + 'height': self.video.h, + 'mipmaps': 1, + 'format': ray.PIXELFORMAT_UNCOMPRESSED_R8G8B8 + }) + self.texture = ray.LoadTextureFromImage(image[0]) else: if frame_data is not None: frame_bytes = frame_data.tobytes() pixels_ptr = ray.ffi.cast('void *', ray.ffi.from_buffer('unsigned char[]', frame_bytes)) - ray.update_texture(self.texture, pixels_ptr) + ray.UpdateTexture(self.texture, pixels_ptr) self.current_frame_data = frame_data return True @@ -108,14 +119,14 @@ class VideoPlayer: def draw(self): """Draw video frames to the raylib canvas""" if self.texture is not None: - ray.draw_texture(self.texture, 0, 0, ray.WHITE) + ray.DrawTexture(self.texture, 0, 0, ray.WHITE) def stop(self): """Stops the video, audio, and clears its buffer""" self.video.close() if self.texture is not None: - ray.unload_texture(self.texture) + ray.UnloadTexture(self.texture) self.texture = None if self.audio is not None: diff --git a/scenes/game.py b/scenes/game.py index a7d9519..9b3d21b 100644 --- a/scenes/game.py +++ b/scenes/game.py @@ -31,7 +31,6 @@ from libs.transition import Transition from libs.utils import ( OutlinedText, get_current_ms, - get_key_code, global_data, global_tex, is_l_don_pressed, @@ -1224,13 +1223,13 @@ class Judgment: self.big = big self.is_finished = False - self.fade_animation_1 = Animation.create_fade(132, initial_opacity=0.5, delay=100) - self.fade_animation_1.start() - self.fade_animation_2 = Animation.create_fade(316 - 233.3, delay=233.3) - self.fade_animation_2.start() - self.move_animation = Animation.create_move(83, total_distance=15, start_position=144) + self.fade_animation_1 = tex.get_animation(27, is_copy=True) + self.fade_animation_2 = tex.get_animation(28, is_copy=True) + self.move_animation = tex.get_animation(29, is_copy=True) + self.texture_animation = tex.get_animation(30, is_copy=True) self.move_animation.start() - self.texture_animation = Animation.create_texture_change(100, textures=[(33, 50, 0), (50, 83, 1), (83, 100, 2), (100, float('inf'), 3)]) + self.fade_animation_2.start() + self.fade_animation_1.start() self.texture_animation.start() def update(self, current_ms): @@ -1323,14 +1322,14 @@ class GaugeHitEffect: self.note_type = note_type self.is_big = big self.texture_change = tex.get_animation(2, is_copy=True) + self.circle_fadein = tex.get_animation(31, is_copy=True) + self.resize = tex.get_animation(32, is_copy=True) + self.fade_out = tex.get_animation(33, is_copy=True) + self.rotation = tex.get_animation(34, is_copy=True) self.texture_change.start() - self.circle_fadein = Animation.create_fade(133, initial_opacity=0.0, final_opacity=1.0, delay=16.67) self.circle_fadein.start() - self.resize = Animation.create_texture_resize(233, delay=self.texture_change.duration, initial_size=0.75, final_size=1.15) self.resize.start() - self.fade_out = Animation.create_fade(66, delay=233) self.fade_out.start() - self.rotation = Animation.create_fade(300, delay=116.67, initial_opacity=0.0, final_opacity=1.0) self.rotation.start() self.color = ray.fade(ray.YELLOW, self.circle_fadein.attribute) self.is_finished = False @@ -1779,17 +1778,17 @@ class ScoreCounterAnimation: self.is_2p = is_2p self.counter = counter self.direction = -1 if self.is_2p else 1 - self.fade_animation_1 = Animation.create_fade(50, initial_opacity=0.0, final_opacity=1.0) + self.fade_animation_1 = tex.get_animation(35, is_copy=True) + self.move_animation_1 = tex.get_animation(36, is_copy=True) + self.fade_animation_2 = tex.get_animation(37, is_copy=True) + self.move_animation_2 = tex.get_animation(38, is_copy=True) + self.move_animation_3 = tex.get_animation(39, is_copy=True) + self.move_animation_4 = tex.get_animation(40, is_copy=True) self.fade_animation_1.start() - self.move_animation_1 = Animation.create_move(80, total_distance=-20, start_position=175) self.move_animation_1.start() - self.fade_animation_2 = Animation.create_fade(80, delay=366.74) self.fade_animation_2.start() - self.move_animation_2 = Animation.create_move(66, total_distance=5, start_position=145, delay=80) self.move_animation_2.start() - self.move_animation_3 = Animation.create_move(66, delay=279.36, total_distance=-2, start_position=146) self.move_animation_3.start() - self.move_animation_4 = Animation.create_move(80, delay=366.74, total_distance=10, start_position=148) self.move_animation_4.start() if player_num == PlayerNum.P2: @@ -1928,7 +1927,7 @@ class ComboAnnounce: self.is_2p = is_2p self.combo = combo self.wait = current_time_ms - self.fade = Animation.create_fade(100) + self.fade = tex.get_animation(65) self.fade.start() self.is_finished = False self.audio_played = False @@ -1977,11 +1976,11 @@ class BranchIndicator: self.is_2p = is_2p self.difficulty = 'normal' self.diff_2 = self.difficulty - self.diff_down = Animation.create_move(100, total_distance=20, ease_out='quadratic') - self.diff_up = Animation.create_move(133, total_distance=70, delay=self.diff_down.duration, ease_out='quadratic') - self.diff_fade = Animation.create_fade(133, delay=self.diff_down.duration) - self.level_fade = Animation.create_fade(116, initial_opacity=0.0, final_opacity=1.0, reverse_delay=116*10) - self.level_scale = Animation.create_texture_resize(116, initial_size=1.0, final_size=1.2, reverse_delay=0) + self.diff_down = tex.get_animation(41) + self.diff_up = tex.get_animation(42) + self.diff_fade = tex.get_animation(43) + self.level_fade = tex.get_animation(44) + self.level_scale = tex.get_animation(45) self.direction = 1 def update(self, current_time_ms): self.diff_down.update(current_time_ms) @@ -2023,24 +2022,24 @@ class FailAnimation: """Animates the fail effect""" def __init__(self, is_2p: bool): self.is_2p = is_2p - self.bachio_fade_in = Animation.create_fade(150, initial_opacity=0.0, final_opacity=1.0) + self.bachio_fade_in = tex.get_animation(46) + self.bachio_texture_change = tex.get_animation(47) + self.bachio_fall = tex.get_animation(48) + self.bachio_move_out = tex.get_animation(49) + self.bachio_boom_fade_in = tex.get_animation(50) + self.bachio_boom_scale = tex.get_animation(51) + self.bachio_up = tex.get_animation(52) + self.bachio_down = tex.get_animation(53) + self.text_fade_in = tex.get_animation(54) + self.text_fade_in.start() self.bachio_fade_in.start() - self.bachio_texture_change = Animation.create_texture_change(266.67, textures=[(0, 150, 0), (150, 266.67, 1)], delay=self.bachio_fade_in.duration) - self.bachio_fall = Animation.create_texture_change(500, textures=[[0, 495, 0], [495, 500, 1]], delay=self.bachio_texture_change.duration) self.bachio_texture_change.start() self.bachio_fall.start() - self.bachio_move_out = Animation.create_move(116.67, total_distance=150, delay=self.bachio_fade_in.duration, ease_out='quadratic') self.bachio_move_out.start() - self.bachio_boom_fade_in = Animation.create_fade(66.67, initial_opacity=0.0, final_opacity=1.0, reverse_delay=0, delay=self.bachio_fade_in.duration + self.bachio_move_out.duration) - self.bachio_boom_scale = Animation.create_texture_resize(133.34, initial_size=0.5, final_size=1.0, delay=self.bachio_fade_in.duration + self.bachio_move_out.duration) self.bachio_boom_fade_in.start() self.bachio_boom_scale.start() - self.bachio_up = Animation.create_move(416.67, total_distance=60, delay=self.bachio_fade_in.duration + self.bachio_move_out.duration, ease_out='quadratic') - self.bachio_down = Animation.create_move(100, total_distance=60, delay=self.bachio_fade_in.duration + self.bachio_move_out.duration + self.bachio_up.duration, ease_out='quadratic') self.bachio_up.start() self.bachio_down.start() - self.text_fade_in = Animation.create_fade(283.33, initial_opacity=0.0, final_opacity=1.0, delay=self.bachio_fade_in.duration + self.bachio_move_out.duration + self.bachio_up.duration/2) - self.text_fade_in.start() self.name = 'in' self.frame = self.bachio_texture_change.attribute audio.play_sound('fail', 'sound') @@ -2070,13 +2069,13 @@ class ClearAnimation: """Animates the clear effect""" def __init__(self, is_2p: bool): self.is_2p = is_2p - self.bachio_fade_in = Animation.create_fade(150, initial_opacity=0.0, final_opacity=1.0) + self.bachio_fade_in = tex.get_animation(46) self.bachio_fade_in.start() - self.bachio_texture_change = Animation.create_texture_change(266.67, textures=[(0, 150, 0), (150, 266.67, 1)], delay=self.bachio_fade_in.duration) + self.bachio_texture_change = tex.get_animation(47) self.bachio_texture_change.start() - self.bachio_out = Animation.create_texture_change(200, textures=[[0, 50, 0], [50, 100, 1], [100, 150, 2], [150, 200, 3]], delay=self.bachio_texture_change.duration+100) + self.bachio_out = tex.get_animation(55) self.bachio_out.start() - self.bachio_move_out = Animation.create_move(116.67, total_distance=200, delay=self.bachio_fade_in.duration, ease_out='quadratic') + self.bachio_move_out = tex.get_animation(66) self.bachio_move_out.start() self.clear_separate_fade_in = [Animation.create_fade(100, initial_opacity=0.0, final_opacity=1.0, delay=i*50) for i in range(5)] for fade in self.clear_separate_fade_in: @@ -2084,7 +2083,7 @@ class ClearAnimation: self.clear_separate_stretch = [Animation.create_text_stretch(200, delay=i*50) for i in range(5)] for stretch in self.clear_separate_stretch: stretch.start() - self.clear_highlight_fade_in = Animation.create_fade(183, initial_opacity=0.0, final_opacity=1.0, reverse_delay=0, delay=450) + self.clear_highlight_fade_in = tex.get_animation(56) self.clear_highlight_fade_in.start() self.draw_clear_full = False self.name = 'in' @@ -2122,13 +2121,13 @@ class FCAnimation: """Animates the full combo effect""" def __init__(self, is_2p: bool): self.is_2p = is_2p - self.bachio_fade_in = Animation.create_fade(150, initial_opacity=0.0, final_opacity=1.0) + self.bachio_fade_in = tex.get_animation(46) self.bachio_fade_in.start() - self.bachio_texture_change = Animation.create_texture_change(266.67, textures=[(0, 150, 0), (150, 266.67, 1)], delay=self.bachio_fade_in.duration) + self.bachio_texture_change = tex.get_animation(47) self.bachio_texture_change.start() - self.bachio_out = Animation.create_texture_change(200, textures=[[0, 50, 0], [50, 100, 1], [100, 150, 2], [150, 200, 3]], delay=self.bachio_texture_change.duration+100) + self.bachio_out = tex.get_animation(55) self.bachio_out.start() - self.bachio_move_out = Animation.create_move(116.67, total_distance=200, delay=self.bachio_fade_in.duration, ease_out='quadratic') + self.bachio_move_out = tex.get_animation(49) self.bachio_move_out.start() self.clear_separate_fade_in = [Animation.create_fade(100, initial_opacity=0.0, final_opacity=1.0, delay=i*50) for i in range(5)] for fade in self.clear_separate_fade_in: @@ -2136,15 +2135,15 @@ class FCAnimation: self.clear_separate_stretch = [Animation.create_text_stretch(200, delay=i*50) for i in range(5)] for stretch in self.clear_separate_stretch: stretch.start() - self.clear_highlight_fade_in = Animation.create_fade(183, initial_opacity=0.0, final_opacity=1.0, reverse_delay=0, delay=450) + self.clear_highlight_fade_in = tex.get_animation(56) self.clear_highlight_fade_in.start() - self.fc_highlight_up = Animation.create_move(133, total_distance=20, reverse_delay=216.67, delay=450 + self.clear_highlight_fade_in.duration, ease_out='quadratic') + self.fc_highlight_up = tex.get_animation(57) self.fc_highlight_up.start() - self.fc_highlight_fade_out = Animation.create_fade(133) - self.bachio_move_out_2 = Animation.create_move(700, total_distance=150, ease_in='quadratic', ease_out='quadratic') - self.bachio_move_up = Animation.create_move(350, total_distance=150, reverse_delay=0, ease_in='quadratic') - self.fan_fade_in = Animation.create_fade(183, initial_opacity=0.0, final_opacity=1.0) - self.fan_texture_change = Animation.create_texture_change(100, textures=[[0, 16.67, 0], [16.67, 33.33, 1], [33.33, 50, 2], [50, 66.67, 3], [66.67, 83.33, 4], [83.33, 100, 5]], delay=self.fan_fade_in.duration) + self.fc_highlight_fade_out = tex.get_animation(58) + self.bachio_move_out_2 = tex.get_animation(59) + self.bachio_move_up = tex.get_animation(60) + self.fan_fade_in = tex.get_animation(61) + self.fan_texture_change = tex.get_animation(62) self.draw_clear_full = False self.name = 'in' self.frame = 0 @@ -2298,7 +2297,7 @@ class Gauge: ] self.gauge_update_anim = tex.get_animation(10) self.rainbow_fade_in = None - self.rainbow_animation = None + self.rainbow_animation = tex.get_animation(64) def add_good(self): """Adds a good note to the gauge""" @@ -2327,7 +2326,7 @@ class Gauge: self.is_clear = self.gauge_length > self.clear_start[min(self.difficulty, Difficulty.HARD)]-1 self.is_rainbow = self.gauge_length == self.gauge_max if self.gauge_length == self.gauge_max and self.rainbow_fade_in is None: - self.rainbow_fade_in = Animation.create_fade(450, initial_opacity=0.0, final_opacity=1.0) + self.rainbow_fade_in = tex.get_animation(63) self.rainbow_fade_in.start() self.gauge_update_anim.update(current_ms) self.tamashii_fire_change.update(current_ms) @@ -2335,13 +2334,7 @@ class Gauge: if self.rainbow_fade_in is not None: self.rainbow_fade_in.update(current_ms) - if self.rainbow_animation is None: - self.rainbow_animation = Animation.create_texture_change((16.67*8) * 3, textures=[((16.67 * 3) * i, (16.67 * 3) * (i + 1), i) for i in range(8)]) - self.rainbow_animation.start() - else: - self.rainbow_animation.update(current_ms) - if self.rainbow_animation.is_finished or self.gauge_length < 87: - self.rainbow_animation = None + self.rainbow_animation.update(current_ms) def draw(self): mirror = 'vertical' if self.is_2p else '' @@ -2357,7 +2350,7 @@ class Gauge: tex.draw_texture('gauge', 'bar_clear_bottom', x=(clear_point) * 8, x2=(gauge_length-clear_point)*8, index=self.is_2p) # Rainbow effect for full gauge - if gauge_length == self.gauge_max and self.rainbow_fade_in is not None and self.rainbow_animation is not None: + if gauge_length == self.gauge_max and self.rainbow_fade_in is not None: if 0 < self.rainbow_animation.attribute < 8: tex.draw_texture('gauge', 'rainbow' + self.string_diff, frame=self.rainbow_animation.attribute-1, fade=self.rainbow_fade_in.attribute, index=self.is_2p, mirror=mirror) tex.draw_texture('gauge', 'rainbow' + self.string_diff, frame=self.rainbow_animation.attribute, fade=self.rainbow_fade_in.attribute, index=self.is_2p, mirror=mirror) diff --git a/scenes/practice/game.py b/scenes/practice/game.py index b785899..4d43c4b 100644 --- a/scenes/practice/game.py +++ b/scenes/practice/game.py @@ -10,9 +10,9 @@ from libs.audio import audio from libs.background import Background from libs.global_data import Modifiers, PlayerNum, global_data from libs.tja import Balloon, Drumroll, Note, NoteType, TJAParser, apply_modifiers -from libs.utils import get_current_ms, get_key_code +from libs.utils import get_current_ms from libs.texture import tex -from scenes.game import DrumHitEffect, GameScreen, JudgeCounter, LaneHitEffect, Player, SCREEN_WIDTH +from scenes.game import DrumHitEffect, DrumType, GameScreen, JudgeCounter, LaneHitEffect, Player, SCREEN_WIDTH, Side logger = logging.getLogger(__name__) @@ -93,14 +93,14 @@ class PracticeGameScreen(GameScreen): self.start_ms = get_current_ms() - self.pause_time def global_keys(self): - if ray.is_key_pressed(get_key_code(global_data.config["keys"]["restart_key"])): + if ray.is_key_pressed(global_data.config["keys"]["restart_key"]): if self.song_music is not None: audio.stop_music_stream(self.song_music) self.init_tja(global_data.session_data[global_data.player_num].selected_song) audio.play_sound('restart', 'sound') self.song_started = False - if ray.is_key_pressed(get_key_code(global_data.config["keys"]["back_key"])): + if ray.is_key_pressed(global_data.config["keys"]["back_key"]): if self.song_music is not None: audio.stop_music_stream(self.song_music) return self.on_screen_end('PRACTICE_SELECT') @@ -276,7 +276,7 @@ class PracticePlayer(Player): self.gauge = None self.paused = False - def spawn_hit_effects(self, note_type: str, side: str): + def spawn_hit_effects(self, note_type: DrumType, side: Side): self.lane_hit_effect = LaneHitEffect(note_type, self.is_2p) self.draw_drum_hit_list.append(PracticeDrumHitEffect(note_type, side, self.is_2p, player_num=self.player_num)) diff --git a/scenes/song_select.py b/scenes/song_select.py index a33e21b..b6449ea 100644 --- a/scenes/song_select.py +++ b/scenes/song_select.py @@ -17,7 +17,6 @@ from libs.transition import Transition from libs.utils import ( OutlinedText, get_current_ms, - get_key_code, global_data, is_l_don_pressed, is_l_kat_pressed, @@ -306,7 +305,7 @@ class SongSelectScreen(Screen): if not current_box.is_back and get_current_ms() >= song.box.wait + (83.33*3): self.texture_index = current_box.texture_index - if ray.is_key_pressed(get_key_code(global_data.config["keys"]["back_key"])): + if ray.is_key_pressed(global_data.config["keys"]["back_key"]): logger.info("Back key pressed, returning to ENTRY screen") return self.on_screen_end('ENTRY') diff --git a/scenes/two_player/game.py b/scenes/two_player/game.py index b57eba4..8f76758 100644 --- a/scenes/two_player/game.py +++ b/scenes/two_player/game.py @@ -110,7 +110,10 @@ class TwoPlayerGameScreen(GameScreen): current_time = get_current_ms() self.transition.update(current_time) self.current_ms = current_time - self.start_ms - self.start_song(current_time) + if self.transition.is_finished: + self.start_song(self.current_ms) + else: + self.start_ms = current_time - self.tja.metadata.offset*1000 self.update_background(current_time) if self.song_music is not None: