mirror of
https://github.com/Yonokid/PyTaiko.git
synced 2026-02-04 11:40:13 +01:00
writing attract sequence
This commit is contained in:
27
game.py
27
game.py
@@ -111,6 +111,8 @@ class GameScreen:
|
|||||||
ray.load_texture(folder_path + 'lane_obi_img00022.png'),
|
ray.load_texture(folder_path + 'lane_obi_img00022.png'),
|
||||||
ray.load_texture(folder_path + 'lane_obi_img00023.png'),
|
ray.load_texture(folder_path + 'lane_obi_img00023.png'),
|
||||||
ray.load_texture(folder_path + 'lane_obi_img00024.png'),
|
ray.load_texture(folder_path + 'lane_obi_img00024.png'),
|
||||||
|
ray.load_texture(folder_path + 'lane_obi_img00025.png'),
|
||||||
|
ray.load_texture(folder_path + 'lane_obi_img00025.png'),
|
||||||
ray.load_texture(folder_path + 'lane_obi_img00025.png')]
|
ray.load_texture(folder_path + 'lane_obi_img00025.png')]
|
||||||
|
|
||||||
self.texture_combo_text = [ray.load_texture(folder_path + 'lane_obi_img00035.png'),
|
self.texture_combo_text = [ray.load_texture(folder_path + 'lane_obi_img00035.png'),
|
||||||
@@ -168,6 +170,7 @@ class GameScreen:
|
|||||||
self.load_textures()
|
self.load_textures()
|
||||||
self.load_sounds()
|
self.load_sounds()
|
||||||
|
|
||||||
|
#Map notes to textures
|
||||||
self.note_type_dict = {'1': self.texture_don,
|
self.note_type_dict = {'1': self.texture_don,
|
||||||
'2': self.texture_kat,
|
'2': self.texture_kat,
|
||||||
'3': self.texture_dai_don,
|
'3': self.texture_dai_don,
|
||||||
@@ -188,6 +191,7 @@ class GameScreen:
|
|||||||
self.song_music = ray.load_music_stream(self.tja.wave)
|
self.song_music = ray.load_music_stream(self.tja.wave)
|
||||||
ray.play_music_stream(self.song_music)
|
ray.play_music_stream(self.song_music)
|
||||||
self.start_ms = get_current_ms() - self.tja.offset*1000
|
self.start_ms = get_current_ms() - self.tja.offset*1000
|
||||||
|
self.profiler = Profiler()
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
ray.update_music_stream(self.song_music)
|
ray.update_music_stream(self.song_music)
|
||||||
@@ -195,7 +199,7 @@ class GameScreen:
|
|||||||
self.player_1.update(self)
|
self.player_1.update(self)
|
||||||
|
|
||||||
def draw(self):
|
def draw(self):
|
||||||
self.player_1.draw(self)
|
self.profiler.profile(self.player_1.draw, (self))
|
||||||
|
|
||||||
class Player:
|
class Player:
|
||||||
def __init__(self, game_screen, player_number, difficulty):
|
def __init__(self, game_screen, player_number, difficulty):
|
||||||
@@ -393,6 +397,13 @@ class Player:
|
|||||||
self.curr_drumroll_count = 0
|
self.curr_drumroll_count = 0
|
||||||
self.curr_balloon_count = 0
|
self.curr_balloon_count = 0
|
||||||
current_note = self.current_notes[0]
|
current_note = self.current_notes[0]
|
||||||
|
#Fix later
|
||||||
|
'''
|
||||||
|
i = 0
|
||||||
|
while current_note['note'] in {'5', '6', '7', '8'}:
|
||||||
|
i += 1
|
||||||
|
current_note = self.current_notes[i]
|
||||||
|
'''
|
||||||
note_type = current_note['note']
|
note_type = current_note['note']
|
||||||
note_ms = current_note['ms']
|
note_ms = current_note['ms']
|
||||||
#If the wrong key was hit, stop checking
|
#If the wrong key was hit, stop checking
|
||||||
@@ -427,6 +438,7 @@ class Player:
|
|||||||
self.draw_judge_list.append(Judgement(game_screen.current_ms, 'BAD', big))
|
self.draw_judge_list.append(Judgement(game_screen.current_ms, 'BAD', big))
|
||||||
self.bad_count += 1
|
self.bad_count += 1
|
||||||
self.combo = 0
|
self.combo = 0
|
||||||
|
self.current_notes.popleft()
|
||||||
|
|
||||||
def drumroll_counter_manager(self, game_screen):
|
def drumroll_counter_manager(self, game_screen):
|
||||||
if self.is_drumroll and self.curr_drumroll_count > 0:
|
if self.is_drumroll and self.curr_drumroll_count > 0:
|
||||||
@@ -434,7 +446,7 @@ class Player:
|
|||||||
self.drumroll_counter.append(DrumrollCounter(game_screen.current_ms))
|
self.drumroll_counter.append(DrumrollCounter(game_screen.current_ms))
|
||||||
|
|
||||||
if len(self.drumroll_counter) > 0:
|
if len(self.drumroll_counter) > 0:
|
||||||
if self.drumroll_counter[0].is_finished:
|
if self.drumroll_counter[0].is_finished and not self.is_drumroll:
|
||||||
self.drumroll_counter.pop(0)
|
self.drumroll_counter.pop(0)
|
||||||
else:
|
else:
|
||||||
self.drumroll_counter[0].update(game_screen, game_screen.current_ms, self.curr_drumroll_count)
|
self.drumroll_counter[0].update(game_screen, game_screen.current_ms, self.curr_drumroll_count)
|
||||||
@@ -464,22 +476,22 @@ class Player:
|
|||||||
self.score_list[0].update(game_screen.current_ms, self.score)
|
self.score_list[0].update(game_screen.current_ms, self.score)
|
||||||
|
|
||||||
def key_manager(self, game_screen):
|
def key_manager(self, game_screen):
|
||||||
if ray.is_key_pressed(ray.KeyboardKey.KEY_F):
|
if ray.is_key_pressed(ray.KeyboardKey.KEY_F) or ray.is_key_pressed(ray.KeyboardKey.KEY_D):
|
||||||
self.draw_effect_list.append(LaneHitEffect(game_screen.current_ms, 'DON'))
|
self.draw_effect_list.append(LaneHitEffect(game_screen.current_ms, 'DON'))
|
||||||
self.draw_drum_hit_list.append(DrumHitEffect(game_screen.current_ms, 'DON', 'L'))
|
self.draw_drum_hit_list.append(DrumHitEffect(game_screen.current_ms, 'DON', 'L'))
|
||||||
ray.play_sound(game_screen.sound_don)
|
ray.play_sound(game_screen.sound_don)
|
||||||
self.check_note(game_screen, '1')
|
self.check_note(game_screen, '1')
|
||||||
if ray.is_key_pressed(ray.KeyboardKey.KEY_J):
|
if ray.is_key_pressed(ray.KeyboardKey.KEY_J) or ray.is_key_pressed(ray.KeyboardKey.KEY_K):
|
||||||
self.draw_effect_list.append(LaneHitEffect(game_screen.current_ms, 'DON'))
|
self.draw_effect_list.append(LaneHitEffect(game_screen.current_ms, 'DON'))
|
||||||
self.draw_drum_hit_list.append(DrumHitEffect(game_screen.current_ms, 'DON', 'R'))
|
self.draw_drum_hit_list.append(DrumHitEffect(game_screen.current_ms, 'DON', 'R'))
|
||||||
ray.play_sound(game_screen.sound_don)
|
ray.play_sound(game_screen.sound_don)
|
||||||
self.check_note(game_screen, '1')
|
self.check_note(game_screen, '1')
|
||||||
if ray.is_key_pressed(ray.KeyboardKey.KEY_D):
|
if ray.is_key_pressed(ray.KeyboardKey.KEY_E) or ray.is_key_pressed(ray.KeyboardKey.KEY_R):
|
||||||
self.draw_effect_list.append(LaneHitEffect(game_screen.current_ms, 'KAT'))
|
self.draw_effect_list.append(LaneHitEffect(game_screen.current_ms, 'KAT'))
|
||||||
self.draw_drum_hit_list.append(DrumHitEffect(game_screen.current_ms, 'KAT', 'L'))
|
self.draw_drum_hit_list.append(DrumHitEffect(game_screen.current_ms, 'KAT', 'L'))
|
||||||
ray.play_sound(game_screen.sound_kat)
|
ray.play_sound(game_screen.sound_kat)
|
||||||
self.check_note(game_screen, '2')
|
self.check_note(game_screen, '2')
|
||||||
if ray.is_key_pressed(ray.KeyboardKey.KEY_K):
|
if ray.is_key_pressed(ray.KeyboardKey.KEY_I) or ray.is_key_pressed(ray.KeyboardKey.KEY_U):
|
||||||
self.draw_effect_list.append(LaneHitEffect(game_screen.current_ms, 'KAT'))
|
self.draw_effect_list.append(LaneHitEffect(game_screen.current_ms, 'KAT'))
|
||||||
self.draw_drum_hit_list.append(DrumHitEffect(game_screen.current_ms, 'KAT', 'R'))
|
self.draw_drum_hit_list.append(DrumHitEffect(game_screen.current_ms, 'KAT', 'R'))
|
||||||
ray.play_sound(game_screen.sound_kat)
|
ray.play_sound(game_screen.sound_kat)
|
||||||
@@ -498,6 +510,7 @@ class Player:
|
|||||||
self.animation_manager(game_screen, self.base_score_list)
|
self.animation_manager(game_screen, self.base_score_list)
|
||||||
self.score_manager(game_screen)
|
self.score_manager(game_screen)
|
||||||
self.key_manager(game_screen)
|
self.key_manager(game_screen)
|
||||||
|
return None
|
||||||
|
|
||||||
def draw_animation_list(self, game_screen, animation_list):
|
def draw_animation_list(self, game_screen, animation_list):
|
||||||
for animation in animation_list:
|
for animation in animation_list:
|
||||||
@@ -546,7 +559,7 @@ class Player:
|
|||||||
elif note in game_screen.note_type_dict:
|
elif note in game_screen.note_type_dict:
|
||||||
eighth_in_ms = (60000 * 4 / game_screen.tja.bpm) / 8
|
eighth_in_ms = (60000 * 4 / game_screen.tja.bpm) / 8
|
||||||
if self.combo >= 50:
|
if self.combo >= 50:
|
||||||
current_eighth = int(game_screen.current_ms // eighth_in_ms)
|
current_eighth = int((game_screen.current_ms - game_screen.start_ms) // eighth_in_ms)
|
||||||
else:
|
else:
|
||||||
current_eighth = 0
|
current_eighth = 0
|
||||||
if note in {'5', '6', 'drumroll_tail', 'dai_drumroll_tail', 'drumroll_body', 'dai_drumroll_body'}:
|
if note in {'5', '6', 'drumroll_tail', 'dai_drumroll_tail', 'drumroll_body', 'dai_drumroll_body'}:
|
||||||
|
|||||||
177
global_funcs.py
177
global_funcs.py
@@ -6,6 +6,103 @@ from collections import deque
|
|||||||
|
|
||||||
#TJA Format creator is unknown. I did not create the format, but I did write the parser though.
|
#TJA Format creator is unknown. I did not create the format, but I did write the parser though.
|
||||||
|
|
||||||
|
import cProfile
|
||||||
|
import pstats
|
||||||
|
import io
|
||||||
|
import sys
|
||||||
|
|
||||||
|
class Profiler:
|
||||||
|
def __init__(self):
|
||||||
|
self.profiler = cProfile.Profile()
|
||||||
|
self.stats = None
|
||||||
|
self.calls = 0
|
||||||
|
self.profiled_functions = set() # Track profiled functions
|
||||||
|
self.previous_order = [] # Track previous order of functions
|
||||||
|
|
||||||
|
def profile(self, func, *args, **kwargs):
|
||||||
|
func_name = func.__name__
|
||||||
|
self.calls += 1
|
||||||
|
|
||||||
|
# Start profiling
|
||||||
|
self.profiler.enable()
|
||||||
|
func(*args, **kwargs)
|
||||||
|
self.profiler.disable()
|
||||||
|
|
||||||
|
# Collect and update stats
|
||||||
|
if self.stats is None:
|
||||||
|
self.stats = pstats.Stats(self.profiler)
|
||||||
|
else:
|
||||||
|
self.stats.add(self.profiler)
|
||||||
|
|
||||||
|
# Get current order of functions
|
||||||
|
current_order = self.get_current_function_order()
|
||||||
|
|
||||||
|
# Check if a new function is added or if order has changed
|
||||||
|
if func_name not in self.profiled_functions or self.previous_order != current_order:
|
||||||
|
self.profiled_functions.add(func_name)
|
||||||
|
self.clear_screen()
|
||||||
|
|
||||||
|
# Update the previous order to the current one
|
||||||
|
self.previous_order = current_order
|
||||||
|
|
||||||
|
# Print the averaged stats
|
||||||
|
self.print_averaged_stats()
|
||||||
|
|
||||||
|
def clear_screen(self):
|
||||||
|
sys.stdout.write('\033[2J\033[H') # Clear screen and move cursor to the top
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
def get_current_function_order(self):
|
||||||
|
# Capture stats output to determine the current order of functions
|
||||||
|
stream = io.StringIO()
|
||||||
|
stats = pstats.Stats(self.profiler, stream=stream)
|
||||||
|
stats.sort_stats(pstats.SortKey.TIME)
|
||||||
|
stats.print_stats()
|
||||||
|
|
||||||
|
# Extract function names from the stats output
|
||||||
|
content = stream.getvalue().splitlines()[5:] # Skip header lines
|
||||||
|
function_order = [line.split()[-1] for line in content if line.strip()]
|
||||||
|
return function_order
|
||||||
|
|
||||||
|
def print_averaged_stats(self):
|
||||||
|
# Prepare the output stream to capture stats
|
||||||
|
stream = io.StringIO()
|
||||||
|
stats = pstats.Stats(self.profiler, stream=stream)
|
||||||
|
stats.sort_stats(pstats.SortKey.TIME)
|
||||||
|
|
||||||
|
# Print the stats, but suppress the raw counts
|
||||||
|
stats.print_stats()
|
||||||
|
|
||||||
|
# Extract and process stats to average them
|
||||||
|
content = stream.getvalue().splitlines()
|
||||||
|
header = content[:5] # Keep the header
|
||||||
|
data = content[5:] # Data lines
|
||||||
|
if data:
|
||||||
|
# Update the total calls and times
|
||||||
|
avg_data = []
|
||||||
|
|
||||||
|
for line in data:
|
||||||
|
parts = line.split()
|
||||||
|
if len(parts) >= 6:
|
||||||
|
ncalls = int(parts[0].replace('/', '')) # Total calls
|
||||||
|
tottime = float(parts[1]) # Total time
|
||||||
|
percall = tottime / ncalls if ncalls > 0 else 0
|
||||||
|
cumtime = float(parts[3]) # Cumulative time
|
||||||
|
cumpercall = cumtime / ncalls if ncalls > 0 else 0
|
||||||
|
|
||||||
|
# Format and add the line
|
||||||
|
avg_data.append(
|
||||||
|
f"{ncalls:>9} {tottime / self.calls:>9.3f} {percall:>9.3f} "
|
||||||
|
f"{ncalls:>9} {cumtime / self.calls:>9.3f} {cumpercall:>9.3f} {line[90:]}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Move cursor to the start of the line before printing
|
||||||
|
sys.stdout.write('\033[F' * (len(header) + len(avg_data))) # Move cursor up to overwrite
|
||||||
|
|
||||||
|
# Print the header and averaged data
|
||||||
|
sys.stdout.write('\n'.join(header + avg_data) + '\n')
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
def rounded(d):
|
def rounded(d):
|
||||||
sign = 1 if (d >= 0) else -1
|
sign = 1 if (d >= 0) else -1
|
||||||
d = abs(d)
|
d = abs(d)
|
||||||
@@ -68,6 +165,7 @@ class tja_parser:
|
|||||||
self.scroll_modifier = 1
|
self.scroll_modifier = 1
|
||||||
self.current_ms = 0
|
self.current_ms = 0
|
||||||
self.barline_display = True
|
self.barline_display = True
|
||||||
|
self.gogo_time = False
|
||||||
|
|
||||||
def file_to_data(self):
|
def file_to_data(self):
|
||||||
with open(self.file_path, 'rt', encoding='utf-8-sig') as tja_file:
|
with open(self.file_path, 'rt', encoding='utf-8-sig') as tja_file:
|
||||||
@@ -94,7 +192,11 @@ class tja_parser:
|
|||||||
elif 'DEMOSTART' in item: self.demo_start = float(item.split(':')[1])
|
elif 'DEMOSTART' in item: self.demo_start = float(item.split(':')[1])
|
||||||
elif 'COURSE' in item:
|
elif 'COURSE' in item:
|
||||||
course = str(item.split(':')[1]).lower()
|
course = str(item.split(':')[1]).lower()
|
||||||
if course == 'edit' or course == '4':
|
if course == 'tower' or course == '6':
|
||||||
|
self.course_data[6] = []
|
||||||
|
if course == 'dan' or course == '5':
|
||||||
|
self.course_data[5] = []
|
||||||
|
elif course == 'edit' or course == '4':
|
||||||
self.course_data[4] = []
|
self.course_data[4] = []
|
||||||
elif course == 'oni' or course == '3':
|
elif course == 'oni' or course == '3':
|
||||||
self.course_data[3] = []
|
self.course_data[3] = []
|
||||||
@@ -195,6 +297,12 @@ class tja_parser:
|
|||||||
elif '#BARLINEON' in part:
|
elif '#BARLINEON' in part:
|
||||||
self.barline_display = True
|
self.barline_display = True
|
||||||
continue
|
continue
|
||||||
|
elif '#GOGOSTART' in part:
|
||||||
|
self.gogo_time = True
|
||||||
|
continue
|
||||||
|
elif '#GOGOEND' in part:
|
||||||
|
self.gogo_time = False
|
||||||
|
continue
|
||||||
#Unrecognized commands will be skipped for now
|
#Unrecognized commands will be skipped for now
|
||||||
elif '#' in part:
|
elif '#' in part:
|
||||||
continue
|
continue
|
||||||
@@ -255,6 +363,9 @@ class tja_parser:
|
|||||||
if note in {'5', '6', '8'}:
|
if note in {'5', '6', '8'}:
|
||||||
play_note_list[-1]['color'] = 255
|
play_note_list[-1]['color'] = 255
|
||||||
if note == '8' and play_note_list[-2]['note'] in ('7', '9'):
|
if note == '8' and play_note_list[-2]['note'] in ('7', '9'):
|
||||||
|
if balloon_index >= len(balloon):
|
||||||
|
play_note_list[-1]['balloon'] = 0
|
||||||
|
else:
|
||||||
play_note_list[-1]['balloon'] = int(balloon[balloon_index])
|
play_note_list[-1]['balloon'] = int(balloon[balloon_index])
|
||||||
balloon_index += 1
|
balloon_index += 1
|
||||||
self.current_ms += increment
|
self.current_ms += increment
|
||||||
@@ -367,3 +478,67 @@ class Animation:
|
|||||||
else:
|
else:
|
||||||
self.attribute = 0
|
self.attribute = 0
|
||||||
self.is_finished = True
|
self.is_finished = True
|
||||||
|
|
||||||
|
import cv2
|
||||||
|
|
||||||
|
class VideoPlayer:
|
||||||
|
def __init__(self, path, loop_start=None):
|
||||||
|
video_path = path
|
||||||
|
audio_path = path[:-4] + '.ogg'
|
||||||
|
self.loop_start = loop_start
|
||||||
|
self.cap = cv2.VideoCapture(video_path)
|
||||||
|
fps = self.cap.get(cv2.CAP_PROP_FPS)
|
||||||
|
self.frame_texture = None
|
||||||
|
self.frame_time = (1.0 / fps) * 1000
|
||||||
|
self.start_ms = get_current_ms()
|
||||||
|
self.audio = ray.load_music_stream(audio_path)
|
||||||
|
if loop_start is None:
|
||||||
|
self.audio.looping = False
|
||||||
|
self.is_finished = [False, False]
|
||||||
|
ray.play_music_stream(self.audio)
|
||||||
|
|
||||||
|
if not self.cap.isOpened():
|
||||||
|
print("Error: Could not open video file.")
|
||||||
|
return
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
current_ms = get_current_ms()
|
||||||
|
elapsed_time = current_ms - self.start_ms
|
||||||
|
ray.update_music_stream(self.audio)
|
||||||
|
if not ray.is_music_stream_playing(self.audio):
|
||||||
|
self.is_finished[1] = True
|
||||||
|
|
||||||
|
if elapsed_time >= self.frame_time:
|
||||||
|
ret, frame = self.cap.read()
|
||||||
|
|
||||||
|
if not ret:
|
||||||
|
# Reset to the loop start frame
|
||||||
|
if self.loop_start == None:
|
||||||
|
self.is_finished[0] = True
|
||||||
|
else:
|
||||||
|
self.cap.set(cv2.CAP_PROP_POS_FRAMES, self.loop_start)
|
||||||
|
ret, frame = self.cap.read() # Read the frame at loop start
|
||||||
|
if not ret:
|
||||||
|
return # If still not successful, return
|
||||||
|
|
||||||
|
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
|
||||||
|
image = ray.Image(frame_rgb.tobytes(), frame_rgb.shape[1], frame_rgb.shape[0], 1, ray.PIXELFORMAT_UNCOMPRESSED_R8G8B8)
|
||||||
|
new_texture = ray.load_texture_from_image(image)
|
||||||
|
|
||||||
|
# Unload the previous texture if it exists
|
||||||
|
if self.frame_texture:
|
||||||
|
ray.unload_texture(self.frame_texture)
|
||||||
|
|
||||||
|
# Assign the new texture to the instance variable
|
||||||
|
self.frame_texture = new_texture
|
||||||
|
self.start_ms = current_ms
|
||||||
|
|
||||||
|
def draw(self):
|
||||||
|
if self.frame_texture:
|
||||||
|
ray.draw_texture(self.frame_texture, 0, 0, ray.WHITE)
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
# Ensure resources are cleaned up when the instance is deleted
|
||||||
|
if self.frame_texture:
|
||||||
|
ray.unload_texture(self.frame_texture)
|
||||||
|
self.cap.release()
|
||||||
|
|||||||
7
main.py
7
main.py
@@ -3,6 +3,7 @@ import sys
|
|||||||
|
|
||||||
from entry import *
|
from entry import *
|
||||||
from game import *
|
from game import *
|
||||||
|
from title import *
|
||||||
|
|
||||||
class Screens:
|
class Screens:
|
||||||
TITLE = "TITLE"
|
TITLE = "TITLE"
|
||||||
@@ -21,23 +22,23 @@ def main():
|
|||||||
ray.set_window_min_size(screen_width, screen_height)
|
ray.set_window_min_size(screen_width, screen_height)
|
||||||
ray.init_window(screen_width, screen_height, "PyTaiko")
|
ray.init_window(screen_width, screen_height, "PyTaiko")
|
||||||
|
|
||||||
current_screen = Screens.ENTRY
|
current_screen = Screens.TITLE
|
||||||
frames_counter = 0
|
frames_counter = 0
|
||||||
|
|
||||||
ray.init_audio_device()
|
ray.init_audio_device()
|
||||||
|
|
||||||
|
title_screen = TitleScreen(screen_width, screen_height)
|
||||||
entry_screen = EntryScreen(screen_width, screen_height)
|
entry_screen = EntryScreen(screen_width, screen_height)
|
||||||
game_screen = GameScreen(screen_width, screen_height)
|
game_screen = GameScreen(screen_width, screen_height)
|
||||||
|
|
||||||
screen_mapping = {
|
screen_mapping = {
|
||||||
Screens.ENTRY: entry_screen,
|
Screens.ENTRY: entry_screen,
|
||||||
#Screens.TITLE: title_screen,
|
Screens.TITLE: title_screen,
|
||||||
#Screens.SONG_SELECT: song_select_screen,
|
#Screens.SONG_SELECT: song_select_screen,
|
||||||
Screens.GAME: game_screen,
|
Screens.GAME: game_screen,
|
||||||
#Screens.RESULT: result_screen
|
#Screens.RESULT: result_screen
|
||||||
}
|
}
|
||||||
|
|
||||||
#ray.set_target_fps(144)
|
|
||||||
start_song = False
|
start_song = False
|
||||||
while not ray.window_should_close():
|
while not ray.window_should_close():
|
||||||
ray.begin_drawing()
|
ray.begin_drawing()
|
||||||
|
|||||||
141
title.py
Normal file
141
title.py
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
import pyray as ray
|
||||||
|
import numpy as np
|
||||||
|
import vlc
|
||||||
|
import cv2
|
||||||
|
from global_funcs import Animation, VideoPlayer, get_current_ms
|
||||||
|
|
||||||
|
class TitleScreen:
|
||||||
|
def __init__(self, width, height):
|
||||||
|
self.width = width
|
||||||
|
self.height = height
|
||||||
|
self.op_video = VideoPlayer('Videos\\OP.mp4')
|
||||||
|
self.warning = None
|
||||||
|
self.load_textures()
|
||||||
|
|
||||||
|
def load_textures(self):
|
||||||
|
self.texture_bg = ray.load_texture('Graphics\\lumendata\\attract\\keikoku\\keikoku_img00000.png')
|
||||||
|
self.texture_warning = ray.load_texture('Graphics\\lumendata\\attract\\keikoku\\keikoku_img00001.png')
|
||||||
|
self.texture_warning_ch1 = [ray.load_texture('Graphics\\lumendata\\attract\\keikoku\\keikoku_img00004.png'),
|
||||||
|
ray.load_texture('Graphics\\lumendata\\attract\\keikoku\\keikoku_img00009.png'),
|
||||||
|
ray.load_texture('Graphics\\lumendata\\attract\\keikoku\\keikoku_img00016.png')]
|
||||||
|
self.texture_warning_ch1_base = ray.load_texture('Graphics\\lumendata\\attract\\keikoku\\keikoku_img00002.png')
|
||||||
|
self.texture_warning_ch2 = [ray.load_texture('Graphics\\lumendata\\attract\\keikoku\\keikoku_img00005.png'),
|
||||||
|
ray.load_texture('Graphics\\lumendata\\attract\\keikoku\\keikoku_img00006.png'),
|
||||||
|
ray.load_texture('Graphics\\lumendata\\attract\\keikoku\\keikoku_img00007.png'),
|
||||||
|
ray.load_texture('Graphics\\lumendata\\attract\\keikoku\\keikoku_img00008.png'),
|
||||||
|
ray.load_texture('Graphics\\lumendata\\attract\\keikoku\\keikoku_img00010.png'),
|
||||||
|
ray.load_texture('Graphics\\lumendata\\attract\\keikoku\\keikoku_img00011.png'),
|
||||||
|
ray.load_texture('Graphics\\lumendata\\attract\\keikoku\\keikoku_img00012.png'),
|
||||||
|
ray.load_texture('Graphics\\lumendata\\attract\\keikoku\\keikoku_img00013.png'),
|
||||||
|
ray.load_texture('Graphics\\lumendata\\attract\\keikoku\\keikoku_img00017.png')]
|
||||||
|
self.texture_warning_ch2_base = ray.load_texture('Graphics\\lumendata\\attract\\keikoku\\keikoku_img00003.png')
|
||||||
|
self.texture_warning_bachi = ray.load_texture('Graphics\\lumendata\\attract\\keikoku\\keikoku_img00019.png')
|
||||||
|
self.texture_warning_bachi_hit = ray.load_texture('Graphics\\lumendata\\attract\\keikoku\\keikoku_img00018.png')
|
||||||
|
|
||||||
|
self.sound_bachi_swipe = ray.load_sound('Sounds\\title\\SE_ATTRACT_2.ogg')
|
||||||
|
self.sound_bachi_hit = ray.load_sound('Sounds\\title\\SE_ATTRACT_3.ogg')
|
||||||
|
|
||||||
|
def animation_manager(self):
|
||||||
|
if self.warning is not None:
|
||||||
|
self.warning.update(get_current_ms(), self)
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
self.animation_manager()
|
||||||
|
if self.op_video is not None:
|
||||||
|
self.op_video.update()
|
||||||
|
if all(self.op_video.is_finished):
|
||||||
|
self.op_video = None
|
||||||
|
self.warning = WarningBoard(get_current_ms(), self)
|
||||||
|
if ray.is_key_pressed(ray.KeyboardKey.KEY_ENTER):
|
||||||
|
return "ENTRY"
|
||||||
|
return None
|
||||||
|
|
||||||
|
def draw_animation(self):
|
||||||
|
if self.warning is not None:
|
||||||
|
self.warning.draw(self)
|
||||||
|
def draw(self):
|
||||||
|
if self.op_video is not None:
|
||||||
|
self.op_video.draw()
|
||||||
|
return
|
||||||
|
bg_source = ray.Rectangle(0, 0, self.texture_bg.width, self.texture_bg.height)
|
||||||
|
bg_dest = ray.Rectangle(0, 0, self.width, self.height)
|
||||||
|
ray.draw_texture_pro(self.texture_bg, bg_source, bg_dest, ray.Vector2(0,0), 0, ray.WHITE)
|
||||||
|
self.draw_animation()
|
||||||
|
|
||||||
|
class WarningBoard:
|
||||||
|
def __init__(self, current_ms, title_screen):
|
||||||
|
self.start_ms = current_ms
|
||||||
|
self.move_animation_1 = Animation(current_ms, 266.67, 'move')
|
||||||
|
self.move_animation_1.params['start_position'] = -720
|
||||||
|
self.move_animation_1.params['total_distance'] = title_screen.height + ((title_screen.height - title_screen.texture_warning.height)//2) + 20
|
||||||
|
|
||||||
|
self.move_animation_2 = Animation(current_ms, 116.67, 'move')
|
||||||
|
self.move_animation_2.params['start_position'] = 92 + 20
|
||||||
|
self.move_animation_2.params['delay'] = 266.67
|
||||||
|
self.move_animation_2.params['total_distance'] = -30
|
||||||
|
|
||||||
|
self.move_animation_3 = Animation(current_ms, 116.67, 'move')
|
||||||
|
self.move_animation_3.params['start_position'] = 82
|
||||||
|
self.move_animation_3.params['delay'] = 383.34
|
||||||
|
self.move_animation_3.params['total_distance'] = 10
|
||||||
|
|
||||||
|
self.fade_animation_1 = Animation(current_ms, 300, 'fade')
|
||||||
|
self.fade_animation_1.params['delay'] = 266.67
|
||||||
|
self.fade_animation_1.params['initial_opacity'] = 0.0
|
||||||
|
self.fade_animation_1.params['final_opacity'] = 1.0
|
||||||
|
self.character_time = 0
|
||||||
|
self.character_index_val = 0
|
||||||
|
self.hit_played = False
|
||||||
|
|
||||||
|
def update(self, current_ms, title_screen):
|
||||||
|
self.move_animation_1.update(current_ms)
|
||||||
|
self.move_animation_2.update(current_ms)
|
||||||
|
self.move_animation_3.update(current_ms)
|
||||||
|
self.fade_animation_1.update(current_ms)
|
||||||
|
delay = 566.67
|
||||||
|
if delay <= current_ms - self.start_ms and self.character_index(1) != 8:
|
||||||
|
if not ray.is_sound_playing(title_screen.sound_bachi_swipe):
|
||||||
|
ray.play_sound(title_screen.sound_bachi_swipe)
|
||||||
|
elif self.character_index(1) == 8 and not self.hit_played:
|
||||||
|
self.hit_played = True
|
||||||
|
ray.play_sound(title_screen.sound_bachi_hit)
|
||||||
|
|
||||||
|
def character_index(self, index):
|
||||||
|
elapsed_time = get_current_ms() - self.start_ms
|
||||||
|
delay = 566.67
|
||||||
|
animation = [(300.00, 1, 0), (183.33, 2, 0), (166.67, 3, 0), (166.67, 4, 1), (166.67, 5, 1), (166.67, 6, 1), (166.67, 7, 1),
|
||||||
|
(166.67, 0, 0), (150.00, 1, 0), (133.34, 2, 0), (133.34, 3, 0), (133.34, 4, 1), (133.34, 5, 1), (133.34, 6, 1), (133.34, 7, 1),
|
||||||
|
(133.34, 0, 0), (116.67, 1, 0), (100.00, 2, 0), (100.00, 3, 0), (100.00, 4, 1), (100.00, 5, 1), (100.00, 6, 1), (100.00, 7, 1),
|
||||||
|
(100.00, 0, 0), (100.00, 1, 0), (83.330, 2, 0), (83.330, 3, 0), (83.330, 4, 1), (83.330, 5, 1), (83.330, 6, 1), (83.330, 7, 1),
|
||||||
|
(83.330, 0, 0), (83.330, 1, 0), (66.670, 2, 0), (66.670, 3, 0), (66.670, 4, 1), (66.670, 5, 1), (66.670, 6, 1), (66.670, 7, 1),
|
||||||
|
(66.670, 0, 0), (66.670, 1, 0), (66.670, 2, 0), (66.670, 3, 0), (66.670, 4, 1), (66.670, 5, 1), (66.670, 6, 1), (66.670, 7, 1),
|
||||||
|
(66.670, 0, 0), (66.670, 1, 0), (66.670, 2, 0), (66.670, 3, 0), (66.670, 4, 1), (66.670, 5, 1), (66.670, 6, 1), (66.670, 7, 1),
|
||||||
|
(66.670, 8, 2)]
|
||||||
|
if self.character_index_val == len(animation)-1:
|
||||||
|
return animation[len(animation)-1][index]
|
||||||
|
elif elapsed_time <= delay:
|
||||||
|
return 0
|
||||||
|
elif elapsed_time >= delay + self.character_time:
|
||||||
|
new_index = animation[self.character_index_val][index]
|
||||||
|
self.character_index_val += 1
|
||||||
|
self.character_time += animation[self.character_index_val][0]
|
||||||
|
return new_index
|
||||||
|
else:
|
||||||
|
return animation[self.character_index_val][index]
|
||||||
|
|
||||||
|
def draw(self, title_screen):
|
||||||
|
if self.move_animation_2.is_finished:
|
||||||
|
y = self.move_animation_3.attribute
|
||||||
|
elif self.move_animation_1.is_finished:
|
||||||
|
y = self.move_animation_2.attribute
|
||||||
|
else:
|
||||||
|
y = self.move_animation_1.attribute
|
||||||
|
ray.draw_texture(title_screen.texture_warning, 0, int(y), ray.WHITE)
|
||||||
|
fade = ray.fade(ray.WHITE, self.fade_animation_1.attribute)
|
||||||
|
fade_2 = ray.fade(ray.WHITE, self.fade_animation_1.attribute if self.fade_animation_1.attribute < 0.75 else 0.75)
|
||||||
|
ray.draw_texture(title_screen.texture_warning_ch1_base, 135, int(y)+title_screen.texture_warning_ch1[0].height+110, fade_2)
|
||||||
|
ray.draw_texture(title_screen.texture_warning_ch1[self.character_index(2)], 115, int(y)+150, fade)
|
||||||
|
ray.draw_texture(title_screen.texture_warning_ch2_base, 360, int(y)+title_screen.texture_warning_ch2[0].height+60, fade_2)
|
||||||
|
ray.draw_texture(title_screen.texture_warning_ch2[self.character_index(1)], 315, int(y)+100, fade)
|
||||||
|
if self.character_index(1) == 8:
|
||||||
|
ray.draw_texture(title_screen.texture_warning_bachi, 350, int(y)+135, ray.WHITE)
|
||||||
Reference in New Issue
Block a user