improve results screen, fix many bugs

This commit is contained in:
Yonokid
2025-04-25 17:56:35 -04:00
parent ac927114cb
commit e2552c0e86
11 changed files with 381 additions and 172 deletions

View File

@@ -10,9 +10,20 @@ class EntryScreen:
self.texture_footer = load_texture_from_zip('Graphics\\lumendata\\entry.zip', 'entry_img00375.png')
self.screen_init = False
def on_screen_start(self):
if not self.screen_init:
self.screen_init = True
def on_screen_end(self):
self.screen_init = False
return "SONG_SELECT"
def update(self):
self.on_screen_start()
if ray.is_key_pressed(ray.KeyboardKey.KEY_ENTER):
return "SONG_SELECT"
return self.on_screen_end()
def draw(self):
ray.draw_texture(self.texture_footer, 0, self.height - 151, ray.WHITE)

View File

@@ -24,7 +24,12 @@ class GameScreen:
self.height = height
self.judge_x = 414
self.current_ms = 0
self.song_is_started = False
self.result_transition = None
self.song_info = None
self.screen_init = False
def load_textures(self):
self.textures = load_all_textures_from_zip('Graphics\\lumendata\\enso_system\\common.zip')
@@ -130,11 +135,16 @@ class GameScreen:
self.textures.update(load_all_textures_from_zip('Graphics\\lumendata\\enso_system\\base1p.zip'))
self.textures.update(load_all_textures_from_zip('Graphics\\lumendata\\enso_system\\don1p.zip'))
self.result_transition_1 = load_texture_from_zip('Graphics\\lumendata\\enso_result.zip', 'retry_game_img00125.png')
self.result_transition_2 = load_texture_from_zip('Graphics\\lumendata\\enso_result.zip', 'retry_game_img00126.png')
def load_sounds(self):
self.sound_don = audio.load_sound('Sounds\\inst_00_don.wav')
self.sound_kat = audio.load_sound('Sounds\\inst_00_katsu.wav')
self.sound_balloon_pop = audio.load_sound('Sounds\\balloon_pop.wav')
self.sound_result_transition = audio.load_sound('Sounds\\result\\VO_RESULT [1].ogg')
def init_tja(self, song: str, difficulty: int):
self.load_textures()
self.load_sounds()
@@ -165,24 +175,46 @@ class GameScreen:
audio.play_sound(self.song_music)
def on_screen_start(self):
if not self.screen_init:
self.screen_init = True
self.init_tja(global_data.selected_song, global_data.selected_difficulty)
self.current_ms = get_current_ms() - self.start_ms
self.song_info = SongInfo(self.current_ms, self.tja.title, 'TEST')
self.result_transition = None
def on_screen_end(self):
self.screen_init = False
for zip in self.textures:
for texture in self.textures[zip]:
ray.unload_texture(texture)
return 'RESULT'
def update(self):
if global_data.start_song and not self.song_is_started:
self.init_tja(global_data.selected_song, global_data.selected_difficulty)
self.song_is_started = True
self.on_screen_start()
self.current_ms = get_current_ms() - self.start_ms
self.player_1.update(self)
if len(self.player_1.play_note_list) == 0 and not audio.is_sound_playing(self.song_music):
self.player_1.update(self)
if self.song_info is not None:
self.song_info.update(self.current_ms)
if self.result_transition is not None:
self.result_transition.update(self.current_ms)
if self.result_transition.is_finished:
return self.on_screen_end()
elif len(self.player_1.play_note_list) == 0 and (len(self.player_1.current_notes) == 0) and not audio.is_sound_playing(self.song_music):
global_data.result_good, global_data.result_ok, global_data.result_bad, global_data.result_score = self.player_1.get_result_score()
global_data.start_song = False
self.song_is_started = False
return 'RESULT'
self.result_transition = ResultTransition(self.current_ms, self.height)
audio.play_sound(self.sound_result_transition)
def draw(self):
self.player_1.draw(self)
if self.song_info is not None:
self.song_info.draw(self)
if self.result_transition is not None:
self.result_transition.draw(self.width, self.height, self.result_transition_1, self.result_transition_2)
class Player:
def __init__(self, game_screen: GameScreen, player_number: int, difficulty: int, judge_offset: int):
@@ -218,6 +250,7 @@ class Player:
self.combo = 0
self.score = 0
self.max_combo = 0
self.total_drumroll = 0
self.arc_points = 25
@@ -225,12 +258,11 @@ class Player:
self.draw_effect_list: list[LaneHitEffect] = []
self.draw_arc_list: list[NoteArc] = []
self.draw_drum_hit_list: list[DrumHitEffect] = []
self.drumroll_counter: list[DrumrollCounter] = []
self.drumroll_counter: DrumrollCounter | None = None
self.balloon_list: list[BalloonAnimation] = []
self.base_score_list: list[ScoreCounterAnimation] = []
self.combo_display = Combo(self.combo, game_screen.current_ms)
self.score_counter = ScoreCounter(self.score, game_screen.current_ms)
self.song_info = SongInfo(game_screen.current_ms, game_screen.tja.title, 'TEST')
self.input_log: dict[float, str] = dict()
@@ -304,7 +336,6 @@ class Player:
else:
bisect.insort_left(self.current_notes_draw, self.draw_note_list.popleft(), key=lambda x: x['index'])
#If a note is off screen, remove it
if len(self.current_notes_draw) == 0:
return
@@ -316,8 +347,6 @@ class Player:
note = self.current_notes_draw[1]
position = self.get_position(game_screen, note['ms'], note['ppf'])
if position < game_screen.judge_x + 650:
if note['note'] == '8':
self.current_notes_draw.pop(0)
self.current_notes_draw.pop(0)
def note_manager(self, game_screen: GameScreen):
@@ -347,6 +376,7 @@ class Player:
note_type = game_screen.note_type_dict[str(int(drum_type)+self.drumroll_big)]
self.draw_arc_list.append(NoteArc(note_type, game_screen.current_ms, self.player_number))
self.curr_drumroll_count += 1
self.total_drumroll += 1
self.score += 100
self.base_score_list.append(ScoreCounterAnimation(game_screen.current_ms, 100))
color = max(0, 255 - (self.curr_drumroll_count * 10))
@@ -359,6 +389,7 @@ class Player:
if len(self.balloon_list) < 1:
self.balloon_list.append(BalloonAnimation(game_screen.current_ms, current_note['balloon']))
self.curr_balloon_count += 1
self.total_drumroll += 1
self.score += 100
self.base_score_list.append(ScoreCounterAnimation(game_screen.current_ms, 100))
self.current_notes_draw[0]['popped'] = False
@@ -367,8 +398,6 @@ class Player:
self.current_notes_draw[0]['popped'] = True
audio.play_sound(game_screen.sound_balloon_pop)
self.note_correct(game_screen, self.current_notes[0])
if len(self.current_notes) > 1 and self.current_notes[0]['note'] == '8':
self.note_correct(game_screen, self.current_notes[0])
def check_note(self, game_screen: GameScreen, drum_type: str):
if self.is_drumroll:
@@ -421,17 +450,14 @@ class Player:
self.current_notes.popleft()
def drumroll_counter_manager(self, game_screen: GameScreen):
if self.is_drumroll and self.curr_drumroll_count > 0:
if len(self.drumroll_counter) == 0 or self.drumroll_counter[-1].is_finished:
self.drumroll_counter.append(DrumrollCounter(game_screen.current_ms))
if self.is_drumroll and self.curr_drumroll_count > 0 and self.drumroll_counter is None:
self.drumroll_counter = DrumrollCounter(game_screen.current_ms)
if len(self.drumroll_counter) <= 0:
return
if self.drumroll_counter[0].is_finished and not self.is_drumroll:
self.drumroll_counter.pop(0)
else:
self.drumroll_counter[0].update(game_screen, game_screen.current_ms, self.curr_drumroll_count)
if self.drumroll_counter is not None:
if self.drumroll_counter.is_finished and not self.is_drumroll:
self.drumroll_counter = None
else:
self.drumroll_counter.update(game_screen, game_screen.current_ms, self.curr_drumroll_count)
def balloon_animation_manager(self, game_screen: GameScreen):
if len(self.balloon_list) <= 0:
@@ -489,7 +515,6 @@ class Player:
self.animation_manager(game_screen, self.draw_drum_hit_list)
self.animation_manager(game_screen, self.draw_arc_list)
self.animation_manager(game_screen, self.base_score_list)
self.song_info.update(game_screen.current_ms)
self.score_counter.update(game_screen.current_ms, self.score)
self.key_manager(game_screen)
@@ -499,10 +524,9 @@ class Player:
def draw_drumroll(self, game_screen: GameScreen, big: bool, position: int, index: int, color: int):
drumroll_start_position = position
i = 1
while self.current_notes_draw[index+i]['note'] != '8':
i += 1
tail = self.current_notes_draw[index+i]
tail = next((note for note in self.current_notes_draw[index+1:] if note['note'] == '8'), None)
if tail is None:
return
if big:
drumroll_body = 'dai_drumroll_body'
drumroll_tail = 'dai_drumroll_tail'
@@ -515,17 +539,16 @@ class Player:
self.draw_note(game_screen, drumroll_tail, drumroll_end_position, color, 10, drumroll_length=None)
def draw_balloon(self, game_screen: GameScreen, note: dict, position: int, index: int):
if self.current_notes_draw[0].get('popped', None):
tail = next((note for note in self.current_notes_draw[index+1:] if note['note'] == '8'), None)
if tail is None:
return
i = 1
while self.current_notes_draw[index+i]['note'] != '8':
i += 1
end_time = self.current_notes_draw[index+i]
end_time_position = self.get_position(game_screen, end_time['load_ms'], end_time['ppf'])
if game_screen.current_ms >= end_time['ms']:
position = end_time_position
tail_position = self.get_position(game_screen, tail['load_ms'], tail['ppf'])
if game_screen.current_ms >= tail['ms']:
position = tail_position
elif game_screen.current_ms >= note['ms']:
position = 349
if note.get('popped', None):
return
self.draw_note(game_screen, '7', position, 255, 9)
def draw_note(self, game_screen: GameScreen, note: str, position: int, color: int, se_note: int | None, drumroll_length: int | None=None):
@@ -587,8 +610,6 @@ class Player:
note = self.current_notes_draw[i]
note_type, load_ms, pixels_per_frame = note['note'], note['load_ms'], note['ppf']
position = self.get_position(game_screen, load_ms, pixels_per_frame)
if 'popped' in note:
continue
if note_type == '5':
self.draw_drumroll(game_screen, False, position, i, note['color'])
elif note_type == '6':
@@ -597,7 +618,7 @@ class Player:
self.draw_balloon(game_screen, note, position, i)
else:
self.draw_note(game_screen, note_type, position, 255, note['se_note'])
#ray.draw_text(str(i), position+64, 192, 25, ray.GREEN)
ray.draw_text(str(i), position+64, 192, 25, ray.GREEN)
def draw_gauge(self, game_screen: GameScreen):
ray.draw_texture(game_screen.textures['gage_don_1p_hard'][0], 327, 128, ray.WHITE)
@@ -621,8 +642,8 @@ class Player:
ray.draw_texture(game_screen.textures['lane_obi'][3], 0, 184, ray.WHITE)
ray.draw_texture(game_screen.textures['lane_obi'][19], 0, 225, ray.WHITE)
ray.draw_texture(game_screen.texture_difficulty[self.difficulty], 50, 222, ray.WHITE)
self.song_info.draw(game_screen)
self.draw_animation_list(game_screen, self.drumroll_counter)
if self.drumroll_counter is not None:
self.drumroll_counter.draw(game_screen)
self.draw_animation_list(game_screen, self.draw_arc_list)
self.draw_animation_list(game_screen, self.balloon_list)
self.score_counter.draw(game_screen)
@@ -787,6 +808,7 @@ class DrumrollCounter:
def update_count(self, current_ms: float, count: int, elapsed_time: float):
self.total_duration = elapsed_time + 1349
self.fade_animation.params['delay'] = self.total_duration - 166
if self.drumroll_count != count:
self.drumroll_count = count
self.stretch_animation = Animation(current_ms, 50, 'text_stretch')
@@ -1028,40 +1050,93 @@ class ScoreCounterAnimation:
ray.draw_texture_pro(game_screen.textures['score_add_1p'][int(counter[i])], source_rect, dest_rect, ray.Vector2(0,0), 0, self.color)
class SongInfo:
FADE_DURATION = 366
DISPLAY_DURATION = 1666
def __init__(self, current_ms: float, song_name: str, genre: str):
self.fade_in = Animation(current_ms, 366, 'fade')
self.fade_in.params['initial_opacity'] = 0.0
self.fade_in.params['final_opacity'] = 1.0
self.fade_in = self._create_fade_in_animation(current_ms)
self.fade_out = self._create_fade_out_animation(current_ms)
self.fade_out = Animation(current_ms, 366, 'fade')
self.fade_out.params['initial_opacity'] = 1.0
self.fade_out.params['final_opacity'] = 0.0
self.fade_out.params['delay'] = 1666 + self.fade_in.duration
self.song_name = song_name
self.genre = genre
self.is_finished = False
self.song_num_fade = ray.WHITE
self.song_name_fade = ray.WHITE
self.font = self._load_font_for_text(song_name)
self.song_title = OutlinedText(
self.font, song_name, 40, ray.WHITE, ray.BLACK, outline_thickness=5
)
def _create_fade_in_animation(self, start_ms: float) -> Animation:
fade_in = Animation(start_ms, self.FADE_DURATION, 'fade')
fade_in.params['initial_opacity'] = 0.0
fade_in.params['final_opacity'] = 1.0
return fade_in
def _create_fade_out_animation(self, start_ms: float) -> Animation:
fade_out = Animation(start_ms, self.FADE_DURATION, 'fade')
fade_out.params['initial_opacity'] = 1.0
fade_out.params['final_opacity'] = 0.0
fade_out.params['delay'] = self.DISPLAY_DURATION + self.FADE_DURATION
return fade_out
def _load_font_for_text(self, text: str) -> ray.Font:
codepoint_count = ray.ffi.new('int *', 0)
codepoints_no_dup = set()
codepoints_no_dup.update(song_name)
codepoints = ray.load_codepoints(''.join(codepoints_no_dup), codepoint_count)
self.font = ray.load_font_ex('Graphics\\Modified-DFPKanteiryu-XB.ttf', 32, codepoints, 0)
self.song_title = OutlinedText(self.font, song_name, 40, ray.WHITE, ray.BLACK, outline_thickness=5)
unique_codepoints = set(text)
codepoints = ray.load_codepoints(''.join(unique_codepoints), codepoint_count)
return ray.load_font_ex('Graphics\\Modified-DFPKanteiryu-XB.ttf', 32, codepoints, 0)
def update(self, current_ms: float):
self.fade_in.update(current_ms)
self.fade_out.update(current_ms)
self.song_num_fade = ray.fade(ray.WHITE, self.fade_in.attribute)
self.song_name_fade = ray.fade(ray.WHITE, 1 - self.fade_in.attribute)
if self.fade_in.is_finished:
if not self.fade_in.is_finished:
self.song_num_fade = ray.fade(ray.WHITE, self.fade_in.attribute)
self.song_name_fade = ray.fade(ray.WHITE, 1 - self.fade_in.attribute)
else:
self.song_num_fade = ray.fade(ray.WHITE, self.fade_out.attribute)
self.song_name_fade = ray.fade(ray.WHITE, 1 - self.fade_out.attribute)
if self.fade_out.is_finished:
self.fade_in.start_ms = current_ms + 1666
self.fade_out.start_ms = current_ms + 1666
self.fade_in.is_finished = False
self.fade_out.is_finished = False
self._reset_animations(current_ms)
def _reset_animations(self, current_ms: float):
next_cycle_start = current_ms + self.DISPLAY_DURATION
self.fade_in = self._create_fade_in_animation(next_cycle_start)
self.fade_out = self._create_fade_out_animation(next_cycle_start)
def draw(self, game_screen: GameScreen):
ray.draw_texture(game_screen.textures['song_info'][(global_data.songs_played % 4) + 8], 1132, 25, self.song_num_fade)
self.song_title.draw(1252 - self.song_title.texture.width, int(50 - self.song_title.texture.height / 2), self.song_name_fade)
song_texture_index = (global_data.songs_played % 4) + 8
ray.draw_texture(
game_screen.textures['song_info'][song_texture_index],
1132, 25,
self.song_num_fade
)
text_x = 1252 - self.song_title.texture.width
text_y = int(50 - self.song_title.texture.height / 2)
self.song_title.draw(text_x, text_y, self.song_name_fade)
class ResultTransition:
def __init__(self, current_ms: float, screen_height: int):
self.move = Animation(current_ms, 983.33, 'move')
self.move.params['start_position'] = 0.0
self.move.params['total_distance'] = screen_height//2
self.is_finished = False
def update(self, current_ms: float):
self.move.update(current_ms)
if self.move.is_finished:
self.is_finished = True
def draw(self, screen_width: int, screen_height: int, texture_1: ray.Texture, texture_2: ray.Texture):
x = 0
while x < screen_width:
ray.draw_texture(texture_1, x, (0 - texture_1.height) + int(self.move.attribute), ray.WHITE)
ray.draw_texture(texture_1, x, (screen_height) - int(self.move.attribute), ray.WHITE)
x += texture_1.width
x = 0
while x < screen_width:
ray.draw_texture(texture_2, x, (0 - texture_2.height) + int(self.move.attribute / ((screen_height//2) / (texture_2.height//2))), ray.WHITE)
ray.draw_texture(texture_2, x, (screen_height) - int(self.move.attribute / ((screen_height//2) / (texture_2.height//2))), ray.WHITE)
x += texture_2.width

View File

@@ -1,11 +1,12 @@
import pyray as ray
from libs.animation import Animation
from libs.audio import audio
from libs.utils import (
OutlinedText,
get_current_ms,
global_data,
load_all_textures_from_zip,
load_image_from_zip,
)
@@ -17,31 +18,61 @@ def draw_scaled_texture(texture, x: int, y: int, scale: float, color: ray.Color)
ray.draw_texture_pro(texture, src_rect, dst_rect, ray.Vector2(0, 0), 0, color)
class ResultScreen:
def __init__(self, width, height):
def __init__(self, width: int, height: int):
self.width = width
self.height = height
self.sound_don = audio.load_sound('Sounds\\inst_00_don.wav')
self.bgm = audio.load_sound('Sounds\\result\\JINGLE_SEISEKI [1].ogg')
zip_file = 'Graphics\\lumendata\\enso_result.zip'
self.textures = load_all_textures_from_zip(zip_file)
ray.unload_texture(self.textures['result'][327])
image = load_image_from_zip(zip_file, 'result_img00327.png')
ray.image_resize(image, 1280, 144)
self.textures['result'][327] = ray.load_texture_from_image(image)
self.text_generated = False
self.song_info = FontText(global_data.song_title, 40).texture
self.screen_init = False
self.fade_in = None
self.bgm_volume = 1.0
def on_screen_start(self):
if not self.screen_init:
self.textures = load_all_textures_from_zip('Graphics\\lumendata\\enso_result.zip')
self.screen_init = True
self.song_info = FontText(global_data.song_title, 40).texture
self.bgm_volume = 1.0
audio.play_sound(self.bgm)
self.fade_in = FadeIn(get_current_ms())
def on_screen_end(self):
self.screen_init = False
global_data.songs_played += 1
audio.play_sound(self.sound_don)
for zip in self.textures:
for texture in self.textures[zip]:
ray.unload_texture(texture)
audio.stop_sound(self.bgm)
return "SONG_SELECT"
def update(self):
self.on_screen_start()
if ray.is_key_pressed(ray.KeyboardKey.KEY_ENTER):
global_data.songs_played += 1
audio.play_sound(self.sound_don)
return "SONG_SELECT"
return self.on_screen_end()
if not self.text_generated and global_data.song_title != '':
self.song_info = FontText(global_data.song_title, 40).texture
self.text_generated = True
if self.fade_in is not None:
self.fade_in.update(get_current_ms())
def draw_score_info(self):
for i in range(len(str(global_data.result_good))):
ray.draw_texture(self.textures['result'][int(str(global_data.result_good)[::-1][i]) + 136], 943-(i*24), 186, ray.WHITE)
for i in range(len(str(global_data.result_ok))):
ray.draw_texture(self.textures['result'][int(str(global_data.result_ok)[::-1][i]) + 136], 943-(i*24), 227, ray.WHITE)
for i in range(len(str(global_data.result_bad))):
ray.draw_texture(self.textures['result'][int(str(global_data.result_bad)[::-1][i]) + 136], 943-(i*24), 267, ray.WHITE)
def draw_total_score(self):
ray.draw_texture(self.textures['result'][167], 554, 236, ray.WHITE)
for i in range(len(str(global_data.result_score))):
ray.draw_texture(self.textures['result'][int(str(global_data.result_score)[::-1][i]) + 156], 723-(i*21), 252, ray.WHITE)
def draw(self):
x = 0
@@ -49,15 +80,11 @@ class ResultScreen:
ray.draw_texture(self.textures['result'][326], x, 0 - self.textures['result'][326].height//2, ray.WHITE)
ray.draw_texture(self.textures['result'][326], x, self.height - self.textures['result'][326].height//2, ray.WHITE)
x += self.textures['result'][326].width
ray.draw_texture(self.textures['result'][327], 0, 0 - self.textures['result'][327].height//2, ray.WHITE)
ray.draw_texture(self.textures['result'][327], 0, self.height - self.textures['result'][327].height + self.textures['result'][327].height//2, ray.WHITE)
ray.draw_text(f"{global_data.selected_song}", 100, 60, 20, ray.BLACK)
ray.draw_text(f"SCORE: {global_data.result_score}", 100, 80, 20, ray.BLACK)
ray.draw_text(f"GOOD: {global_data.result_good}", 100, 100, 20, ray.BLACK)
ray.draw_text(f"OK: {global_data.result_ok}", 100, 120, 20, ray.BLACK)
ray.draw_text(f"BAD: {global_data.result_bad}", 100, 140, 20, ray.BLACK)
x = 0
while x < self.width:
ray.draw_texture(self.textures['result'][327], x, 0 - self.textures['result'][327].height//2, ray.WHITE)
ray.draw_texture(self.textures['result'][327], x, self.height - self.textures['result'][327].height + self.textures['result'][327].height//2, ray.WHITE)
x += self.textures['result'][327].width
ray.draw_texture(self.textures['result'][330], -5, 3, ray.WHITE)
ray.draw_texture(self.textures['result'][(global_data.songs_played % 4) + 331], 232, 4, ray.WHITE)
@@ -71,6 +98,43 @@ class ResultScreen:
draw_scaled_texture(self.textures['result'][187], 1058, 124, (10/11), ray.WHITE)
draw_scaled_texture(self.textures['result'][188], 1182, 115, (10/11), ray.WHITE)
ray.draw_texture(self.textures['result'][170], 817, 186, ray.WHITE)
ray.draw_texture(self.textures['result'][171], 817, 227, ray.WHITE)
ray.draw_texture(self.textures['result'][172], 817, 267, ray.WHITE)
ray.draw_texture(self.textures['result'][173], 987, 186, ray.WHITE)
ray.draw_texture(self.textures['result'][174], 981, 227, ray.WHITE)
self.draw_score_info()
self.draw_total_score()
if self.fade_in is not None:
self.fade_in.draw(self.width, self.height, self.textures['result'][326], self.textures['result'][327])
class FadeIn:
def __init__(self, current_ms: float):
self.fadein = Animation(current_ms, 450, 'fade')
self.fadein.params['initial_opacity'] = 1.0
self.fadein.params['final_opacity'] = 0.0
self.fadein.params['delay'] = 100
self.fade = ray.fade(ray.WHITE, self.fadein.attribute)
def update(self, current_ms: float):
self.fadein.update(current_ms)
self.fade = ray.fade(ray.WHITE, self.fadein.attribute)
def draw(self, screen_width: int, screen_height: int, texture_1: ray.Texture, texture_2: ray.Texture):
x = 0
while x < screen_width:
ray.draw_texture(texture_1, x, 0 - texture_1.height//2, self.fade)
ray.draw_texture(texture_1, x, screen_height - texture_1.height//2, self.fade)
x += texture_1.width
x = 0
while x < screen_width:
ray.draw_texture(texture_2, x, 0 - texture_2.height//2, self.fade)
ray.draw_texture(texture_2, x, screen_height - texture_2.height + texture_2.height//2, self.fade)
x += texture_2.width
class FontText:
def __init__(self, text, font_size):
codepoint_count = ray.ffi.new('int *', 0)

View File

@@ -3,6 +3,7 @@ import os
import pyray as ray
from libs.audio import audio
from libs.tja import TJAParser
from libs.utils import get_config, global_data
@@ -12,7 +13,7 @@ class SongSelectScreen:
self.height = height
self.is_song_select = True
self.is_difficulty_select = False
self.song_list: list[str] = []
self.song_list: dict[str, list] = dict()
self.selected_song = 0
self.selected_difficulty = 0
self.selected_index = 0
@@ -21,7 +22,23 @@ class SongSelectScreen:
for dirpath, dirnames, filenames in os.walk(f'{get_config()["paths"]["tja_path"]}'):
for filename in filenames:
if filename.endswith(".tja"):
self.song_list.append(dirpath)
self.song_list[dirpath] = TJAParser(dirpath).get_metadata()
self.screen_init = False
def on_screen_start(self):
if not self.screen_init:
self.screen_init = True
self.is_song_select = True
self.is_difficulty_select = False
def on_screen_end(self):
self.screen_init = False
audio.play_sound(self.sound_don)
global_data.selected_song = list(self.song_list.keys())[self.selected_song]
global_data.selected_difficulty = self.selected_difficulty
return "GAME"
def update_song_select(self):
if ray.is_key_pressed(ray.KeyboardKey.KEY_ENTER):
@@ -37,13 +54,7 @@ class SongSelectScreen:
def update_difficulty_select(self):
if ray.is_key_pressed(ray.KeyboardKey.KEY_ENTER):
audio.play_sound(self.sound_don)
global_data.selected_song = self.song_list[self.selected_song]
global_data.selected_difficulty = self.selected_difficulty
global_data.start_song = True
self.is_song_select = True
self.is_difficulty_select = False
return "GAME"
return self.on_screen_end()
elif ray.is_key_pressed(ray.KeyboardKey.KEY_BACKSPACE):
self.is_song_select = True
self.is_difficulty_select = False
@@ -55,6 +66,7 @@ class SongSelectScreen:
self.selected_difficulty = (self.selected_difficulty + 1) % 5
def update(self):
self.on_screen_start()
if self.is_song_select:
self.update_song_select()
elif self.is_difficulty_select:
@@ -62,21 +74,23 @@ class SongSelectScreen:
def draw_song_select(self):
visible_songs = 36
total_songs = len(self.song_list)
song_paths = list(self.song_list.keys()) # Get all paths as a list
total_songs = len(song_paths)
start_index = max(0, self.selected_song - visible_songs // 2)
if start_index + visible_songs > total_songs:
start_index = max(0, total_songs - visible_songs)
for i in range(visible_songs):
song_index = (start_index + i) % total_songs
if start_index + i < total_songs: # Ensure we don't go out of bounds
song_index = start_index + i
current_path = song_paths[song_index]
# Get display text from metadata, or use the path as fallback
display_text = self.song_list[current_path][0]
if song_index == self.selected_song:
color = ray.GREEN
else:
color = ray.BLACK
ray.draw_text(self.song_list[song_index], 20, (20*i), 20, color)
if song_index == self.selected_song:
color = ray.GREEN
else:
color = ray.BLACK
ray.draw_text(display_text, 20, (20*i), 20, color)
def draw_difficulty_select(self):
difficulties = ["Easy", "Normal", "Hard", "Oni", "Ura"]

View File

@@ -28,6 +28,8 @@ class TitleScreen:
self.load_textures()
self.warning_board = WarningScreen(get_current_ms(), self)
self.screen_init = False
def get_videos(self):
return self.op_video, self.attract_video
@@ -41,6 +43,17 @@ class TitleScreen:
self.texture_black = load_texture_from_zip('Graphics\\lumendata\\attract\\movie.zip', 'movie_img00000.png')
def on_screen_start(self):
if not self.screen_init:
self.screen_init = True
def on_screen_end(self) -> str:
for zip in self.textures:
for texture in self.textures[zip]:
ray.unload_texture(texture)
self.screen_init = False
return "ENTRY"
def scene_manager(self):
if self.scene == 'Opening Video':
self.op_video.update()
@@ -59,9 +72,11 @@ class TitleScreen:
self.op_video = VideoPlayer(random.choice(self.op_video_list))
def update(self):
self.on_screen_start()
self.scene_manager()
if ray.is_key_pressed(ray.KeyboardKey.KEY_ENTER):
return "ENTRY"
return self.on_screen_end()
def draw(self):
if self.scene == 'Opening Video':