this update doubles the fps

This commit is contained in:
Anthony Samms
2025-11-17 20:10:36 -05:00
parent ca72a23310
commit 7066dc385b
9 changed files with 154 additions and 125 deletions

View File

@@ -20,7 +20,6 @@ from libs.tja import TJAParser
from libs.utils import ( from libs.utils import (
force_dedicated_gpu, force_dedicated_gpu,
get_config, get_config,
get_key_code,
global_data, global_data,
global_tex global_tex
) )
@@ -208,16 +207,17 @@ def main():
ray.gen_texture_mipmaps(target.texture) ray.gen_texture_mipmaps(target.texture)
ray.set_texture_filter(target.texture, ray.TextureFilter.TEXTURE_FILTER_TRILINEAR) 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.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() ray.hide_cursor()
logger.info("Cursor hidden") logger.info("Cursor hidden")
last_fps = 1
while not ray.window_should_close(): 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() ray.toggle_fullscreen()
logger.info("Toggled 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() ray.toggle_borderless_windowed()
logger.info("Toggled borderless windowed mode") logger.info("Toggled borderless windowed mode")
@@ -248,7 +248,15 @@ def main():
global_data.input_locked = 0 global_data.input_locked = 0
if global_data.config["general"]["fps_counter"]: 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_blend_mode()
ray.end_texture_mode() ray.end_texture_mode()
ray.begin_drawing() ray.begin_drawing()

View File

@@ -1346,8 +1346,7 @@ class FileNavigator:
"""Get crowns for a directory, calculating only if needed""" """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: if dir_key in self.crown_cache_dirty or dir_key not in self.directory_crowns:
# Calculate crowns on-demand # Calculate crowns on-demand
dir_path = Path(dir_key) tja_files = self.directory_contents[dir_key]
tja_files = self._get_tja_files_for_directory(dir_path)
self._calculate_directory_crowns(dir_key, tja_files) self._calculate_directory_crowns(dir_key, tja_files)
self.crown_cache_dirty.discard(dir_key) self.crown_cache_dirty.discard(dir_key)

View File

@@ -5,9 +5,10 @@ import logging
import tempfile import tempfile
import zipfile import zipfile
from pathlib import Path 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 from libs.animation import BaseAnimation, parse_animations
@@ -23,7 +24,7 @@ class Coordinates:
class Texture: class Texture:
"""Texture class for managing textures and animations.""" """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.name = name
self.texture = texture self.texture = texture
self.init_vals = init_vals 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}]") logger.warning(f"Duplicate texture ID {texture.id}: {ids[texture.id]} and {zip}/{file}[{i}]")
else: else:
ids[texture.id] = f"{zip}/{file}[{i}]" ids[texture.id] = f"{zip}/{file}[{i}]"
ray.unload_texture(texture) ray.UnloadTexture(texture)
else: else:
if tex_object.texture.id in ids: 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}") logger.warning(f"Duplicate texture ID {tex_object.texture.id}: {ids[tex_object.texture.id]} and {zip}/{file}")
else: else:
ids[tex_object.texture.id] = f"{zip}/{file}" ids[tex_object.texture.id] = f"{zip}/{file}"
ray.unload_texture(tex_object.texture) ray.UnloadTexture(tex_object.texture)
self.textures.clear() self.textures.clear()
self.animations.clear() self.animations.clear()
@@ -147,10 +148,10 @@ class TextureWrapper:
extracted_path = Path(temp_dir) / tex_name extracted_path = Path(temp_dir) / tex_name
if extracted_path.is_dir(): 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()] key=lambda x: int(x.stem)) if frame.is_file()]
else: 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.textures[zip.stem][tex_name] = Texture(tex_name, frames, tex_mapping)
self._read_tex_obj_data(tex_mapping, self.textures[zip.stem][tex_name]) self._read_tex_obj_data(tex_mapping, self.textures[zip.stem][tex_name])
elif f"{tex_name}.png" in zip_ref.namelist(): elif f"{tex_name}.png" in zip_ref.namelist():
@@ -162,7 +163,7 @@ class TextureWrapper:
temp_path = temp_file.name temp_path = temp_file.name
try: 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.textures[zip.stem][tex_name] = Texture(tex_name, tex, tex_mapping)
self._read_tex_obj_data(tex_mapping, self.textures[zip.stem][tex_name]) self._read_tex_obj_data(tex_mapping, self.textures[zip.stem][tex_name])
finally: finally:
@@ -192,25 +193,58 @@ class TextureWrapper:
def control(self, tex_object: Texture, index: int = 0): def control(self, tex_object: Texture, index: int = 0):
'''debug function''' '''debug function'''
distance = 1 distance = 1
if ray.is_key_down(ray.KeyboardKey.KEY_LEFT_SHIFT): if ray.IsKeyDown(ray.KEY_LEFT_SHIFT):
distance = 10 distance = 10
if ray.is_key_pressed(ray.KeyboardKey.KEY_LEFT): if ray.IsKeyPressed(ray.KEY_LEFT):
tex_object.x[index] -= distance tex_object.x[index] -= distance
logger.info(f"{tex_object.name}: {tex_object.x[index]}, {tex_object.y[index]}") 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 tex_object.x[index] += distance
logger.info(f"{tex_object.name}: {tex_object.x[index]}, {tex_object.y[index]}") 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 tex_object.y[index] -= distance
logger.info(f"{tex_object.name}: {tex_object.x[index]}, {tex_object.y[index]}") 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 tex_object.y[index] += distance
logger.info(f"{tex_object.name}: {tex_object.x[index]}, {tex_object.y[index]}") 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, 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, origin: Vector2 = Vector2(0,0), rotation: float = 0, fade: float = 1.1,
index: int = 0, src: Optional[ray.Rectangle] = None, controllable: bool = False) -> None: index: int = 0, src: Optional[Rectangle] = None, controllable: bool = False) -> None:
""" """
Wrapper function for raylib's draw_texture_pro(). Wrapper function for raylib's draw_texture_pro().
Parameters: Parameters:
@@ -232,33 +266,14 @@ class TextureWrapper:
src (Optional[ray.Rectangle]): The source rectangle of the texture. src (Optional[ray.Rectangle]): The source rectangle of the texture.
controllable (bool): Whether the texture is controllable. 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: if src is not None:
source_rect = src src_data = (src.x, src.y, src.width, src.height)
else: else:
source_rect = ray.Rectangle(0, 0, tex_object.width * mirror_x, tex_object.height * mirror_y) src_data = None
if center: if isinstance(color, tuple):
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) color_data = (color[0], color[1], color[2], color[3])
else: 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) 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)
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)
tex = TextureWrapper() tex = TextureWrapper()

