mirror of
https://github.com/Yonokid/PyTaiko.git
synced 2026-02-04 11:40:13 +01:00
add 1 billion sound effects
This commit is contained in:
@@ -56,6 +56,13 @@ def create_song_db():
|
||||
'''
|
||||
cursor.execute(create_table_query)
|
||||
con.commit()
|
||||
# Migrate existing records: set clear=2 for full combos (bad=0)
|
||||
cursor.execute("""
|
||||
UPDATE Scores
|
||||
SET clear = 2
|
||||
WHERE bad = 0 AND (clear IS NULL OR clear <> 2)
|
||||
""")
|
||||
con.commit()
|
||||
print("Scores database created successfully")
|
||||
|
||||
def main():
|
||||
|
||||
300
libs/audio.py
300
libs/audio.py
@@ -1,8 +1,6 @@
|
||||
import cffi
|
||||
import platform
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
import numpy as np
|
||||
|
||||
from libs.utils import get_config
|
||||
|
||||
@@ -107,7 +105,7 @@ ffi.cdef("""
|
||||
# gcc -shared -fPIC -o libaudio.so audio.c -lportaudio -lsndfile -lpthread
|
||||
try:
|
||||
if platform.system() == "Windows":
|
||||
lib = ffi.dlopen("libaudio.dll") # or "libaudio.dll" if that's the compiled name
|
||||
lib = ffi.dlopen("libaudio.dll")
|
||||
elif platform.system() == "Darwin":
|
||||
lib = ffi.dlopen("./libaudio.dylib")
|
||||
else: # Assume Linux/Unix
|
||||
@@ -134,12 +132,12 @@ class AudioEngine:
|
||||
sample_rate = 44100
|
||||
self.target_sample_rate = sample_rate
|
||||
self.buffer_size = buffer_size
|
||||
self.sounds = {} # sound_id -> sound struct
|
||||
self.music_streams = {} # music_id -> music struct
|
||||
self.sound_counter = 0
|
||||
self.music_counter = 0
|
||||
self.sounds = {}
|
||||
self.music_streams = {}
|
||||
self.audio_device_ready = False
|
||||
|
||||
self.sounds_path = Path("Sounds")
|
||||
|
||||
def list_host_apis(self):
|
||||
lib.list_host_apis() # type: ignore
|
||||
|
||||
@@ -148,6 +146,10 @@ class AudioEngine:
|
||||
try:
|
||||
lib.init_audio_device(self.device_type, self.target_sample_rate, self.buffer_size) # type: ignore
|
||||
self.audio_device_ready = lib.is_audio_device_ready() # type: ignore
|
||||
file_path_str = str(self.sounds_path / 'don.wav').encode('utf-8')
|
||||
self.don = lib.load_sound(file_path_str) # type: ignore
|
||||
file_path_str = str(self.sounds_path / 'ka.wav').encode('utf-8')
|
||||
self.kat = lib.load_sound(file_path_str) # type: ignore
|
||||
if self.audio_device_ready:
|
||||
print("Audio device initialized successfully")
|
||||
return self.audio_device_ready
|
||||
@@ -164,6 +166,8 @@ class AudioEngine:
|
||||
for music_id in list(self.music_streams.keys()):
|
||||
self.unload_music_stream(music_id)
|
||||
|
||||
lib.unload_sound(self.don) # type: ignore
|
||||
lib.unload_sound(self.kat) # type: ignore
|
||||
lib.close_audio_device() # type: ignore
|
||||
self.audio_device_ready = False
|
||||
print("Audio device closed")
|
||||
@@ -183,18 +187,16 @@ class AudioEngine:
|
||||
return lib.get_master_volume() # type: ignore
|
||||
|
||||
# Sound management
|
||||
def load_sound(self, file_path: Path) -> str:
|
||||
def load_sound(self, file_path: Path, name: str) -> str:
|
||||
"""Load a sound file and return sound ID"""
|
||||
try:
|
||||
file_path_str = str(file_path).encode('utf-8')
|
||||
sound = lib.load_sound(file_path_str) # type: ignore
|
||||
|
||||
if lib.is_sound_valid(sound): # type: ignore
|
||||
sound_id = f"sound_{self.sound_counter}"
|
||||
self.sounds[sound_id] = sound
|
||||
self.sound_counter += 1
|
||||
print(f"Loaded sound from {file_path} as {sound_id}")
|
||||
return sound_id
|
||||
self.sounds[name] = sound
|
||||
print(f"Loaded sound from {file_path} as {name}")
|
||||
return name
|
||||
else:
|
||||
print(f"Failed to load sound: {file_path}")
|
||||
return ""
|
||||
@@ -202,164 +204,180 @@ class AudioEngine:
|
||||
print(f"Error loading sound {file_path}: {e}")
|
||||
return ""
|
||||
|
||||
def unload_sound(self, sound_id: str) -> None:
|
||||
"""Unload a sound"""
|
||||
if sound_id in self.sounds:
|
||||
lib.unload_sound(self.sounds[sound_id]) # type: ignore
|
||||
del self.sounds[sound_id]
|
||||
def unload_sound(self, name: str) -> None:
|
||||
"""Unload a sound by name"""
|
||||
if name in self.sounds:
|
||||
lib.unload_sound(self.sounds[name]) # type: ignore
|
||||
del self.sounds[name]
|
||||
print(f"Unloaded sound {name}")
|
||||
else:
|
||||
print(f"Sound {name} not found")
|
||||
|
||||
def unload_all_sounds(self) -> None:
|
||||
def load_screen_sounds(self, screen_name: str) -> None:
|
||||
"""Load sounds for a given screen"""
|
||||
path = self.sounds_path / screen_name
|
||||
for sound in path.iterdir():
|
||||
if sound.is_dir():
|
||||
for file in sound.iterdir():
|
||||
self.load_sound(file, sound.stem + '_' + file.stem)
|
||||
if sound.is_file():
|
||||
self.load_sound(sound, sound.stem)
|
||||
|
||||
path = self.sounds_path / 'global'
|
||||
for sound in path.iterdir():
|
||||
if sound.is_dir():
|
||||
for file in sound.iterdir():
|
||||
self.load_sound(file, sound.stem + '_' + file.stem)
|
||||
if sound.is_file():
|
||||
self.load_sound(sound, sound.stem)
|
||||
|
||||
def unload_all_sounds(self):
|
||||
"""Unload all sounds"""
|
||||
for sound_id in list(self.sounds.keys()):
|
||||
self.unload_sound(sound_id)
|
||||
for name in list(self.sounds.keys()):
|
||||
self.unload_sound(name)
|
||||
|
||||
def play_sound(self, sound_id: str) -> None:
|
||||
def play_sound(self, name: str) -> None:
|
||||
"""Play a sound"""
|
||||
if sound_id in self.sounds:
|
||||
lib.play_sound(self.sounds[sound_id]) # type: ignore
|
||||
if name == 'don':
|
||||
lib.play_sound(self.don) # type: ignore
|
||||
elif name == 'kat':
|
||||
lib.play_sound(self.kat) # type: ignore
|
||||
elif name in self.sounds:
|
||||
sound = self.sounds[name]
|
||||
lib.play_sound(sound) # type: ignore
|
||||
else:
|
||||
print(f"Sound {name} not found")
|
||||
|
||||
def stop_sound(self, sound_id: str) -> None:
|
||||
def stop_sound(self, name: str) -> None:
|
||||
"""Stop a sound"""
|
||||
if sound_id in self.sounds:
|
||||
lib.stop_sound(self.sounds[sound_id]) # type: ignore
|
||||
if name == 'don':
|
||||
lib.stop_sound(self.don) # type: ignore
|
||||
elif name == 'kat':
|
||||
lib.stop_sound(self.kat) # type: ignore
|
||||
if name in self.sounds:
|
||||
sound = self.sounds[name]
|
||||
lib.stop_sound(sound) # type: ignore
|
||||
else:
|
||||
print(f"Sound {name} not found")
|
||||
|
||||
def pause_sound(self, sound_id: str) -> None:
|
||||
"""Pause a sound"""
|
||||
if sound_id in self.sounds:
|
||||
lib.pause_sound(self.sounds[sound_id]) # type: ignore
|
||||
|
||||
def resume_sound(self, sound_id: str) -> None:
|
||||
"""Resume a sound"""
|
||||
if sound_id in self.sounds:
|
||||
lib.resume_sound(self.sounds[sound_id]) # type: ignore
|
||||
|
||||
def is_sound_valid(self, sound_id: str) -> bool:
|
||||
"""Check if sound is valid"""
|
||||
if sound_id in self.sounds:
|
||||
return lib.is_sound_valid(self.sounds[sound_id]) # type: ignore
|
||||
def is_sound_playing(self, name: str) -> bool:
|
||||
if name == 'don':
|
||||
return lib.is_sound_playing(self.don) # type: ignore
|
||||
elif name == 'kat':
|
||||
return lib.is_sound_playing(self.kat) # type: ignore
|
||||
if name in self.sounds:
|
||||
sound = self.sounds[name]
|
||||
return lib.is_sound_playing(sound) # type: ignore
|
||||
else:
|
||||
print(f"Sound {name} not found")
|
||||
return False
|
||||
|
||||
def is_sound_playing(self, sound_id: str) -> bool:
|
||||
"""Check if sound is playing"""
|
||||
if sound_id in self.sounds:
|
||||
return lib.is_sound_playing(self.sounds[sound_id]) # type: ignore
|
||||
return False
|
||||
|
||||
def set_sound_volume(self, sound_id: str, volume: float) -> None:
|
||||
"""Set sound volume"""
|
||||
if sound_id in self.sounds:
|
||||
lib.set_sound_volume(self.sounds[sound_id], max(0.0, volume)) # type: ignore
|
||||
|
||||
def set_sound_pan(self, sound_id: str, pan: float) -> None:
|
||||
"""Set sound pan (0.0 = left, 0.5 = center, 1.0 = right)"""
|
||||
if sound_id in self.sounds:
|
||||
lib.set_sound_pan(self.sounds[sound_id], max(0.0, min(1.0, pan))) # type: ignore
|
||||
|
||||
def normalize_sound(self, sound_id: str, rms: float) -> None:
|
||||
"""Normalize sound - Note: This would need to be implemented in C"""
|
||||
# The C implementation doesn't have normalize function yet
|
||||
# You'd need to add this to your C code
|
||||
print(f"Warning: normalize_sound not implemented in C backend")
|
||||
def set_sound_volume(self, name: str, volume: float) -> None:
|
||||
if name == 'don':
|
||||
lib.set_sound_volume(self.don, volume) # type: ignore
|
||||
elif name == 'kat':
|
||||
lib.set_sound_volume(self.kat, volume) # type: ignore
|
||||
elif name in self.sounds:
|
||||
sound = self.sounds[name]
|
||||
lib.set_sound_volume(sound, volume) # type: ignore
|
||||
else:
|
||||
print(f"Sound {name} not found")
|
||||
|
||||
# Music management
|
||||
def load_music_stream(self, file_path: Path, normalize: Optional[float] = None) -> str:
|
||||
def load_music_stream(self, file_path: Path, name: str) -> str:
|
||||
"""Load a music stream and return music ID"""
|
||||
try:
|
||||
file_path_str = str(file_path).encode('utf-8')
|
||||
music = lib.load_music_stream(file_path_str) # type: ignore
|
||||
|
||||
if lib.is_music_valid(music): # type: ignore
|
||||
music_id = f"music_{self.music_counter}"
|
||||
self.music_streams[music_id] = music
|
||||
self.music_counter += 1
|
||||
print(f"Loaded music stream from {file_path} as {music_id}")
|
||||
return music_id
|
||||
self.music_streams[name] = music
|
||||
print(f"Loaded music stream from {file_path} as {name}")
|
||||
return name
|
||||
else:
|
||||
print(f"Failed to load music: {file_path}")
|
||||
return ""
|
||||
except Exception as e:
|
||||
print(f"Error loading music {file_path}: {e}")
|
||||
return ""
|
||||
|
||||
def load_music_stream_from_data(self, audio_array: np.ndarray, sample_rate: int = 44100) -> str:
|
||||
"""Load music from numpy array - would need C implementation"""
|
||||
print("Warning: load_music_stream_from_data not implemented in C backend")
|
||||
return ""
|
||||
|
||||
def unload_music_stream(self, music_id: str) -> None:
|
||||
"""Unload a music stream"""
|
||||
if music_id in self.music_streams:
|
||||
lib.unload_music_stream(self.music_streams[music_id]) # type: ignore
|
||||
del self.music_streams[music_id]
|
||||
|
||||
def is_music_valid(self, music_id: str) -> bool:
|
||||
"""Check if music is valid"""
|
||||
if music_id in self.music_streams:
|
||||
return lib.is_music_valid(self.music_streams[music_id]) # type: ignore
|
||||
return False
|
||||
|
||||
def play_music_stream(self, music_id: str) -> None:
|
||||
def play_music_stream(self, name: str) -> None:
|
||||
"""Play a music stream"""
|
||||
if music_id in self.music_streams:
|
||||
lib.seek_music_stream(self.music_streams[music_id], 0) # type: ignore
|
||||
lib.play_music_stream(self.music_streams[music_id]) # type: ignore
|
||||
if name in self.music_streams:
|
||||
music = self.music_streams[name]
|
||||
lib.seek_music_stream(music, 0) # type: ignore
|
||||
lib.play_music_stream(music) # type: ignore
|
||||
else:
|
||||
print(f"Music stream {name} not found")
|
||||
|
||||
def stop_music_stream(self, music_id: str) -> None:
|
||||
"""Stop a music stream"""
|
||||
if music_id in self.music_streams:
|
||||
lib.stop_music_stream(self.music_streams[music_id]) # type: ignore
|
||||
def update_music_stream(self, name: str) -> None:
|
||||
"""Update a music stream"""
|
||||
if name in self.music_streams:
|
||||
music = self.music_streams[name]
|
||||
lib.update_music_stream(music) # type: ignore
|
||||
else:
|
||||
print(f"Music stream {name} not found")
|
||||
|
||||
def pause_music_stream(self, music_id: str) -> None:
|
||||
"""Pause a music stream"""
|
||||
if music_id in self.music_streams:
|
||||
lib.pause_music_stream(self.music_streams[music_id]) # type: ignore
|
||||
def get_music_time_length(self, name: str) -> float:
|
||||
"""Get the time length of a music stream"""
|
||||
if name in self.music_streams:
|
||||
music = self.music_streams[name]
|
||||
return lib.get_music_time_length(music) # type: ignore
|
||||
else:
|
||||
print(f"Music stream {name} not found")
|
||||
return 0.0
|
||||
|
||||
def resume_music_stream(self, music_id: str) -> None:
|
||||
"""Resume a music stream"""
|
||||
if music_id in self.music_streams:
|
||||
lib.resume_music_stream(self.music_streams[music_id]) # type: ignore
|
||||
def get_music_time_played(self, name: str) -> float:
|
||||
"""Get the time played of a music stream"""
|
||||
if name in self.music_streams:
|
||||
music = self.music_streams[name]
|
||||
return lib.get_music_time_played(music) # type: ignore
|
||||
else:
|
||||
print(f"Music stream {name} not found")
|
||||
return 0.0
|
||||
|
||||
def is_music_stream_playing(self, music_id: str) -> bool:
|
||||
"""Check if music stream is playing"""
|
||||
if music_id in self.music_streams:
|
||||
return lib.is_music_stream_playing(self.music_streams[music_id]) # type: ignore
|
||||
def set_music_volume(self, name: str, volume: float) -> None:
|
||||
"""Set the volume of a music stream"""
|
||||
if name in self.music_streams:
|
||||
music = self.music_streams[name]
|
||||
lib.set_music_volume(music, volume) # type: ignore
|
||||
else:
|
||||
print(f"Music stream {name} not found")
|
||||
|
||||
def is_music_stream_playing(self, name: str) -> bool:
|
||||
"""Check if a music stream is playing"""
|
||||
if name in self.music_streams:
|
||||
music = self.music_streams[name]
|
||||
return lib.is_music_stream_playing(music) # type: ignore
|
||||
else:
|
||||
print(f"Music stream {name} not found")
|
||||
return False
|
||||
|
||||
def seek_music_stream(self, music_id: str, position: float) -> None:
|
||||
"""Seek music stream to position in seconds"""
|
||||
if music_id in self.music_streams:
|
||||
lib.seek_music_stream(self.music_streams[music_id], position) # type: ignore
|
||||
def stop_music_stream(self, name: str) -> None:
|
||||
"""Stop a music stream"""
|
||||
if name in self.music_streams:
|
||||
music = self.music_streams[name]
|
||||
lib.stop_music_stream(music) # type: ignore
|
||||
else:
|
||||
print(f"Music stream {name} not found")
|
||||
|
||||
def update_music_stream(self, music_id: str) -> None:
|
||||
"""Update music stream (fill buffers)"""
|
||||
if music_id in self.music_streams:
|
||||
lib.update_music_stream(self.music_streams[music_id]) # type: ignore
|
||||
def unload_music_stream(self, name: str) -> None:
|
||||
"""Unload a music stream"""
|
||||
if name in self.music_streams:
|
||||
music = self.music_streams[name]
|
||||
lib.unload_music_stream(music) # type: ignore
|
||||
del self.music_streams[name]
|
||||
else:
|
||||
print(f"Music stream {name} not found")
|
||||
|
||||
def set_music_volume(self, music_id: str, volume: float) -> None:
|
||||
"""Set music volume"""
|
||||
if music_id in self.music_streams:
|
||||
lib.set_music_volume(self.music_streams[music_id], max(0.0, min(1.0, volume))) # type: ignore
|
||||
def unload_all_music(self) -> None:
|
||||
"""Unload all music streams"""
|
||||
for music_id in list(self.music_streams.keys()):
|
||||
self.unload_music_stream(music_id)
|
||||
|
||||
def set_music_pan(self, music_id: str, pan: float) -> None:
|
||||
"""Set music pan"""
|
||||
if music_id in self.music_streams:
|
||||
lib.set_music_pan(self.music_streams[music_id], max(0.0, min(1.0, pan))) # type: ignore
|
||||
|
||||
def normalize_music_stream(self, music_id: str, rms: float) -> None:
|
||||
"""Normalize music stream - would need C implementation"""
|
||||
print("Warning: normalize_music_stream not implemented in C backend")
|
||||
|
||||
def get_music_time_length(self, music_id: str) -> float:
|
||||
"""Get total music length in seconds"""
|
||||
if music_id in self.music_streams:
|
||||
return lib.get_music_time_length(self.music_streams[music_id]) # type: ignore
|
||||
return 0.0
|
||||
|
||||
def get_music_time_played(self, music_id: str) -> float:
|
||||
"""Get current music position in seconds"""
|
||||
if music_id in self.music_streams:
|
||||
return lib.get_music_time_played(self.music_streams[music_id]) # type: ignore
|
||||
return 0.0
|
||||
def seek_music_stream(self, name: str, position: float) -> None:
|
||||
"""Seek a music stream to a specific position"""
|
||||
if name in self.music_streams:
|
||||
music = self.music_streams[name]
|
||||
lib.seek_music_stream(music, position) # type: ignore
|
||||
else:
|
||||
print(f"Music stream {name} not found")
|
||||
|
||||
# Create the global audio instance
|
||||
audio = AudioEngine(get_config()["audio"]["device_type"], get_config()["audio"]["sample_rate"], get_config()["audio"]["buffer_size"])
|
||||
|
||||
@@ -2,6 +2,7 @@ from enum import Enum
|
||||
import pyray as ray
|
||||
|
||||
from libs.utils import OutlinedText, get_config, global_tex
|
||||
from libs.audio import audio
|
||||
|
||||
|
||||
class Nameplate:
|
||||
@@ -123,7 +124,7 @@ class Timer:
|
||||
self.is_finished = False
|
||||
self.is_frozen = get_config()["general"]["timer_frozen"]
|
||||
def update(self, current_time_ms: float):
|
||||
if self.time == 0 and not self.is_finished:
|
||||
if self.time == 0 and not self.is_finished and not audio.is_sound_playing('voice_timer_0'):
|
||||
self.is_finished = True
|
||||
self.confirm_func()
|
||||
self.num_resize.update(current_time_ms)
|
||||
@@ -136,9 +137,16 @@ class Timer:
|
||||
self.last_time = current_time_ms
|
||||
self.counter = str(self.time)
|
||||
if self.time < 10:
|
||||
audio.play_sound('timer_blip')
|
||||
self.num_resize.start()
|
||||
self.highlight_fade.start()
|
||||
self.highlight_resize.start()
|
||||
if self.time == 10:
|
||||
audio.play_sound('voice_timer_10')
|
||||
elif self.time == 5:
|
||||
audio.play_sound('voice_timer_5')
|
||||
elif self.time == 0:
|
||||
audio.play_sound('voice_timer_0')
|
||||
def draw(self, x: int = 0, y: int = 0):
|
||||
tex = global_tex
|
||||
if self.time < 10:
|
||||
|
||||
@@ -158,7 +158,7 @@ def build_song_hashes(output_dir=Path("cache")):
|
||||
continue
|
||||
if imported_clears[i] == 2:
|
||||
bads = 0
|
||||
clear = 1
|
||||
clear = 2
|
||||
elif imported_clears[i] == 1:
|
||||
bads = None
|
||||
clear = 1
|
||||
|
||||
@@ -14,7 +14,7 @@ class VideoPlayer:
|
||||
self.video = VideoFileClip(path)
|
||||
if self.video.audio is not None:
|
||||
self.video.audio.write_audiofile("cache/temp_audio.wav")
|
||||
self.audio = audio.load_music_stream(Path("cache/temp_audio.wav"))
|
||||
self.audio = audio.load_music_stream(Path("cache/temp_audio.wav"), 'video')
|
||||
|
||||
self.buffer_size = 10 # Number of frames to keep in memory
|
||||
self.frame_buffer: dict[float, ray.Texture] = dict() # Dictionary to store frames {timestamp: texture}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
from pathlib import Path
|
||||
|
||||
import pyray as ray
|
||||
|
||||
from libs.audio import audio
|
||||
@@ -25,19 +23,10 @@ class EntryScreen:
|
||||
def __init__(self):
|
||||
self.screen_init = False
|
||||
|
||||
def load_textures(self):
|
||||
tex.load_screen_textures('entry')
|
||||
|
||||
def load_sounds(self):
|
||||
sounds_dir = Path("Sounds")
|
||||
self.sound_don = audio.load_sound(sounds_dir / "hit_sounds" / "0" / "don.wav")
|
||||
self.sound_kat = audio.load_sound(sounds_dir / "hit_sounds" / "0" / "ka.wav")
|
||||
self.bgm = audio.load_sound(sounds_dir / "entry" / "JINGLE_ENTRY [1].ogg")
|
||||
|
||||
def on_screen_start(self):
|
||||
if not self.screen_init:
|
||||
self.load_textures()
|
||||
self.load_sounds()
|
||||
tex.load_screen_textures('entry')
|
||||
audio.load_screen_sounds('entry')
|
||||
self.side = 1
|
||||
self.box_manager = BoxManager()
|
||||
self.state = State.SELECT_SIDE
|
||||
@@ -61,15 +50,16 @@ class EntryScreen:
|
||||
self.nameplate_fadein = tex.get_animation(12)
|
||||
self.side_select_fade.start()
|
||||
self.chara = Chara2D(0, 100)
|
||||
audio.play_sound(self.bgm)
|
||||
self.announce_played = False
|
||||
audio.play_sound('bgm')
|
||||
|
||||
def on_screen_end(self, next_screen: str):
|
||||
self.screen_init = False
|
||||
global_data.player_num = round((self.side/3) + 1)
|
||||
audio.stop_sound(self.bgm)
|
||||
audio.stop_sound('bgm')
|
||||
self.nameplate.unload()
|
||||
tex.unload_textures()
|
||||
audio.unload_all_sounds()
|
||||
audio.unload_all_music()
|
||||
return next_screen
|
||||
|
||||
def handle_input(self):
|
||||
@@ -79,6 +69,7 @@ class EntryScreen:
|
||||
if is_l_don_pressed() or is_r_don_pressed():
|
||||
if self.side == 1:
|
||||
return self.on_screen_end("TITLE")
|
||||
global_data.player_num = round((self.side/3) + 1)
|
||||
self.drum_move_1.start()
|
||||
self.drum_move_2.start()
|
||||
self.drum_move_3.start()
|
||||
@@ -86,31 +77,33 @@ class EntryScreen:
|
||||
self.cloud_resize_loop.start()
|
||||
self.cloud_texture_change.start()
|
||||
self.cloud_fade.start()
|
||||
audio.play_sound('cloud')
|
||||
audio.play_sound(f'entry_start_{global_data.player_num}p')
|
||||
plate_info = global_data.config['nameplate']
|
||||
self.nameplate.unload()
|
||||
self.nameplate = Nameplate(plate_info['name'], plate_info['title'], round((self.side/3) + 1), plate_info['dan'], plate_info['gold'])
|
||||
self.nameplate = Nameplate(plate_info['name'], plate_info['title'], global_data.player_num, plate_info['dan'], plate_info['gold'])
|
||||
self.nameplate_fadein.start()
|
||||
self.state = State.SELECT_MODE
|
||||
if self.side == 2:
|
||||
self.chara = Chara2D(1, 100)
|
||||
else:
|
||||
self.chara = Chara2D(0, 100)
|
||||
audio.play_sound(self.sound_don)
|
||||
audio.play_sound('don')
|
||||
if is_l_kat_pressed():
|
||||
audio.play_sound(self.sound_kat)
|
||||
audio.play_sound('kat')
|
||||
self.side = max(0, self.side - 1)
|
||||
if is_r_kat_pressed():
|
||||
audio.play_sound(self.sound_kat)
|
||||
audio.play_sound('kat')
|
||||
self.side = min(2, self.side + 1)
|
||||
elif self.state == State.SELECT_MODE:
|
||||
if is_l_don_pressed() or is_r_don_pressed():
|
||||
audio.play_sound(self.sound_don)
|
||||
audio.play_sound('don')
|
||||
self.box_manager.select_box()
|
||||
if is_l_kat_pressed():
|
||||
audio.play_sound(self.sound_kat)
|
||||
audio.play_sound('kat')
|
||||
self.box_manager.move_left()
|
||||
if is_r_kat_pressed():
|
||||
audio.play_sound(self.sound_kat)
|
||||
audio.play_sound('kat')
|
||||
self.box_manager.move_right()
|
||||
|
||||
def update(self):
|
||||
@@ -133,6 +126,9 @@ class EntryScreen:
|
||||
self.chara.update(current_time, 100, False, False)
|
||||
if self.box_manager.is_finished():
|
||||
return self.on_screen_end(self.box_manager.selected_box())
|
||||
if self.cloud_fade.is_finished and not audio.is_sound_playing(f'entry_start_{global_data.player_num}p') and not self.announce_played:
|
||||
audio.play_sound('select_mode')
|
||||
self.announce_played = True
|
||||
return self.handle_input()
|
||||
|
||||
def draw_background(self):
|
||||
|
||||
@@ -49,21 +49,17 @@ class GameScreen:
|
||||
self.song_started = False
|
||||
self.mask_shader = ray.load_shader("", "shader/mask.fs")
|
||||
|
||||
def load_sounds(self):
|
||||
def load_hitsounds(self):
|
||||
sounds_dir = Path("Sounds")
|
||||
if global_data.hit_sound == -1:
|
||||
self.sound_don = audio.load_sound(Path('none.wav'))
|
||||
self.sound_kat = audio.load_sound(Path('none.wav'))
|
||||
self.sound_don = audio.load_sound(Path('none.wav'), 'hitsound_don')
|
||||
self.sound_kat = audio.load_sound(Path('none.wav'), 'hitsound_kat')
|
||||
if global_data.hit_sound == 0:
|
||||
self.sound_don = audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound) / "don.wav")
|
||||
self.sound_kat = audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound) / "ka.wav")
|
||||
self.sound_don = audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound) / "don.wav", 'hitsound_don')
|
||||
self.sound_kat = audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound) / "ka.wav", 'hitsound_kat')
|
||||
else:
|
||||
self.sound_don = audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound) / "don.ogg")
|
||||
self.sound_kat = audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound) / "ka.ogg")
|
||||
self.sound_restart = audio.load_sound(sounds_dir / 'song_select' / 'Skip.ogg')
|
||||
self.sound_balloon_pop = audio.load_sound(sounds_dir / "balloon_pop.wav")
|
||||
self.sound_kusudama_pop = audio.load_sound(sounds_dir / "kusudama_pop.ogg")
|
||||
self.sound_result_transition = audio.load_sound(sounds_dir / "result" / "VO_RESULT [1].ogg")
|
||||
self.sound_don = audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound) / "don.ogg", 'hitsound_don')
|
||||
self.sound_kat = audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound) / "ka.ogg", 'hitsound_kat')
|
||||
|
||||
def init_tja(self, song: Path, difficulty: int):
|
||||
if song == Path(''):
|
||||
@@ -78,8 +74,7 @@ class GameScreen:
|
||||
self.movie = None
|
||||
session_data.song_title = self.tja.metadata.title.get(global_data.config['general']['language'].lower(), self.tja.metadata.title['en'])
|
||||
if self.tja.metadata.wave.exists() and self.tja.metadata.wave.is_file() and self.song_music is None:
|
||||
self.song_music = audio.load_music_stream(self.tja.metadata.wave)
|
||||
audio.normalize_music_stream(self.song_music, 0.1935)
|
||||
self.song_music = audio.load_music_stream(self.tja.metadata.wave, 'song')
|
||||
|
||||
self.player_1 = Player(self.tja, global_data.player_num, difficulty)
|
||||
if self.tja is not None:
|
||||
@@ -91,9 +86,10 @@ class GameScreen:
|
||||
self.movie = None
|
||||
self.song_music = None
|
||||
tex.load_screen_textures('game')
|
||||
audio.load_screen_sounds('game')
|
||||
self.load_hitsounds()
|
||||
ray.set_shader_value_texture(self.mask_shader, ray.get_shader_location(self.mask_shader, "texture0"), tex.textures['balloon']['rainbow_mask'].texture)
|
||||
ray.set_shader_value_texture(self.mask_shader, ray.get_shader_location(self.mask_shader, "texture1"), tex.textures['balloon']['rainbow'].texture)
|
||||
self.load_sounds()
|
||||
self.init_tja(global_data.selected_song, session_data.selected_difficulty)
|
||||
self.song_info = SongInfo(session_data.song_title, session_data.genre_index)
|
||||
self.result_transition = ResultTransition(global_data.player_num)
|
||||
@@ -113,8 +109,8 @@ class GameScreen:
|
||||
def on_screen_end(self, next_screen):
|
||||
self.screen_init = False
|
||||
tex.unload_textures()
|
||||
if self.song_music is not None:
|
||||
audio.unload_music_stream(self.song_music)
|
||||
audio.unload_all_sounds()
|
||||
audio.unload_all_music()
|
||||
self.song_started = False
|
||||
self.end_ms = 0
|
||||
self.movie = None
|
||||
@@ -131,14 +127,24 @@ class GameScreen:
|
||||
cursor = con.cursor()
|
||||
notes, _, _, _ = TJAParser.notes_to_position(TJAParser(self.tja.file_path), self.player_1.difficulty)
|
||||
hash = self.tja.hash_note_data(notes)
|
||||
check_query = "SELECT score FROM Scores WHERE hash = ? LIMIT 1"
|
||||
check_query = "SELECT score, clear FROM Scores WHERE hash = ? LIMIT 1"
|
||||
cursor.execute(check_query, (hash,))
|
||||
result = cursor.fetchone()
|
||||
if result is None or session_data.result_score > result[0]:
|
||||
existing_score = result[0] if result is not None else None
|
||||
existing_clear = result[1] if result is not None and len(result) > 1 and result[1] is not None else 0
|
||||
|
||||
# Determine clear value for this run: 2 for full combo (no bads), 1 for clear gauge, 0 otherwise
|
||||
run_clear = 2 if session_data.result_bad == 0 else (1 if self.player_1.gauge.is_clear else 0)
|
||||
best_clear = max(existing_clear, run_clear)
|
||||
|
||||
if result is None or (existing_score is not None and session_data.result_score > existing_score):
|
||||
if result is None:
|
||||
session_data.prev_score = 0
|
||||
else:
|
||||
session_data.prev_score = result[0]
|
||||
if not isinstance(existing_score, int):
|
||||
session_data.prev_score = 0
|
||||
else:
|
||||
session_data.prev_score = existing_score
|
||||
insert_query = '''
|
||||
INSERT OR REPLACE INTO Scores (hash, en_name, jp_name, diff, score, good, ok, bad, drumroll, combo, clear)
|
||||
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
|
||||
@@ -147,9 +153,14 @@ class GameScreen:
|
||||
self.tja.metadata.title.get('ja', ''), self.player_1.difficulty,
|
||||
session_data.result_score, session_data.result_good,
|
||||
session_data.result_ok, session_data.result_bad,
|
||||
session_data.result_total_drumroll, session_data.result_max_combo, int(self.player_1.gauge.is_clear))
|
||||
session_data.result_total_drumroll, session_data.result_max_combo, best_clear)
|
||||
cursor.execute(insert_query, data)
|
||||
con.commit()
|
||||
else:
|
||||
# Score didn't improve; if clear improved, update only the clear column to preserve best crown
|
||||
if run_clear > existing_clear:
|
||||
cursor.execute("UPDATE Scores SET clear = ? WHERE hash = ?", (run_clear, hash))
|
||||
con.commit()
|
||||
|
||||
def update(self):
|
||||
self.on_screen_start()
|
||||
@@ -178,7 +189,7 @@ class GameScreen:
|
||||
self.player_1.update(self, current_time)
|
||||
self.song_info.update(current_time)
|
||||
self.result_transition.update(current_time)
|
||||
if self.result_transition.is_finished:
|
||||
if self.result_transition.is_finished and not audio.is_sound_playing('result_transition'):
|
||||
return self.on_screen_end('RESULT')
|
||||
elif self.current_ms >= self.player_1.end_time:
|
||||
session_data.result_score, session_data.result_good, session_data.result_ok, session_data.result_bad, session_data.result_max_combo, session_data.result_total_drumroll = self.player_1.get_result_score()
|
||||
@@ -195,7 +206,7 @@ class GameScreen:
|
||||
if current_time >= self.end_ms + 8533.34:
|
||||
if not self.result_transition.is_started:
|
||||
self.result_transition.start()
|
||||
audio.play_sound(self.sound_result_transition)
|
||||
audio.play_sound('result_transition')
|
||||
else:
|
||||
self.write_score()
|
||||
self.end_ms = current_time
|
||||
@@ -204,7 +215,7 @@ class GameScreen:
|
||||
if self.song_music is not None:
|
||||
audio.stop_music_stream(self.song_music)
|
||||
self.init_tja(global_data.selected_song, session_data.selected_difficulty)
|
||||
audio.play_sound(self.sound_restart)
|
||||
audio.play_sound('restart')
|
||||
self.song_started = False
|
||||
|
||||
if ray.is_key_pressed(ray.KeyboardKey.KEY_ESCAPE):
|
||||
@@ -570,7 +581,7 @@ class Player:
|
||||
self.is_balloon = False
|
||||
note.popped = True
|
||||
self.balloon_anim.update(current_time, self.curr_balloon_count, note.popped)
|
||||
audio.play_sound(game_screen.sound_balloon_pop)
|
||||
audio.play_sound('balloon_pop')
|
||||
self.note_correct(note, current_time)
|
||||
self.curr_balloon_count = 0
|
||||
|
||||
@@ -582,7 +593,7 @@ class Player:
|
||||
self.score += 100
|
||||
self.base_score_list.append(ScoreCounterAnimation(self.player_number, 100))
|
||||
if self.curr_balloon_count == note.count:
|
||||
audio.play_sound(game_screen.sound_kusudama_pop)
|
||||
audio.play_sound('kusudama_pop')
|
||||
self.is_balloon = False
|
||||
note.popped = True
|
||||
self.curr_balloon_count = 0
|
||||
@@ -1696,6 +1707,7 @@ class ComboAnnounce:
|
||||
self.fade = Animation.create_fade(100)
|
||||
self.fade.start()
|
||||
self.is_finished = False
|
||||
self.audio_played = False
|
||||
|
||||
def update(self, current_time_ms: float):
|
||||
if current_time_ms >= self.wait + 1666.67 and not self.is_finished:
|
||||
@@ -1703,6 +1715,9 @@ class ComboAnnounce:
|
||||
self.is_finished = True
|
||||
|
||||
self.fade.update(current_time_ms)
|
||||
if not self.audio_played:
|
||||
audio.play_sound(f'combo_{self.combo}_{global_data.player_num}p')
|
||||
self.audio_played = True
|
||||
|
||||
def draw(self):
|
||||
if self.combo == 0:
|
||||
@@ -1800,6 +1815,7 @@ class FailAnimation:
|
||||
self.text_fade_in.start()
|
||||
self.name = 'in'
|
||||
self.frame = self.bachio_texture_change.attribute
|
||||
audio.play_sound('fail')
|
||||
def update(self, current_time_ms: float):
|
||||
self.bachio_fade_in.update(current_time_ms)
|
||||
self.bachio_texture_change.update(current_time_ms)
|
||||
@@ -1843,6 +1859,7 @@ class ClearAnimation:
|
||||
self.draw_clear_full = False
|
||||
self.name = 'in'
|
||||
self.frame = 0
|
||||
audio.play_sound('clear')
|
||||
|
||||
def update(self, current_time_ms: float):
|
||||
self.bachio_fade_in.update(current_time_ms)
|
||||
@@ -1899,6 +1916,7 @@ class FCAnimation:
|
||||
self.draw_clear_full = False
|
||||
self.name = 'in'
|
||||
self.frame = 0
|
||||
audio.play_sound('full_combo')
|
||||
|
||||
def update(self, current_time_ms: float):
|
||||
self.bachio_fade_in.update(current_time_ms)
|
||||
@@ -1918,6 +1936,7 @@ class FCAnimation:
|
||||
self.bachio_move_up.start()
|
||||
self.fan_fade_in.start()
|
||||
self.fan_texture_change.start()
|
||||
audio.play_sound('full_combo_voice')
|
||||
if self.clear_highlight_fade_in.attribute == 1.0:
|
||||
self.draw_clear_full = True
|
||||
for fade in self.clear_separate_fade_in:
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
from pathlib import Path
|
||||
|
||||
import pyray as ray
|
||||
|
||||
from libs import utils
|
||||
@@ -28,23 +26,13 @@ class ResultScreen:
|
||||
self.height = 720
|
||||
self.screen_init = False
|
||||
|
||||
def load_textures(self):
|
||||
tex.load_screen_textures('result')
|
||||
|
||||
def load_sounds(self):
|
||||
sounds_dir = Path("Sounds")
|
||||
self.sound_don = audio.load_sound(sounds_dir / "hit_sounds" / "0" / "don.wav")
|
||||
self.sound_kat = audio.load_sound(sounds_dir / "hit_sounds" / "0" / "ka.wav")
|
||||
self.sound_num_up = audio.load_sound(sounds_dir / "result" / "SE_RESULT [4].ogg")
|
||||
self.bgm = audio.load_sound(sounds_dir / "result" / "JINGLE_SEISEKI [1].ogg")
|
||||
|
||||
def on_screen_start(self):
|
||||
if not self.screen_init:
|
||||
self.load_textures()
|
||||
self.load_sounds()
|
||||
tex.load_screen_textures('result')
|
||||
audio.load_screen_sounds('result')
|
||||
self.screen_init = True
|
||||
self.song_info = OutlinedText(session_data.song_title, 40, ray.WHITE, ray.BLACK, outline_thickness=5)
|
||||
audio.play_sound(self.bgm)
|
||||
audio.play_sound('bgm')
|
||||
self.fade_in = FadeIn()
|
||||
self.fade_out = tex.get_animation(0)
|
||||
self.fade_in_bottom = tex.get_animation(1)
|
||||
@@ -86,7 +74,9 @@ class ResultScreen:
|
||||
self.screen_init = False
|
||||
global_data.songs_played += 1
|
||||
tex.unload_textures()
|
||||
audio.stop_sound(self.bgm)
|
||||
audio.stop_sound('bgm')
|
||||
audio.unload_all_sounds()
|
||||
audio.unload_all_music()
|
||||
utils.session_data = utils.reset_session()
|
||||
return "SONG_SELECT"
|
||||
|
||||
@@ -102,9 +92,9 @@ class ResultScreen:
|
||||
curr_num = self.update_list[self.update_index][0]
|
||||
setattr(self, self.update_list[self.update_index][0], self.score_animator.next_score())
|
||||
if self.update_list[self.update_index] != curr_num:
|
||||
audio.play_sound(self.sound_num_up)
|
||||
audio.play_sound('num_up')
|
||||
if self.score_animator.is_finished:
|
||||
audio.play_sound(self.sound_don)
|
||||
audio.play_sound('don')
|
||||
self.score_delay += 750
|
||||
if self.update_index == len(self.update_list) - 1:
|
||||
self.is_skipped = True
|
||||
@@ -122,7 +112,7 @@ class ResultScreen:
|
||||
self.is_skipped = True
|
||||
else:
|
||||
self.fade_out.start()
|
||||
audio.play_sound(self.sound_don)
|
||||
audio.play_sound('don')
|
||||
|
||||
def update(self):
|
||||
self.on_screen_start()
|
||||
@@ -281,7 +271,6 @@ class Crown:
|
||||
self.white_fadein.start()
|
||||
self.gleam.start()
|
||||
self.fadein.start()
|
||||
self.sound = audio.load_sound(Path('Sounds/result/SE_RESULT [1].ogg'))
|
||||
self.sound_played = False
|
||||
|
||||
def update(self, current_ms: float):
|
||||
@@ -291,7 +280,7 @@ class Crown:
|
||||
self.white_fadein.update(current_ms)
|
||||
self.gleam.update(current_ms)
|
||||
if self.resize_fix.is_finished and not self.sound_played:
|
||||
audio.play_sound(self.sound)
|
||||
audio.play_sound('crown')
|
||||
self.sound_played = True
|
||||
|
||||
def draw(self, crown_name: str):
|
||||
|
||||
@@ -43,21 +43,14 @@ class SongSelectScreen:
|
||||
def load_navigator(self):
|
||||
self.navigator = FileNavigator(self.root_dir)
|
||||
|
||||
def load_sounds(self):
|
||||
sounds_dir = Path("Sounds")
|
||||
self.sound_don = audio.load_sound(sounds_dir / "hit_sounds" / "0" / "don.wav")
|
||||
self.sound_kat = audio.load_sound(sounds_dir / "hit_sounds" / "0" / "ka.wav")
|
||||
self.sound_skip = audio.load_sound(sounds_dir / 'song_select' / 'Skip.ogg')
|
||||
self.sound_ura_switch = audio.load_sound(sounds_dir / 'song_select' / 'SE_SELECT [4].ogg')
|
||||
self.sound_add_favorite = audio.load_sound(sounds_dir / 'song_select' / 'add_favorite.ogg')
|
||||
audio.set_sound_volume(self.sound_ura_switch, 0.25)
|
||||
audio.set_sound_volume(self.sound_add_favorite, 3.0)
|
||||
self.sound_bgm = audio.load_sound(sounds_dir / "song_select" / "JINGLE_GENRE [1].ogg")
|
||||
|
||||
def on_screen_start(self):
|
||||
if not self.screen_init:
|
||||
tex.load_screen_textures('song_select')
|
||||
self.load_sounds()
|
||||
audio.load_screen_sounds('song_select')
|
||||
audio.set_sound_volume('ura_switch', 0.25)
|
||||
audio.set_sound_volume('add_favorite', 3.0)
|
||||
audio.play_sound('bgm')
|
||||
audio.play_sound('voice_enter')
|
||||
self.background_move = tex.get_animation(0)
|
||||
self.move_away = tex.get_animation(1)
|
||||
self.diff_fade_out = tex.get_animation(2)
|
||||
@@ -120,6 +113,7 @@ class SongSelectScreen:
|
||||
self.reset_demo_music()
|
||||
self.navigator.reset_items()
|
||||
audio.unload_all_sounds()
|
||||
audio.unload_all_music()
|
||||
tex.unload_textures()
|
||||
self.nameplate.unload()
|
||||
return next_screen
|
||||
@@ -128,7 +122,7 @@ class SongSelectScreen:
|
||||
if self.demo_song is not None:
|
||||
audio.stop_music_stream(self.demo_song)
|
||||
audio.unload_music_stream(self.demo_song)
|
||||
audio.play_sound(self.sound_bgm)
|
||||
audio.play_sound('bgm')
|
||||
self.demo_song = None
|
||||
self.navigator.get_current_item().box.wait = get_current_ms()
|
||||
|
||||
@@ -137,24 +131,24 @@ class SongSelectScreen:
|
||||
self.reset_demo_music()
|
||||
for _ in range(10):
|
||||
self.navigator.navigate_left()
|
||||
audio.play_sound(self.sound_skip)
|
||||
audio.play_sound('skip')
|
||||
self.last_moved = get_current_ms()
|
||||
elif ray.is_key_pressed(ray.KeyboardKey.KEY_RIGHT_CONTROL) or (is_r_kat_pressed() and get_current_ms() <= self.last_moved + 50):
|
||||
self.reset_demo_music()
|
||||
for _ in range(10):
|
||||
self.navigator.navigate_right()
|
||||
audio.play_sound(self.sound_skip)
|
||||
audio.play_sound('skip')
|
||||
self.last_moved = get_current_ms()
|
||||
elif is_l_kat_pressed():
|
||||
self.reset_demo_music()
|
||||
self.navigator.navigate_left()
|
||||
audio.play_sound(self.sound_kat)
|
||||
audio.play_sound('kat')
|
||||
self.last_moved = get_current_ms()
|
||||
|
||||
elif is_r_kat_pressed():
|
||||
self.reset_demo_music()
|
||||
self.navigator.navigate_right()
|
||||
audio.play_sound(self.sound_kat)
|
||||
audio.play_sound('kat')
|
||||
self.last_moved = get_current_ms()
|
||||
|
||||
# Select/Enter
|
||||
@@ -162,7 +156,7 @@ class SongSelectScreen:
|
||||
selected_item = self.navigator.items[self.navigator.selected_index]
|
||||
if selected_item is not None and selected_item.box.is_back:
|
||||
self.navigator.go_back()
|
||||
#audio.play_sound(self.sound_cancel)
|
||||
audio.play_sound('cancel')
|
||||
elif isinstance(selected_item, Directory) and selected_item.collection == Directory.COLLECTIONS[3]:
|
||||
self.state = State.DIFF_SORTING
|
||||
self.diff_sort_selector = DiffSortSelect(self.navigator.diff_sort_statistics, self.navigator.diff_sort_diff, self.navigator.diff_sort_level)
|
||||
@@ -177,7 +171,8 @@ class SongSelectScreen:
|
||||
elif (4 in selected_song.tja.metadata.course_data and
|
||||
3 not in selected_song.tja.metadata.course_data):
|
||||
self.is_ura = True
|
||||
audio.play_sound(self.sound_don)
|
||||
audio.play_sound('don')
|
||||
audio.play_sound('voice_select_diff')
|
||||
self.move_away.start()
|
||||
self.diff_fade_out.start()
|
||||
self.text_fade_out.start()
|
||||
@@ -188,7 +183,7 @@ class SongSelectScreen:
|
||||
if ray.is_key_pressed(ray.KeyboardKey.KEY_SPACE):
|
||||
success = self.navigator.add_favorite()
|
||||
if success:
|
||||
audio.play_sound(self.sound_add_favorite)
|
||||
audio.play_sound('add_favorite')
|
||||
|
||||
def handle_input_selected(self):
|
||||
# Handle song selection confirmation or cancel
|
||||
@@ -198,28 +193,28 @@ class SongSelectScreen:
|
||||
elif is_r_kat_pressed():
|
||||
self.neiro_selector.move_right()
|
||||
if is_l_don_pressed() or is_r_don_pressed():
|
||||
audio.play_sound(self.sound_don)
|
||||
audio.play_sound('don')
|
||||
self.neiro_selector.confirm()
|
||||
return
|
||||
if self.modifier_selector is not None:
|
||||
if is_l_kat_pressed():
|
||||
audio.play_sound(self.sound_kat)
|
||||
audio.play_sound('kat')
|
||||
self.modifier_selector.left()
|
||||
elif is_r_kat_pressed():
|
||||
audio.play_sound(self.sound_kat)
|
||||
audio.play_sound('kat')
|
||||
self.modifier_selector.right()
|
||||
if is_l_don_pressed() or is_r_don_pressed():
|
||||
audio.play_sound(self.sound_don)
|
||||
audio.play_sound('don')
|
||||
self.modifier_selector.confirm()
|
||||
return
|
||||
if is_l_don_pressed() or is_r_don_pressed():
|
||||
if self.selected_difficulty == -3:
|
||||
self._cancel_selection()
|
||||
elif self.selected_difficulty == -2:
|
||||
audio.play_sound(self.sound_don)
|
||||
audio.play_sound('don')
|
||||
self.modifier_selector = ModifierSelector()
|
||||
elif self.selected_difficulty == -1:
|
||||
audio.play_sound(self.sound_don)
|
||||
audio.play_sound('don')
|
||||
self.neiro_selector = NeiroSelector()
|
||||
else:
|
||||
self._confirm_selection()
|
||||
@@ -231,7 +226,7 @@ class SongSelectScreen:
|
||||
return selected_song
|
||||
|
||||
if is_l_kat_pressed() or is_r_kat_pressed():
|
||||
audio.play_sound(self.sound_kat)
|
||||
audio.play_sound('kat')
|
||||
selected_song = get_current_song()
|
||||
diffs = sorted(selected_song.tja.metadata.course_data)
|
||||
prev_diff = self.selected_difficulty
|
||||
@@ -254,13 +249,13 @@ class SongSelectScreen:
|
||||
raise Exception("Diff sort selector was not able to be created")
|
||||
if is_l_kat_pressed():
|
||||
self.diff_sort_selector.input_left()
|
||||
audio.play_sound(self.sound_kat)
|
||||
audio.play_sound('kat')
|
||||
if is_r_kat_pressed():
|
||||
self.diff_sort_selector.input_right()
|
||||
audio.play_sound(self.sound_kat)
|
||||
audio.play_sound('kat')
|
||||
if is_l_don_pressed() or is_r_don_pressed():
|
||||
tuple = self.diff_sort_selector.input_select()
|
||||
audio.play_sound(self.sound_don)
|
||||
audio.play_sound('don')
|
||||
if tuple is None:
|
||||
return
|
||||
diff, level = tuple
|
||||
@@ -289,7 +284,8 @@ class SongSelectScreen:
|
||||
|
||||
def _confirm_selection(self):
|
||||
"""Confirm song selection and create game transition"""
|
||||
audio.play_sound(self.sound_don)
|
||||
audio.play_sound('don')
|
||||
audio.play_sound(f'voice_start_song_{global_data.player_num}p')
|
||||
self.selected_diff_highlight_fade.start()
|
||||
self.selected_diff_text_resize.start()
|
||||
self.selected_diff_text_fadein.start()
|
||||
@@ -354,7 +350,7 @@ class SongSelectScreen:
|
||||
self.ura_toggle = 0
|
||||
self.is_ura = not self.is_ura
|
||||
self.ura_switch_animation.start(not self.is_ura)
|
||||
audio.play_sound(self.sound_ura_switch)
|
||||
audio.play_sound('ura_switch')
|
||||
self.selected_difficulty = 7 - self.selected_difficulty
|
||||
|
||||
def handle_input(self):
|
||||
@@ -431,7 +427,7 @@ class SongSelectScreen:
|
||||
if self.modifier_selector.is_finished:
|
||||
self.modifier_selector = None
|
||||
|
||||
if self.selected_diff_highlight_fade.is_finished and self.game_transition is None:
|
||||
if self.selected_diff_highlight_fade.is_finished and not audio.is_sound_playing(f'voice_start_song_{global_data.player_num}p') and self.game_transition is None:
|
||||
selected_song = self.navigator.get_current_item()
|
||||
if not isinstance(selected_song, SongFile):
|
||||
raise Exception("picked directory")
|
||||
@@ -450,10 +446,10 @@ class SongSelectScreen:
|
||||
if self.demo_song is None and get_current_ms() >= song.box.wait + (83.33*3):
|
||||
song.box.get_scores()
|
||||
if song.tja.metadata.wave.exists() and song.tja.metadata.wave.is_file():
|
||||
self.demo_song = audio.load_music_stream(song.tja.metadata.wave)
|
||||
self.demo_song = audio.load_music_stream(song.tja.metadata.wave, 'demo_song')
|
||||
audio.play_music_stream(self.demo_song)
|
||||
audio.seek_music_stream(self.demo_song, song.tja.metadata.demostart)
|
||||
audio.stop_sound(self.sound_bgm)
|
||||
audio.stop_sound('bgm')
|
||||
if song.box.is_open:
|
||||
current_box = song.box
|
||||
if not current_box.is_back and get_current_ms() >= song.box.wait + (83.33*3):
|
||||
@@ -623,6 +619,10 @@ class SongBox:
|
||||
self.target_position = -1
|
||||
self.is_open = False
|
||||
self.is_back = self.texture_index == SongBox.BACK_INDEX
|
||||
if self.is_back:
|
||||
for i in range(1, 16):
|
||||
if audio.is_sound_playing(f'genre_voice_{i}'):
|
||||
audio.stop_sound(f'genre_voice_{i}')
|
||||
self.name = None
|
||||
self.black_name = None
|
||||
self.hori_name = None
|
||||
@@ -732,6 +732,10 @@ class SongBox:
|
||||
self.wait = get_current_ms()
|
||||
if get_current_ms() >= self.history_wait + 3000:
|
||||
self.history_wait = get_current_ms()
|
||||
if self.tja is None and self.texture_index != 17 and not audio.is_sound_playing('voice_enter'):
|
||||
audio.play_sound(f'genre_voice_{self.texture_index}')
|
||||
elif not self.is_open and is_open_prev and audio.is_sound_playing(f'genre_voice_{self.texture_index}'):
|
||||
audio.stop_sound(f'genre_voice_{self.texture_index}')
|
||||
if self.tja_count is not None and self.tja_count > 0 and self.tja_count_text is None:
|
||||
self.tja_count_text = OutlinedText(str(self.tja_count), 35, ray.WHITE, ray.BLACK, outline_thickness=5)#, horizontal_spacing=1.2)
|
||||
if self.box_texture is None and self.box_texture_path is not None:
|
||||
@@ -771,11 +775,11 @@ class SongBox:
|
||||
if valid_scores:
|
||||
highest_key = max(valid_scores.keys())
|
||||
score = self.scores[highest_key]
|
||||
if score and score[2] == 0 and score[3] == 0:
|
||||
if score and ((score[4] == 2 and score[2] == 0) or (score[2] == 0 and score[3] == 0)):
|
||||
tex.draw_texture('yellow_box', 'crown_dfc', x=x, y=y, frame=min(4, highest_key))
|
||||
elif score and score[3] == 0:
|
||||
elif score and ((score[4] == 2) or (score[3] == 0)):
|
||||
tex.draw_texture('yellow_box', 'crown_fc', x=x, y=y, frame=min(4, highest_key))
|
||||
elif score and score[4] == 1:
|
||||
elif score and score[4] >= 1:
|
||||
tex.draw_texture('yellow_box', 'crown_clear', x=x, y=y, frame=min(4, highest_key))
|
||||
if self.crown: #Folder lamp
|
||||
highest_crown = max(self.crown)
|
||||
@@ -934,11 +938,11 @@ class YellowBox:
|
||||
for diff in self.tja.metadata.course_data:
|
||||
if diff >= 4:
|
||||
continue
|
||||
elif diff in song_box.scores and song_box.scores[diff] is not None and song_box.scores[diff][2] == 0 and song_box.scores[diff][3] == 0:
|
||||
elif diff in song_box.scores and song_box.scores[diff] is not None and ((song_box.scores[diff][4] == 2 and song_box.scores[diff][2] == 0) or (song_box.scores[diff][2] == 0 and song_box.scores[diff][3] == 0)):
|
||||
tex.draw_texture('yellow_box', 's_crown_dfc', x=(diff*60), color=color)
|
||||
elif diff in song_box.scores and song_box.scores[diff] is not None and song_box.scores[diff][3] == 0:
|
||||
elif diff in song_box.scores and song_box.scores[diff] is not None and ((song_box.scores[diff][4] == 2) or (song_box.scores[diff][3] == 0)):
|
||||
tex.draw_texture('yellow_box', 's_crown_fc', x=(diff*60), color=color)
|
||||
elif diff in song_box.scores and song_box.scores[diff] is not None and song_box.scores[diff][4] == 1:
|
||||
elif diff in song_box.scores and song_box.scores[diff] is not None and song_box.scores[diff][4] >= 1:
|
||||
tex.draw_texture('yellow_box', 's_crown_clear', x=(diff*60), color=color)
|
||||
tex.draw_texture('yellow_box', 's_crown_outline', x=(diff*60), fade=min(fade, 0.25))
|
||||
|
||||
@@ -974,11 +978,11 @@ class YellowBox:
|
||||
for diff in self.tja.metadata.course_data:
|
||||
if diff >= 4:
|
||||
continue
|
||||
elif diff in song_box.scores and song_box.scores[diff] is not None and song_box.scores[diff][2] == 0 and song_box.scores[diff][3] == 0:
|
||||
elif diff in song_box.scores and song_box.scores[diff] is not None and ((song_box.scores[diff][4] == 2 and song_box.scores[diff][2] == 0) or (song_box.scores[diff][2] == 0 and song_box.scores[diff][3] == 0)):
|
||||
tex.draw_texture('yellow_box', 's_crown_dfc', x=(diff*115)+8, y=-120, fade=self.fade_in.attribute)
|
||||
elif diff in song_box.scores and song_box.scores[diff] is not None and song_box.scores[diff][3] == 0:
|
||||
elif diff in song_box.scores and song_box.scores[diff] is not None and ((song_box.scores[diff][4] == 2) or (song_box.scores[diff][3] == 0)):
|
||||
tex.draw_texture('yellow_box', 's_crown_fc', x=(diff*115)+8, y=-120, fade=self.fade_in.attribute)
|
||||
elif diff in song_box.scores and song_box.scores[diff] is not None and song_box.scores[diff][4] == 1:
|
||||
elif diff in song_box.scores and song_box.scores[diff] is not None and song_box.scores[diff][4] >= 1:
|
||||
tex.draw_texture('yellow_box', 's_crown_clear', x=(diff*115)+8, y=-120, fade=self.fade_in.attribute)
|
||||
tex.draw_texture('yellow_box', 's_crown_outline', x=(diff*115)+8, y=-120, fade=min(self.fade_in.attribute, 0.25))
|
||||
|
||||
@@ -1152,6 +1156,7 @@ class DiffSortSelect:
|
||||
]
|
||||
for course, levels in self.diff_sort_statistics.items()
|
||||
}
|
||||
audio.play_sound('voice_diff_sort_enter')
|
||||
|
||||
def update(self, current_ms):
|
||||
self.bg_resize.update(current_ms)
|
||||
@@ -1194,6 +1199,7 @@ class DiffSortSelect:
|
||||
self.bounce_up_2.start()
|
||||
self.bounce_down_2.start()
|
||||
self.confirm_index = 1
|
||||
audio.play_sound('voice_diff_sort_confirm')
|
||||
return None
|
||||
if self.selected_box == -1:
|
||||
return (-1, -1)
|
||||
@@ -1201,6 +1207,7 @@ class DiffSortSelect:
|
||||
return (0, -1)
|
||||
elif self.selected_box == 4:
|
||||
return self.get_random_sort()
|
||||
audio.play_sound('voice_diff_sort_level')
|
||||
self.in_level_select = True
|
||||
self.bg_resize.start()
|
||||
self.diff_fade_in.start()
|
||||
@@ -1356,6 +1363,7 @@ class NeiroSelector:
|
||||
self.sounds = neiro_list.readlines()
|
||||
self.sounds.append('無音')
|
||||
self.load_sound()
|
||||
audio.play_sound(f'voice_hitsound_select_{global_data.player_num}p')
|
||||
self.is_finished = False
|
||||
self.is_confirmed = False
|
||||
self.move = tex.get_animation(28)
|
||||
@@ -1372,9 +1380,9 @@ class NeiroSelector:
|
||||
if self.selected_sound == len(self.sounds):
|
||||
return
|
||||
if self.selected_sound == 0:
|
||||
self.curr_sound = audio.load_sound(Path("Sounds") / "hit_sounds" / str(self.selected_sound) / "don.wav")
|
||||
self.curr_sound = audio.load_sound(Path("Sounds") / "hit_sounds" / str(self.selected_sound) / "don.wav", 'hit_sound')
|
||||
else:
|
||||
self.curr_sound = audio.load_sound(Path("Sounds") / "hit_sounds" / str(self.selected_sound) / "don.ogg")
|
||||
self.curr_sound = audio.load_sound(Path("Sounds") / "hit_sounds" / str(self.selected_sound) / "don.ogg", 'hit_sound')
|
||||
|
||||
def move_left(self):
|
||||
if self.move.is_started and not self.move.is_finished:
|
||||
@@ -1484,6 +1492,7 @@ class ModifierSelector:
|
||||
self.move_sideways = tex.get_animation(31)
|
||||
self.fade_sideways = tex.get_animation(32)
|
||||
self.direction = -1
|
||||
audio.play_sound(f'voice_options_{global_data.player_num}p')
|
||||
self.text_name = [OutlinedText(ModifierSelector.NAME_MAP[mod.name], 30, ray.WHITE, ray.BLACK, outline_thickness=3.5) for mod in self.mods]
|
||||
self.text_true = OutlinedText('する', 30, ray.WHITE, ray.BLACK, outline_thickness=3.5)
|
||||
self.text_false = OutlinedText('しない', 30, ray.WHITE, ray.BLACK, outline_thickness=3.5)
|
||||
@@ -1921,8 +1930,8 @@ class FileNavigator:
|
||||
|
||||
scores = song_obj.box.scores.get(course)
|
||||
if scores is not None:
|
||||
is_cleared = scores[4] == 1
|
||||
is_full_combo = scores[3] == 0
|
||||
is_cleared = scores[4] >= 1
|
||||
is_full_combo = (scores[4] == 2) or (scores[3] == 0)
|
||||
else:
|
||||
is_cleared = False
|
||||
is_full_combo = False
|
||||
@@ -2181,11 +2190,11 @@ class FileNavigator:
|
||||
all_scores[diff].append(song_obj.box.scores[diff])
|
||||
|
||||
for diff in all_scores:
|
||||
if all(score is not None and score[2] == 0 and score[3] == 0 for score in all_scores[diff]):
|
||||
if all(score is not None and ((score[4] == 2 and score[2] == 0) or (score[2] == 0 and score[3] == 0)) for score in all_scores[diff]):
|
||||
crowns[diff] = 'DFC'
|
||||
elif all(score is not None and score[3] == 0 for score in all_scores[diff]):
|
||||
elif all(score is not None and ((score[4] == 2) or (score[3] == 0)) for score in all_scores[diff]):
|
||||
crowns[diff] = 'FC'
|
||||
elif all(score is not None and score[4] == 1 for score in all_scores[diff]):
|
||||
elif all(score is not None and score[4] >= 1 for score in all_scores[diff]):
|
||||
crowns[diff] = 'CLEAR'
|
||||
|
||||
self.directory_crowns[dir_key] = crowns
|
||||
|
||||
@@ -30,20 +30,11 @@ class TitleScreen:
|
||||
self.allnet_indicator = AllNetIcon()
|
||||
self.entry_overlay = EntryOverlay()
|
||||
|
||||
def load_sounds(self):
|
||||
sounds_dir = Path("Sounds")
|
||||
title_dir = sounds_dir / "title"
|
||||
self.sound_don = audio.load_sound(sounds_dir / "hit_sounds" / "0" / "don.wav")
|
||||
self.sound_bachi_swipe = audio.load_sound(title_dir / "SE_ATTRACT_2.ogg")
|
||||
self.sound_bachi_hit = audio.load_sound(title_dir / "SE_ATTRACT_3.ogg")
|
||||
self.sound_warning_message = audio.load_sound(title_dir / "VO_ATTRACT_3.ogg")
|
||||
self.sound_warning_error = audio.load_sound(title_dir / "SE_ATTRACT_1.ogg")
|
||||
|
||||
def on_screen_start(self):
|
||||
if not self.screen_init:
|
||||
self.screen_init = True
|
||||
tex.load_screen_textures('title')
|
||||
self.load_sounds()
|
||||
audio.load_screen_sounds('title')
|
||||
self.state = State.OP_VIDEO
|
||||
self.op_video = None
|
||||
self.attract_video = None
|
||||
@@ -57,15 +48,16 @@ class TitleScreen:
|
||||
if self.attract_video is not None:
|
||||
self.attract_video.stop()
|
||||
audio.unload_all_sounds()
|
||||
audio.unload_all_music()
|
||||
tex.unload_textures()
|
||||
self.screen_init = False
|
||||
return "ENTRY"
|
||||
|
||||
def scene_manager(self):
|
||||
def scene_manager(self, current_time):
|
||||
if self.state == State.OP_VIDEO:
|
||||
if self.op_video is None:
|
||||
self.op_video = VideoPlayer(random.choice(self.op_video_list))
|
||||
self.op_video.start(get_current_ms())
|
||||
self.op_video.start(current_time)
|
||||
self.op_video.update()
|
||||
if self.op_video.is_finished():
|
||||
self.op_video.stop()
|
||||
@@ -73,15 +65,15 @@ class TitleScreen:
|
||||
self.state = State.WARNING
|
||||
elif self.state == State.WARNING:
|
||||
if self.warning_board is None:
|
||||
self.warning_board = WarningScreen(get_current_ms())
|
||||
self.warning_board.update(get_current_ms(), self)
|
||||
self.warning_board = WarningScreen(current_time)
|
||||
self.warning_board.update(current_time)
|
||||
if self.warning_board.is_finished:
|
||||
self.state = State.ATTRACT_VIDEO
|
||||
self.warning_board = None
|
||||
elif self.state == State.ATTRACT_VIDEO:
|
||||
if self.attract_video is None:
|
||||
self.attract_video = VideoPlayer(random.choice(self.attract_video_list))
|
||||
self.attract_video.start(get_current_ms())
|
||||
self.attract_video.start(current_time)
|
||||
self.attract_video.update()
|
||||
if self.attract_video.is_finished():
|
||||
self.attract_video.stop()
|
||||
@@ -91,17 +83,18 @@ class TitleScreen:
|
||||
|
||||
def update(self):
|
||||
self.on_screen_start()
|
||||
current_time = get_current_ms()
|
||||
|
||||
self.text_overlay_fade.update(get_current_ms())
|
||||
self.fade_out.update(get_current_ms())
|
||||
self.text_overlay_fade.update(current_time)
|
||||
self.fade_out.update(current_time)
|
||||
if self.fade_out.is_finished:
|
||||
self.fade_out.update(get_current_ms())
|
||||
self.fade_out.update(current_time)
|
||||
return self.on_screen_end()
|
||||
|
||||
self.scene_manager()
|
||||
self.scene_manager(current_time)
|
||||
if is_l_don_pressed() or is_r_don_pressed():
|
||||
self.fade_out.start()
|
||||
audio.play_sound(self.sound_don)
|
||||
audio.play_sound('don')
|
||||
|
||||
def draw(self):
|
||||
if self.state == State.OP_VIDEO and self.op_video is not None:
|
||||
@@ -134,13 +127,13 @@ class WarningScreen:
|
||||
self.fadein_2.start()
|
||||
self.sound_played = False
|
||||
|
||||
def update(self, current_ms: float, sound):
|
||||
def update(self, current_ms: float):
|
||||
self.resize.update(current_ms)
|
||||
self.fadein.update(current_ms)
|
||||
self.fadein_2.update(current_ms)
|
||||
|
||||
if self.resize.attribute > 1 and not self.sound_played:
|
||||
audio.play_sound(sound)
|
||||
audio.play_sound('error')
|
||||
self.sound_played = True
|
||||
|
||||
def draw_bg(self):
|
||||
@@ -156,9 +149,9 @@ class WarningScreen:
|
||||
|
||||
self.sound_played = False
|
||||
|
||||
def update(self, current_ms: float, sound):
|
||||
def update(self, current_ms: float):
|
||||
if not self.sound_played:
|
||||
audio.play_sound(sound)
|
||||
audio.play_sound('bachi_hit')
|
||||
self.sound_played = True
|
||||
self.fadein.start()
|
||||
self.resize.start()
|
||||
@@ -241,22 +234,22 @@ class WarningScreen:
|
||||
|
||||
self.is_finished = False
|
||||
|
||||
def update(self, current_ms: float, title_screen: TitleScreen):
|
||||
def update(self, current_ms: float):
|
||||
self.board.update(current_ms)
|
||||
self.fade_in.update(current_ms)
|
||||
self.fade_out.update(current_ms)
|
||||
delay = 566.67
|
||||
elapsed_time = current_ms - self.start_ms
|
||||
self.warning_x.update(current_ms, title_screen.sound_warning_error)
|
||||
self.warning_x.update(current_ms)
|
||||
self.characters.update(current_ms)
|
||||
|
||||
if self.characters.is_finished:
|
||||
self.warning_bachi_hit.update(current_ms, title_screen.sound_bachi_hit)
|
||||
self.warning_bachi_hit.update(current_ms)
|
||||
else:
|
||||
self.fade_out.delay = elapsed_time + 500
|
||||
if delay <= elapsed_time and not audio.is_sound_playing(title_screen.sound_bachi_swipe):
|
||||
audio.play_sound(title_screen.sound_warning_message)
|
||||
audio.play_sound(title_screen.sound_bachi_swipe)
|
||||
if delay <= elapsed_time and not audio.is_sound_playing('bachi_swipe'):
|
||||
audio.play_sound('warning_voiceover')
|
||||
audio.play_sound('bachi_swipe')
|
||||
|
||||
self.is_finished = self.fade_out.is_finished
|
||||
|
||||
|
||||
Reference in New Issue
Block a user