diff --git a/PyTaiko.py b/PyTaiko.py index 9a89621..73fd5cc 100644 --- a/PyTaiko.py +++ b/PyTaiko.py @@ -1,9 +1,10 @@ import sqlite3 +from pathlib import Path import pyray as ray from libs.audio import audio -from libs.utils import get_config +from libs.utils import get_config, global_data, load_all_textures_from_zip from scenes.entry import EntryScreen from scenes.game import GameScreen from scenes.result import ResultScreen @@ -89,6 +90,7 @@ def main(): #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(0x302, 0x303, 1, 0x303, 0x8006, 0x8006) ray.set_exit_key(ray.KeyboardKey.KEY_A) + global_data.textures = load_all_textures_from_zip(Path('Graphics/lumendata/intermission.zip')) while not ray.window_should_close(): ray.begin_texture_mode(target) @@ -100,10 +102,7 @@ def main(): next_screen = screen.update() screen.draw() - if screen == title_screen: - ray.clear_background(ray.BLACK) - else: - ray.clear_background(ray.WHITE) + ray.clear_background(ray.BLACK) if next_screen is not None: current_screen = next_screen diff --git a/libs/tja.py b/libs/tja.py index e6dc77b..cc2fb3e 100644 --- a/libs/tja.py +++ b/libs/tja.py @@ -67,6 +67,11 @@ class TJAParser: #Defined on file_to_data() self.data = [] + with open(self.file_path, 'rt', encoding='utf-8-sig') as tja_file: + for line in tja_file: + line = strip_comments(line).strip() + if line != '': + self.data.append(str(line)) #Defined on get_metadata() self.title = '' @@ -88,16 +93,7 @@ class TJAParser: self.barline_display = True self.gogo_time = False - def _file_to_data(self): - with open(self.file_path, 'rt', encoding='utf-8-sig') as tja_file: - for line in tja_file: - line = strip_comments(line).strip() - if line != '': - self.data.append(str(line)) - return self.data - def get_metadata(self): - self._file_to_data() current_diff = None # Track which difficulty we're currently processing for item in self.data: @@ -173,7 +169,6 @@ class TJAParser: self.bpm, self.wave, self.offset, self.demo_start, self.course_data] def data_to_notes(self, diff): - self._file_to_data() note_start = -1 note_end = -1 target_found = False @@ -393,8 +388,6 @@ class TJAParser: # Bars can be sorted like this because they don't need hit detection draw_note_list = deque(sorted(play_note_list, key=lambda n: n.load_ms)) bar_list = deque(sorted(bar_list, key=lambda b: b.load_ms)) - for note in play_note_list: - print(note) return play_note_list, draw_note_list, bar_list def hash_note_data(self, notes: list): diff --git a/libs/utils.py b/libs/utils.py index 79e1ab4..28b9034 100644 --- a/libs/utils.py +++ b/libs/utils.py @@ -120,6 +120,7 @@ def reset_session(): @dataclass class GlobalData: + textures: dict[str, list[ray.Texture]] = field(default_factory=lambda: dict()) songs_played: int = 0 global_data = GlobalData() diff --git a/scenes/game.py b/scenes/game.py index 5e4a458..1a63bd1 100644 --- a/scenes/game.py +++ b/scenes/game.py @@ -80,10 +80,6 @@ class GameScreen: self.textures.update(load_all_textures_from_zip(Path('Graphics/lumendata/enso_system/base1p.zip'))) self.textures.update(load_all_textures_from_zip(Path('Graphics/lumendata/enso_system/don1p.zip'))) - - self.result_transition_1 = load_texture_from_zip(Path('Graphics/lumendata/enso_result.zip'), 'retry_game_img00125.png') - self.result_transition_2 = load_texture_from_zip(Path('Graphics/lumendata/enso_result.zip'), 'retry_game_img00126.png') - def load_sounds(self): sounds_dir = Path("Sounds") self.sound_don = audio.load_sound(str(sounds_dir / "inst_00_don.wav")) @@ -202,7 +198,7 @@ class GameScreen: 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) + self.result_transition.draw(self.width, self.height, global_data.textures['shutter'][0], global_data.textures['shutter'][1]) class Player: TIMING_GOOD = 25.0250015258789 @@ -1124,7 +1120,7 @@ class SongInfo: codepoint_count = ray.ffi.new('int *', 0) unique_codepoints = set(text) codepoints = ray.load_codepoints(''.join(unique_codepoints), codepoint_count) - return ray.load_font_ex(str(Path('Graphics/Modified-DFPKanteiryu-XB.ttf')), 32, codepoints, 0) + return ray.load_font_ex(str(Path('Graphics/Modified-DFPKanteiryu-XB.ttf')), 40, codepoints, 0) def update(self, current_ms: float): self.fade_in.update(current_ms) diff --git a/scenes/result.py b/scenes/result.py index 63b0a4c..6d97fef 100644 --- a/scenes/result.py +++ b/scenes/result.py @@ -21,6 +21,7 @@ class ResultScreen: self.width = width self.height = height self.screen_init = False + self.fade_out = None def load_textures(self): zip_file = Path('Graphics/lumendata/enso_result.zip') @@ -41,6 +42,7 @@ class ResultScreen: self.song_info = FontText(session_data.song_title, 40).texture audio.play_sound(self.bgm) self.fade_in = FadeIn(get_current_ms()) + self.fade_out = None self.gauge = None self.score_delay = None self.score_animator = ScoreAnimator(session_data.result_score) @@ -62,7 +64,6 @@ class ResultScreen: 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) @@ -113,11 +114,16 @@ class ResultScreen: if ray.is_key_pressed(ord(don)): if not self.is_skipped: self.is_skipped = True - audio.play_sound(self.sound_don) else: - return self.on_screen_end() + if self.fade_out is None: + self.fade_out = FadeOut() + audio.play_sound(self.sound_don) self.update_score_animation(self.is_skipped) + if self.fade_out is not None: + self.fade_out.update(get_current_ms()) + if self.fade_out.is_finished: + return self.on_screen_end() def draw_score_info(self): if self.good > -1: @@ -175,6 +181,9 @@ class ResultScreen: if self.fade_in is not None: self.fade_in.draw(self.width, self.height, self.textures['result'][326], self.textures['result'][327]) + if self.fade_out is not None: + self.fade_out.draw(self.width, self.height) + class FadeIn: def __init__(self, current_ms: float): @@ -206,7 +215,7 @@ class FontText: codepoints_no_dup = set() codepoints_no_dup.update(session_data.song_title) codepoints = ray.load_codepoints(''.join(codepoints_no_dup), codepoint_count) - self.font = ray.load_font_ex(str(Path('Graphics/Modified-DFPKanteiryu-XB.ttf')), 32, codepoints, 0) + self.font = ray.load_font_ex(str(Path('Graphics/Modified-DFPKanteiryu-XB.ttf')), 40, codepoints, 0) self.text = OutlinedText(self.font, str(text), font_size, ray.WHITE, ray.BLACK, outline_thickness=4) self.texture = self.text.texture @@ -287,3 +296,17 @@ class Gauge: else: draw_scaled_texture(textures[187], 1058, 124, (10/11), color) draw_scaled_texture(textures[188], 1182, 115, (10/11), color) + +class FadeOut: + def __init__(self) -> None: + self.texture = global_data.textures['scene_change_fade'][0] + self.fade_out = Animation.create_fade(1000, initial_opacity=0.0, final_opacity=1.0) + self.is_finished = False + def update(self, current_time_ms: float): + self.fade_out.update(current_time_ms) + print(self.fade_out.attribute) + self.is_finished = self.fade_out.is_finished + def draw(self, screen_width: int, screen_height: int): + src = ray.Rectangle(0, 0, self.texture.width, self.texture.height) + dst = ray.Rectangle(0, 0, screen_width, screen_height) + ray.draw_texture_pro(self.texture, src, dst, ray.Vector2(0,0), 0, ray.fade(ray.WHITE, self.fade_out.attribute)) diff --git a/scenes/song_select.py b/scenes/song_select.py index ebec3da..47e2650 100644 --- a/scenes/song_select.py +++ b/scenes/song_select.py @@ -1,5 +1,6 @@ import os from pathlib import Path +import sqlite3 import pyray as ray @@ -10,6 +11,7 @@ from libs.utils import ( OutlinedText, get_config, get_current_ms, + global_data, load_all_textures_from_zip, session_data, ) @@ -23,15 +25,22 @@ class SongSelectScreen: self.song_name_textures: list[OutlinedText] = [] self.selected_song = 0 self.selected_difficulty = 0 - self.selected_index = 0 + + self.song_boxes: list[SongBox] = [] + self.yellow_box = YellowBox() self.screen_init = False + self.box_wait = 0 + self.move = Animation.create_move(0) + + self.game_transition = None + def _load_font_for_text(self, text: str) -> ray.Font: codepoint_count = ray.ffi.new('int *', 0) unique_codepoints = set(text) codepoints = ray.load_codepoints(''.join(unique_codepoints), codepoint_count) - return ray.load_font_ex(str(Path('Graphics/Modified-DFPKanteiryu-XB.ttf')), 32, codepoints, 0) + return ray.load_font_ex(str(Path('Graphics/Modified-DFPKanteiryu-XB.ttf')), 40, codepoints, 0) def load_textures(self): self.textures = load_all_textures_from_zip(Path('Graphics/lumendata/song_select.zip')) @@ -41,20 +50,32 @@ class SongSelectScreen: self.sound_don = audio.load_sound(str(sounds_dir / "inst_00_don.wav")) self.sound_kat = audio.load_sound(str(sounds_dir / "inst_00_katsu.wav")) + def get_scores(self, tja: TJAParser, difficulty: int): + with sqlite3.connect('scores.db') as con: + cursor = con.cursor() + hash = tja.hash_note_data(tja.data_to_notes(difficulty)[0]) + check_query = "SELECT score, good, ok, bad FROM Scores WHERE hash = ? LIMIT 1" + cursor.execute(check_query, (hash,)) + result = cursor.fetchone() + return result + def on_screen_start(self): if not self.screen_init: self.load_textures() self.load_sounds() + self.game_transition = None for dirpath, dirnames, filenames in os.walk(f'{get_config()["paths"]["tja_path"]}'): for filename in filenames: if filename.endswith(".tja"): - self.song_list[dirpath] = TJAParser(dirpath).get_metadata() - name = self.song_list[dirpath][1] - if name == '': - name = self.song_list[dirpath][0] - if len(self.song_name_textures) < 17: - font = self._load_font_for_text(name) - self.song_name_textures.append(OutlinedText(font, name, 40, ray.WHITE, ray.BLACK, outline_thickness=4, vertical=True)) + tja = TJAParser(dirpath) + scores = dict() + self.song_list[dirpath] = tja.get_metadata() + for diff in self.song_list[dirpath][8].keys(): + scores[diff] = self.get_scores(tja, diff) + name = self.song_list[dirpath][0] + font = self._load_font_for_text(name) + text = OutlinedText(font, name, 40, ray.WHITE, ray.BLACK, outline_thickness=4, vertical=True) + self.song_boxes.append(SongBox(text, dirpath, scores)) self.screen_init = True self.is_song_select = True self.is_difficulty_select = False @@ -62,8 +83,7 @@ class SongSelectScreen: def on_screen_end(self): self.screen_init = False - audio.play_sound(self.sound_don) - session_data.selected_song = list(self.song_list.keys())[self.selected_song] + session_data.selected_song = self.song_boxes[5].dirpath session_data.selected_difficulty = self.selected_difficulty for zip in self.textures: for texture in self.textures[zip]: @@ -75,87 +95,241 @@ class SongSelectScreen: audio.play_sound(self.sound_don) self.is_song_select = False self.is_difficulty_select = True - elif ray.is_key_pressed(ray.KeyboardKey.KEY_UP): + elif ray.is_key_pressed(ray.KeyboardKey.KEY_LEFT): audio.play_sound(self.sound_kat) - self.selected_song -= 1 - elif ray.is_key_pressed(ray.KeyboardKey.KEY_DOWN): + self.song_boxes.insert(0, self.song_boxes.pop()) + self.move = Animation.create_move(66.68, start_position=0, total_distance=100) + self.box_wait = get_current_ms() + elif ray.is_key_pressed(ray.KeyboardKey.KEY_RIGHT): audio.play_sound(self.sound_kat) - self.selected_song += 1 + self.song_boxes.append(self.song_boxes.pop(0)) + self.move = Animation.create_move(66.68, start_position=0, total_distance=-100) + self.box_wait = get_current_ms() def update_difficulty_select(self): if ray.is_key_pressed(ray.KeyboardKey.KEY_ENTER): - return self.on_screen_end() - elif ray.is_key_pressed(ray.KeyboardKey.KEY_BACKSPACE): - self.is_song_select = True - self.is_difficulty_select = False - elif ray.is_key_pressed(ray.KeyboardKey.KEY_UP): + if self.selected_difficulty == -1: + self.is_song_select = True + self.is_difficulty_select = False + else: + audio.play_sound(self.sound_don) + self.game_transition = Transition(self.height) + elif ray.is_key_pressed(ray.KeyboardKey.KEY_LEFT): audio.play_sound(self.sound_kat) - self.selected_difficulty = (self.selected_difficulty - 1) % 5 - elif ray.is_key_pressed(ray.KeyboardKey.KEY_DOWN): + if self.selected_difficulty >= 0: + self.selected_difficulty = (self.selected_difficulty - 1) + elif ray.is_key_pressed(ray.KeyboardKey.KEY_RIGHT): audio.play_sound(self.sound_kat) - self.selected_difficulty = (self.selected_difficulty + 1) % 5 + if self.selected_difficulty < 4: + self.selected_difficulty = (self.selected_difficulty + 1) def update(self): self.on_screen_start() self.background_move.update(get_current_ms()) + if self.game_transition is not None: + self.game_transition.update(get_current_ms()) + if self.game_transition.is_finished: + return self.on_screen_end() if self.background_move.is_finished: self.background_move = Animation.create_move(15000, start_position=0, total_distance=1280) if self.is_song_select: self.update_song_select() + self.yellow_box.update(self.song_boxes[5].name, False) elif self.is_difficulty_select: - return self.update_difficulty_select() - - def draw_box(self, x: int, y: int, texture_index: int): - ray.draw_texture(self.textures['song_select'][texture_index+1], x, y, ray.WHITE) - for i in range(0, self.textures['song_select'][texture_index].width * 4, self.textures['song_select'][texture_index].width): - ray.draw_texture(self.textures['song_select'][texture_index], (x+32)+i, y, ray.WHITE) - ray.draw_texture(self.textures['song_select'][texture_index+2], x+64, y, ray.WHITE) - ray.draw_texture(self.textures['song_select'][texture_index+3], x+12, y+16, ray.WHITE) + self.yellow_box.update(self.song_boxes[5].name, True) + self.update_difficulty_select() + if self.move is not None: + self.move.update(get_current_ms()) def draw_song_select(self): + offset = 0 + for i in range(-1, 17): + box = self.song_boxes[i+1] + if i == 4 and self.move.is_finished and get_current_ms() >= self.box_wait + 133.36: + self.yellow_box.draw(self.textures, self.song_list, self.song_boxes) + offset = 300 + else: + move = 0 + if self.move is not None: + move = int(self.move.attribute) - self.move.total_distance + box.draw(44 + (i*100) + offset + move, 95, 620, self.textures) + + def draw_selector(self): + if self.selected_difficulty == -1: + ray.draw_texture(self.textures['song_select'][133], 314, 110, ray.WHITE) + else: + ray.draw_texture(self.textures['song_select'][140], 450 + (self.selected_difficulty * 115), 7, ray.WHITE) + ray.draw_texture(self.textures['song_select'][131], 461 + (self.selected_difficulty * 115), 132, ray.WHITE) + + def draw_difficulty_select(self): + self.yellow_box.draw(self.textures, self.song_list, self.song_boxes) + self.draw_selector() + + def draw(self): texture = self.textures['song_select'][784] for i in range(0, texture.width * 4, texture.width): ray.draw_texture(self.textures['song_select'][784], i - int(self.background_move.attribute), 0, ray.WHITE) - ray.draw_texture(self.textures['song_select'][244], 5, 5, ray.WHITE) - ray.draw_texture(self.textures['song_select'][394], 0, self.height - self.textures['song_select'][394].height, ray.WHITE) - - for i in range(-1, 15): - self.draw_box(44 + (i*100), 95, 620) - texture = self.song_name_textures[i+1] - src = ray.Rectangle(0, 0, texture.texture.width, texture.texture.height) - dest = ray.Rectangle((91 + (i*100)) - texture.texture.width / 2, 130, texture.texture.width, min(texture.texture.height, 417)) - texture.draw(src, dest, ray.Vector2(0, 0), 0, ray.WHITE) - - visible_songs = 36 - 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): - 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(display_text, 20, (20*i), 20, color) - - def draw_difficulty_select(self): - difficulties = ["Easy", "Normal", "Hard", "Oni", "Ura"] - for i in range(len(difficulties)): - if i == self.selected_difficulty: - color = ray.GREEN - else: - color = ray.BLACK - ray.draw_text(difficulties[i], 20, (20*i), 20, color) - - def draw(self): if self.is_song_select: self.draw_song_select() + ray.draw_texture(self.textures['song_select'][244], 5, 5, ray.WHITE) elif self.is_difficulty_select: self.draw_difficulty_select() + ray.draw_texture(self.textures['song_select'][192], 5, 5, ray.WHITE) + ray.draw_texture(self.textures['song_select'][394], 0, self.height - self.textures['song_select'][394].height, ray.WHITE) + + if self.game_transition is not None: + self.game_transition.draw(self.height) + +class SongBox: + def __init__(self, song_name_texture: OutlinedText, dirpath, scores): + self.name = song_name_texture + self.dirpath = dirpath + self.scores = scores + def update(self): + pass + def draw(self, x: int, y: int, texture_index: int, textures): + ray.draw_texture(textures['song_select'][texture_index+1], x, y, ray.WHITE) + for i in range(0, textures['song_select'][texture_index].width * 4, textures['song_select'][texture_index].width): + ray.draw_texture(textures['song_select'][texture_index], (x+32)+i, y, ray.WHITE) + ray.draw_texture(textures['song_select'][texture_index+2], x+64, y, ray.WHITE) + ray.draw_texture(textures['song_select'][texture_index+3], x+12, y+16, ray.WHITE) + + src = ray.Rectangle(0, 0, self.name.texture.width, self.name.texture.height) + dest = ray.Rectangle(x + 47 - int(self.name.texture.width / 2), y+35, self.name.texture.width, min(self.name.texture.height, 417)) + self.name.draw(src, dest, ray.Vector2(0, 0), 0, ray.WHITE) + +class YellowBox: + def __init__(self): + self.is_diff_select = False + self.right_x = 803 + self.left_x = 443 + self.top_y = 94 + self.bottom_y = 542 + self.center_width = 331 + self.center_height = 422 + self.edge_height = 32 + self.name = None + def update(self, name, is_diff_select): + self.is_diff_select = is_diff_select + self.name = name + if self.is_diff_select: + self.right_x = 1014 + self.left_x = 230 + self.top_y = 34 + self.center_width = 755 + self.center_height = 482 + else: + self.right_x = 803 + self.left_x = 443 + self.top_y = 94 + self.center_width = 331 + self.center_height = 422 + def draw(self, textures, song_list, song_boxes): + + # Draw corners + ray.draw_texture(textures['song_select'][235], self.right_x, self.bottom_y, ray.WHITE) # Bottom right + ray.draw_texture(textures['song_select'][236], self.left_x, self.bottom_y, ray.WHITE) # Bottom left + ray.draw_texture(textures['song_select'][237], self.right_x, self.top_y, ray.WHITE) # Top right + ray.draw_texture(textures['song_select'][238], self.left_x, self.top_y, ray.WHITE) # Top left + + # Edges + # Bottom edge + texture = textures['song_select'][231] + src = ray.Rectangle(0, 0, texture.width, texture.height) + dest = ray.Rectangle(self.left_x + self.edge_height, self.bottom_y, self.center_width, texture.height) + ray.draw_texture_pro(texture, src, dest, ray.Vector2(0, 0), 0, ray.WHITE) + + # Right edge + texture = textures['song_select'][232] + src = ray.Rectangle(0, 0, texture.width, texture.height) + dest = ray.Rectangle(self.right_x, self.top_y + self.edge_height, texture.width, self.center_height) + ray.draw_texture_pro(texture, src, dest, ray.Vector2(0, 0), 0, ray.WHITE) + + # Left edge + texture = textures['song_select'][233] + src = ray.Rectangle(0, 0, texture.width, texture.height) + dest = ray.Rectangle(self.left_x, self.top_y + self.edge_height, texture.width, self.center_height) + ray.draw_texture_pro(texture, src, dest, ray.Vector2(0, 0), 0, ray.WHITE) + + # Top edge + texture = textures['song_select'][234] + src = ray.Rectangle(0, 0, texture.width, texture.height) + dest = ray.Rectangle(self.left_x + self.edge_height, self.top_y, self.center_width, texture.height) + ray.draw_texture_pro(texture, src, dest, ray.Vector2(0, 0), 0, ray.WHITE) + + # Center + texture = textures['song_select'][230] + src = ray.Rectangle(0, 0, texture.width, texture.height) + dest = ray.Rectangle(self.left_x + self.edge_height, self.top_y + self.edge_height, self.center_width, self.center_height) + ray.draw_texture_pro(texture, src, dest, ray.Vector2(0, 0), 0, ray.WHITE) + + + if self.is_diff_select: + #Back Button + ray.draw_texture(textures['song_select'][153], 314, 110, ray.WHITE) + + #Difficulties + ray.draw_texture(textures['song_select'][154], 450, 90, ray.WHITE) + ray.draw_texture(textures['song_select'][182], 565, 90, ray.WHITE) + ray.draw_texture(textures['song_select'][185], 680, 90, ray.WHITE) + ray.draw_texture(textures['song_select'][188], 795, 90, ray.WHITE) + + for i in range(4): + try: + for j in range(song_list[song_boxes[5].dirpath][8][i][0]): + ray.draw_texture(textures['song_select'][155], 482+(i*115), 471+(j*-20), ray.WHITE) + except: + pass + + else: + #Crowns + for i in range(4): + if i in song_boxes[5].scores and song_boxes[5].scores[i] is not None and song_boxes[5].scores[i][3] == 0: + ray.draw_texture(textures['song_select'][160], 473 + (i*60), 175, ray.WHITE) + ray.draw_texture(textures['song_select'][158], 473 + (i*60), 175, ray.fade(ray.WHITE, 0.25)) + + #Difficulties + ray.draw_texture(textures['song_select'][395], 458, 210, ray.WHITE) + ray.draw_texture(textures['song_select'][401], 518, 210, ray.WHITE) + ray.draw_texture(textures['song_select'][403], 578, 210, ray.WHITE) + ray.draw_texture(textures['song_select'][406], 638, 210, ray.WHITE) + + #Stars + for i in range(4): + try: + for j in range(song_list[song_boxes[5].dirpath][8][i][0]): + ray.draw_texture(textures['song_select'][396], 474+(i*60), 490+(j*-17), ray.WHITE) + except: + pass + + if self.name is not None: + texture = self.name.texture + src = ray.Rectangle(0, 0, texture.width, texture.height) + dest = ray.Rectangle((self.right_x - 32) - texture.width / 2, self.top_y + 32, texture.width, min(texture.height, 417)) + self.name.draw(src, dest, ray.Vector2(0, 0), 0, ray.WHITE) + +class Transition: + def __init__(self, screen_height) -> None: + self.is_finished = False + self.rainbow_up = Animation.create_move(266, start_position=0, total_distance=screen_height + global_data.textures['scene_change_rainbow'][2].height, ease_in='cubic') + self.chara_down = None + def update(self, current_time_ms: float): + self.rainbow_up.update(current_time_ms) + if self.rainbow_up.is_finished and self.chara_down is None: + self.chara_down = Animation.create_move(33, start_position=0, total_distance=30) + + if self.chara_down is not None: + self.chara_down.update(current_time_ms) + self.is_finished = self.chara_down.is_finished + + def draw(self, screen_height): + ray.draw_texture(global_data.textures['scene_change_rainbow'][2], 0, screen_height - int(self.rainbow_up.attribute), ray.WHITE) + texture = global_data.textures['scene_change_rainbow'][0] + src = ray.Rectangle(0, 0, texture.width, texture.height) + dest = ray.Rectangle(0, screen_height - int(self.rainbow_up.attribute) + global_data.textures['scene_change_rainbow'][2].height, texture.width, screen_height) + ray.draw_texture_pro(texture, src, dest, ray.Vector2(0, 0), 0, ray.WHITE) + texture = global_data.textures['scene_change_rainbow'][3] + offset = 0 + if self.chara_down is not None: + offset = int(self.chara_down.attribute) + ray.draw_texture(texture, 76, 816 - int(self.rainbow_up.attribute) + offset, ray.WHITE)