View File

@@ -10,6 +10,7 @@ from pathlib import Path
from typing import Optional from typing import Optional
import pyray as ray import pyray as ray
import raylib as rl
import tomlkit import tomlkit
from raylib import ( from raylib import (
SHADER_UNIFORM_FLOAT, SHADER_UNIFORM_FLOAT,
@@ -83,7 +84,7 @@ def get_config() -> Config:
config: Config = json.loads(json.dumps(config_file)) config: Config = json.loads(json.dumps(config_file))
for key in config['keys']: 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']: for key in config['keys_1p']:
bindings = config['keys_1p'][key] bindings = config['keys_1p'][key]
for i, bind in enumerate(bindings): 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: if global_data.input_locked:
return False return False
for key in keys: for key in keys:
if ray.is_key_pressed(key): if rl.IsKeyPressed(key):
return True return True
if ray.is_gamepad_available(0): if rl.IsGamepadAvailable(0):
for button in gamepad_buttons: for button in gamepad_buttons:
if ray.is_gamepad_button_pressed(0, button): if rl.IsGamepadButtonPressed(0, button):
return True return True
return False return False

View File

@@ -1,7 +1,7 @@
from pathlib import Path from pathlib import Path
import logging import logging
import pyray as ray import raylib as ray
from moviepy import VideoFileClip from moviepy import VideoFileClip
from libs.audio import audio from libs.audio import audio
@@ -52,13 +52,24 @@ class VideoPlayer:
frame_data = self.video.get_frame(time_sec) frame_data = self.video.get_frame(time_sec)
if self.texture is None: if self.texture is None:
image = ray.Image(frame_data, self.video.w, self.video.h, 1, ray.PixelFormat.PIXELFORMAT_UNCOMPRESSED_R8G8B8) if frame_data is None:
self.texture = ray.load_texture_from_image(image) 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: else:
if frame_data is not None: if frame_data is not None:
frame_bytes = frame_data.tobytes() frame_bytes = frame_data.tobytes()
pixels_ptr = ray.ffi.cast('void *', ray.ffi.from_buffer('unsigned char[]', frame_bytes)) 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 self.current_frame_data = frame_data
return True return True
@@ -108,14 +119,14 @@ class VideoPlayer:
def draw(self): def draw(self):
"""Draw video frames to the raylib canvas""" """Draw video frames to the raylib canvas"""
if self.texture is not None: 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): def stop(self):
"""Stops the video, audio, and clears its buffer""" """Stops the video, audio, and clears its buffer"""
self.video.close() self.video.close()
if self.texture is not None: if self.texture is not None:
ray.unload_texture(self.texture) ray.UnloadTexture(self.texture)
self.texture = None self.texture = None
if self.audio is not None: if self.audio is not None:

View File

@@ -31,7 +31,6 @@ from libs.transition import Transition
from libs.utils import ( from libs.utils import (
OutlinedText, OutlinedText,
get_current_ms, get_current_ms,
get_key_code,
global_data, global_data,
global_tex, global_tex,
is_l_don_pressed, is_l_don_pressed,
@@ -1224,13 +1223,13 @@ class Judgment:
self.big = big self.big = big
self.is_finished = False self.is_finished = False
self.fade_animation_1 = Animation.create_fade(132, initial_opacity=0.5, delay=100) self.fade_animation_1 = tex.get_animation(27, is_copy=True)
self.fade_animation_1.start() self.fade_animation_2 = tex.get_animation(28, is_copy=True)
self.fade_animation_2 = Animation.create_fade(316 - 233.3, delay=233.3) self.move_animation = tex.get_animation(29, is_copy=True)
self.fade_animation_2.start() self.texture_animation = tex.get_animation(30, is_copy=True)
self.move_animation = Animation.create_move(83, total_distance=15, start_position=144)
self.move_animation.start() 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() self.texture_animation.start()
def update(self, current_ms): def update(self, current_ms):
@@ -1323,14 +1322,14 @@ class GaugeHitEffect:
self.note_type = note_type self.note_type = note_type
self.is_big = big self.is_big = big
self.texture_change = tex.get_animation(2, is_copy=True) 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.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.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.resize.start()
self.fade_out = Animation.create_fade(66, delay=233)
self.fade_out.start() 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.rotation.start()
self.color = ray.fade(ray.YELLOW, self.circle_fadein.attribute) self.color = ray.fade(ray.YELLOW, self.circle_fadein.attribute)
self.is_finished = False self.is_finished = False
@@ -1779,17 +1778,17 @@ class ScoreCounterAnimation:
self.is_2p = is_2p self.is_2p = is_2p
self.counter = counter self.counter = counter
self.direction = -1 if self.is_2p else 1 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.fade_animation_1.start()
self.move_animation_1 = Animation.create_move(80, total_distance=-20, start_position=175)
self.move_animation_1.start() self.move_animation_1.start()
self.fade_animation_2 = Animation.create_fade(80, delay=366.74)
self.fade_animation_2.start() 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_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_3.start()
self.move_animation_4 = Animation.create_move(80, delay=366.74, total_distance=10, start_position=148)
self.move_animation_4.start() self.move_animation_4.start()
if player_num == PlayerNum.P2: if player_num == PlayerNum.P2:
@@ -1928,7 +1927,7 @@ class ComboAnnounce:
self.is_2p = is_2p self.is_2p = is_2p
self.combo = combo self.combo = combo
self.wait = current_time_ms self.wait = current_time_ms
self.fade = Animation.create_fade(100) self.fade = tex.get_animation(65)
self.fade.start() self.fade.start()
self.is_finished = False self.is_finished = False
self.audio_played = False self.audio_played = False
@@ -1977,11 +1976,11 @@ class BranchIndicator:
self.is_2p = is_2p self.is_2p = is_2p
self.difficulty = 'normal' self.difficulty = 'normal'
self.diff_2 = self.difficulty self.diff_2 = self.difficulty
self.diff_down = Animation.create_move(100, total_distance=20, ease_out='quadratic') self.diff_down = tex.get_animation(41)
self.diff_up = Animation.create_move(133, total_distance=70, delay=self.diff_down.duration, ease_out='quadratic') self.diff_up = tex.get_animation(42)
self.diff_fade = Animation.create_fade(133, delay=self.diff_down.duration) self.diff_fade = tex.get_animation(43)
self.level_fade = Animation.create_fade(116, initial_opacity=0.0, final_opacity=1.0, reverse_delay=116*10) self.level_fade = tex.get_animation(44)
self.level_scale = Animation.create_texture_resize(116, initial_size=1.0, final_size=1.2, reverse_delay=0) self.level_scale = tex.get_animation(45)
self.direction = 1 self.direction = 1
def update(self, current_time_ms): def update(self, current_time_ms):
self.diff_down.update(current_time_ms) self.diff_down.update(current_time_ms)
@@ -2023,24 +2022,24 @@ class FailAnimation:
"""Animates the fail effect""" """Animates the fail effect"""
def __init__(self, is_2p: bool): def __init__(self, is_2p: bool):
self.is_2p = is_2p 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_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_texture_change.start()
self.bachio_fall.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_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_fade_in.start()
self.bachio_boom_scale.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_up.start()
self.bachio_down.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.name = 'in'
self.frame = self.bachio_texture_change.attribute self.frame = self.bachio_texture_change.attribute
audio.play_sound('fail', 'sound') audio.play_sound('fail', 'sound')
@@ -2070,13 +2069,13 @@ class ClearAnimation:
"""Animates the clear effect""" """Animates the clear effect"""
def __init__(self, is_2p: bool): def __init__(self, is_2p: bool):
self.is_2p = is_2p 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_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_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_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.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)] 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: 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)] self.clear_separate_stretch = [Animation.create_text_stretch(200, delay=i*50) for i in range(5)]
for stretch in self.clear_separate_stretch: for stretch in self.clear_separate_stretch:
stretch.start() 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.clear_highlight_fade_in.start()
self.draw_clear_full = False self.draw_clear_full = False
self.name = 'in' self.name = 'in'
@@ -2122,13 +2121,13 @@ class FCAnimation:
"""Animates the full combo effect""" """Animates the full combo effect"""
def __init__(self, is_2p: bool): def __init__(self, is_2p: bool):
self.is_2p = is_2p 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_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_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_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.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)] 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: 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)] self.clear_separate_stretch = [Animation.create_text_stretch(200, delay=i*50) for i in range(5)]
for stretch in self.clear_separate_stretch: for stretch in self.clear_separate_stretch:
stretch.start() 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.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_up.start()
self.fc_highlight_fade_out = Animation.create_fade(133) self.fc_highlight_fade_out = tex.get_animation(58)
self.bachio_move_out_2 = Animation.create_move(700, total_distance=150, ease_in='quadratic', ease_out='quadratic') self.bachio_move_out_2 = tex.get_animation(59)
self.bachio_move_up = Animation.create_move(350, total_distance=150, reverse_delay=0, ease_in='quadratic') self.bachio_move_up = tex.get_animation(60)
self.fan_fade_in = Animation.create_fade(183, initial_opacity=0.0, final_opacity=1.0) self.fan_fade_in = tex.get_animation(61)
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.fan_texture_change = tex.get_animation(62)
self.draw_clear_full = False self.draw_clear_full = False
self.name = 'in' self.name = 'in'
self.frame = 0 self.frame = 0
@@ -2298,7 +2297,7 @@ class Gauge:
] ]
self.gauge_update_anim = tex.get_animation(10) self.gauge_update_anim = tex.get_animation(10)
self.rainbow_fade_in = None self.rainbow_fade_in = None
self.rainbow_animation = None self.rainbow_animation = tex.get_animation(64)
def add_good(self): def add_good(self):
"""Adds a good note to the gauge""" """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_clear = self.gauge_length > self.clear_start[min(self.difficulty, Difficulty.HARD)]-1
self.is_rainbow = self.gauge_length == self.gauge_max self.is_rainbow = self.gauge_length == self.gauge_max
if self.gauge_length == self.gauge_max and self.rainbow_fade_in is None: 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.rainbow_fade_in.start()
self.gauge_update_anim.update(current_ms) self.gauge_update_anim.update(current_ms)
self.tamashii_fire_change.update(current_ms) self.tamashii_fire_change.update(current_ms)
@@ -2335,13 +2334,7 @@ class Gauge:
if self.rainbow_fade_in is not None: if self.rainbow_fade_in is not None:
self.rainbow_fade_in.update(current_ms) self.rainbow_fade_in.update(current_ms)
if self.rainbow_animation is None: self.rainbow_animation.update(current_ms)
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
def draw(self): def draw(self):
mirror = 'vertical' if self.is_2p else '' 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) 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 # 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: 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-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) 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)

View File

@@ -10,9 +10,9 @@ from libs.audio import audio
from libs.background import Background from libs.background import Background
from libs.global_data import Modifiers, PlayerNum, global_data from libs.global_data import Modifiers, PlayerNum, global_data
from libs.tja import Balloon, Drumroll, Note, NoteType, TJAParser, apply_modifiers 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 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__) logger = logging.getLogger(__name__)
@@ -93,14 +93,14 @@ class PracticeGameScreen(GameScreen):
self.start_ms = get_current_ms() - self.pause_time self.start_ms = get_current_ms() - self.pause_time
def global_keys(self): 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: if self.song_music is not None:
audio.stop_music_stream(self.song_music) audio.stop_music_stream(self.song_music)
self.init_tja(global_data.session_data[global_data.player_num].selected_song) self.init_tja(global_data.session_data[global_data.player_num].selected_song)
audio.play_sound('restart', 'sound') audio.play_sound('restart', 'sound')
self.song_started = False 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: if self.song_music is not None:
audio.stop_music_stream(self.song_music) audio.stop_music_stream(self.song_music)
return self.on_screen_end('PRACTICE_SELECT') return self.on_screen_end('PRACTICE_SELECT')
@@ -276,7 +276,7 @@ class PracticePlayer(Player):
self.gauge = None self.gauge = None
self.paused = False 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.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)) self.draw_drum_hit_list.append(PracticeDrumHitEffect(note_type, side, self.is_2p, player_num=self.player_num))

View File

@@ -17,7 +17,6 @@ from libs.transition import Transition
from libs.utils import ( from libs.utils import (
OutlinedText, OutlinedText,
get_current_ms, get_current_ms,
get_key_code,
global_data, global_data,
is_l_don_pressed, is_l_don_pressed,
is_l_kat_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): if not current_box.is_back and get_current_ms() >= song.box.wait + (83.33*3):
self.texture_index = current_box.texture_index 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") logger.info("Back key pressed, returning to ENTRY screen")
return self.on_screen_end('ENTRY') return self.on_screen_end('ENTRY')

View File

@@ -110,7 +110,10 @@ class TwoPlayerGameScreen(GameScreen):
current_time = get_current_ms() current_time = get_current_ms()
self.transition.update(current_time) self.transition.update(current_time)
self.current_ms = current_time - self.start_ms 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) self.update_background(current_time)
if self.song_music is not None: if self.song_music is not None: