mirror of
https://github.com/Yonokid/PyTaiko.git
synced 2026-02-04 03:30:13 +01:00
Add 2P
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
import copy
|
||||
from pathlib import Path
|
||||
from libs.global_data import Modifiers
|
||||
from libs.tja import TJAParser
|
||||
from libs.utils import get_current_ms
|
||||
from libs.audio import audio
|
||||
from libs.utils import global_data, session_data
|
||||
from libs.utils import global_data
|
||||
from libs.video import VideoPlayer
|
||||
from scenes.game import ClearAnimation, FCAnimation, FailAnimation, GameScreen, Player, Background, SCREEN_WIDTH
|
||||
import pyray as ray
|
||||
from scenes.game import ClearAnimation, FCAnimation, FailAnimation, GameScreen, Player, Background, SCREEN_WIDTH, ResultTransition
|
||||
|
||||
class TwoPlayerGameScreen(GameScreen):
|
||||
def on_screen_start(self):
|
||||
@@ -16,27 +16,52 @@ class TwoPlayerGameScreen(GameScreen):
|
||||
if self.background is not None:
|
||||
self.background.unload()
|
||||
self.background = Background(3, self.bpm, scene_preset=scene_preset)
|
||||
self.result_transition = ResultTransition(3)
|
||||
|
||||
def load_hitsounds(self):
|
||||
"""Load the hit sounds"""
|
||||
sounds_dir = Path("Sounds")
|
||||
if global_data.hit_sound == -1:
|
||||
|
||||
# Load hitsounds for 1P
|
||||
if global_data.hit_sound[0] == -1:
|
||||
audio.load_sound(Path('none.wav'), 'hitsound_don_1p')
|
||||
audio.load_sound(Path('none.wav'), 'hitsound_kat_1p')
|
||||
if global_data.hit_sound == 0:
|
||||
audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound) / "don.wav", 'hitsound_don_1p')
|
||||
audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound) / "ka.wav", 'hitsound_kat_1p')
|
||||
audio.set_sound_pan('hitsound_don_1p', 1.0)
|
||||
audio.set_sound_pan('hitsound_kat_1p', 1.0)
|
||||
audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound) / "don_2p.wav", 'hitsound_don_2p')
|
||||
audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound) / "ka_2p.wav", 'hitsound_kat_2p')
|
||||
audio.set_sound_pan('hitsound_don_2p', 0.0)
|
||||
audio.set_sound_pan('hitsound_kat_2p', 0.0)
|
||||
elif global_data.hit_sound[0] == 0:
|
||||
audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[0]) / "don.wav", 'hitsound_don_1p')
|
||||
audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[0]) / "ka.wav", 'hitsound_kat_1p')
|
||||
else:
|
||||
audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound) / "don.ogg", 'hitsound_don_1p')
|
||||
audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound) / "ka.ogg", 'hitsound_kat_1p')
|
||||
audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[0]) / "don.ogg", 'hitsound_don_1p')
|
||||
audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[0]) / "ka.ogg", 'hitsound_kat_1p')
|
||||
audio.set_sound_pan('hitsound_don_1p', 1.0)
|
||||
audio.set_sound_pan('hitsound_kat_1p', 1.0)
|
||||
|
||||
def init_tja(self, song: Path, difficulty: int):
|
||||
# Load hitsounds for 2P
|
||||
if global_data.hit_sound[1] == -1:
|
||||
audio.load_sound(Path('none.wav'), 'hitsound_don_2p')
|
||||
audio.load_sound(Path('none.wav'), 'hitsound_kat_2p')
|
||||
elif global_data.hit_sound[1] == 0:
|
||||
audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[1]) / "don_2p.wav", 'hitsound_don_2p')
|
||||
audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[1]) / "ka_2p.wav", 'hitsound_kat_2p')
|
||||
else:
|
||||
audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[1]) / "don.ogg", 'hitsound_don_2p')
|
||||
audio.load_sound(sounds_dir / "hit_sounds" / str(global_data.hit_sound[1]) / "ka.ogg", 'hitsound_kat_2p')
|
||||
audio.set_sound_pan('hitsound_don_2p', 0.0)
|
||||
audio.set_sound_pan('hitsound_kat_2p', 0.0)
|
||||
|
||||
def global_keys(self):
|
||||
if ray.is_key_pressed(ray.KeyboardKey.KEY_F1):
|
||||
if self.song_music is not None:
|
||||
audio.stop_music_stream(self.song_music)
|
||||
self.init_tja(global_data.selected_song)
|
||||
audio.play_sound('restart', 'sound')
|
||||
self.song_started = False
|
||||
|
||||
if ray.is_key_pressed(ray.KeyboardKey.KEY_ESCAPE):
|
||||
if self.song_music is not None:
|
||||
audio.stop_music_stream(self.song_music)
|
||||
return self.on_screen_end('SONG_SELECT_2P')
|
||||
|
||||
def init_tja(self, song: Path):
|
||||
"""Initialize the TJA file"""
|
||||
self.tja = TJAParser(song, start_delay=self.start_delay, distance=SCREEN_WIDTH - GameScreen.JUDGE_X)
|
||||
if self.tja.metadata.bgmovie != Path() and self.tja.metadata.bgmovie.exists():
|
||||
@@ -44,24 +69,28 @@ class TwoPlayerGameScreen(GameScreen):
|
||||
self.movie.set_volume(0.0)
|
||||
else:
|
||||
self.movie = None
|
||||
session_data.song_title = self.tja.metadata.title.get(global_data.config['general']['language'].lower(), self.tja.metadata.title['en'])
|
||||
global_data.session_data[0].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, 'song')
|
||||
|
||||
tja_copy = copy.deepcopy(self.tja)
|
||||
self.player_1 = Player(self.tja, 1, difficulty, False, global_data.modifiers)
|
||||
self.player_2 = Player(tja_copy, 2, difficulty-1, True, Modifiers())
|
||||
self.player_1 = Player(self.tja, 1, global_data.session_data[0].selected_difficulty, False, global_data.modifiers[0])
|
||||
self.player_2 = Player(tja_copy, 2, global_data.session_data[1].selected_difficulty, True, global_data.modifiers[1])
|
||||
self.start_ms = (get_current_ms() - self.tja.metadata.offset*1000)
|
||||
|
||||
def spawn_ending_anims(self):
|
||||
if session_data.result_bad == 0:
|
||||
if global_data.session_data[0].result_bad == 0:
|
||||
self.player_1.ending_anim = FCAnimation(self.player_1.is_2p)
|
||||
self.player_2.ending_anim = FCAnimation(self.player_2.is_2p)
|
||||
elif self.player_1.gauge.is_clear:
|
||||
self.player_1.ending_anim = ClearAnimation(self.player_1.is_2p)
|
||||
self.player_2.ending_anim = ClearAnimation(self.player_2.is_2p)
|
||||
elif not self.player_1.gauge.is_clear:
|
||||
self.player_1.ending_anim = FailAnimation(self.player_1.is_2p)
|
||||
|
||||
if global_data.session_data[1].result_bad == 0:
|
||||
self.player_2.ending_anim = FCAnimation(self.player_2.is_2p)
|
||||
elif self.player_2.gauge.is_clear:
|
||||
self.player_2.ending_anim = ClearAnimation(self.player_2.is_2p)
|
||||
elif not self.player_2.gauge.is_clear:
|
||||
self.player_2.ending_anim = FailAnimation(self.player_2.is_2p)
|
||||
|
||||
def update(self):
|
||||
@@ -80,10 +109,14 @@ class TwoPlayerGameScreen(GameScreen):
|
||||
self.song_info.update(current_time)
|
||||
self.result_transition.update(current_time)
|
||||
if self.result_transition.is_finished and not audio.is_sound_playing('result_transition'):
|
||||
return self.on_screen_end('RESULT')
|
||||
return self.on_screen_end('RESULT_2P')
|
||||
elif self.current_ms >= self.player_1.end_time:
|
||||
session_data = global_data.session_data[0]
|
||||
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()
|
||||
session_data.result_gauge_length = self.player_1.gauge.gauge_length
|
||||
session_data = global_data.session_data[1]
|
||||
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_2.get_result_score()
|
||||
session_data.result_gauge_length = self.player_2.gauge.gauge_length
|
||||
if self.end_ms != 0:
|
||||
if current_time >= self.end_ms + 1000:
|
||||
if self.player_1.ending_anim is None:
|
||||
|
||||
36
scenes/two_player/result.py
Normal file
36
scenes/two_player/result.py
Normal file
@@ -0,0 +1,36 @@
|
||||
from libs.utils import get_current_ms
|
||||
from scenes.result import Background, FadeIn, ResultPlayer, ResultScreen
|
||||
|
||||
class TwoPlayerResultScreen(ResultScreen):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def on_screen_start(self):
|
||||
if not self.screen_init:
|
||||
super().on_screen_start()
|
||||
self.background = Background('3', self.width)
|
||||
self.fade_in = FadeIn('3')
|
||||
self.player_1 = ResultPlayer('1', True, False)
|
||||
self.player_2 = ResultPlayer('2', True, True)
|
||||
|
||||
def update(self):
|
||||
self.on_screen_start()
|
||||
current_time = get_current_ms()
|
||||
self.fade_in.update(current_time)
|
||||
self.player_1.update(current_time, self.fade_in.is_finished, self.is_skipped)
|
||||
self.player_2.update(current_time, self.fade_in.is_finished, self.is_skipped)
|
||||
|
||||
if current_time >= self.start_ms + 5000 and not self.fade_out.is_started:
|
||||
self.handle_input()
|
||||
|
||||
self.fade_out.update(current_time)
|
||||
if self.fade_out.is_finished:
|
||||
self.fade_out.update(current_time)
|
||||
return self.on_screen_end("SONG_SELECT_2P")
|
||||
|
||||
def draw(self):
|
||||
self.background.draw()
|
||||
self.draw_song_info()
|
||||
self.player_1.draw()
|
||||
self.player_2.draw()
|
||||
self.draw_overlay()
|
||||
166
scenes/two_player/song_select.py
Normal file
166
scenes/two_player/song_select.py
Normal file
@@ -0,0 +1,166 @@
|
||||
from libs.file_navigator import SongFile
|
||||
from libs.transition import Transition
|
||||
from scenes.song_select import DiffSortSelect, SongSelectPlayer, SongSelectScreen, State
|
||||
from libs.utils import get_current_ms, global_data
|
||||
from libs.audio import audio
|
||||
|
||||
class TwoPlayerSongSelectScreen(SongSelectScreen):
|
||||
def on_screen_start(self):
|
||||
if not self.screen_init:
|
||||
super().on_screen_start()
|
||||
self.player_1 = SongSelectPlayer('1', self.text_fade_in)
|
||||
self.player_2 = SongSelectPlayer('2', self.text_fade_in)
|
||||
|
||||
def finalize_song(self):
|
||||
global_data.selected_song = self.navigator.get_current_item().path
|
||||
global_data.session_data[0].genre_index = self.navigator.get_current_item().box.name_texture_index
|
||||
|
||||
def handle_input_browsing(self):
|
||||
"""Handle input for browsing songs."""
|
||||
action = self.player_1.handle_input_browsing(self.last_moved, self.navigator.items[self.navigator.selected_index] if self.navigator.items else None)
|
||||
if action is None:
|
||||
action = self.player_2.handle_input_browsing(self.last_moved, self.navigator.items[self.navigator.selected_index] if self.navigator.items else None)
|
||||
if action is None:
|
||||
return
|
||||
|
||||
current_time = get_current_ms()
|
||||
if action == "skip_left":
|
||||
self.reset_demo_music()
|
||||
for _ in range(10):
|
||||
self.navigator.navigate_left()
|
||||
self.last_moved = current_time
|
||||
elif action == "skip_right":
|
||||
self.reset_demo_music()
|
||||
for _ in range(10):
|
||||
self.navigator.navigate_right()
|
||||
self.last_moved = current_time
|
||||
elif action == "navigate_left":
|
||||
self.reset_demo_music()
|
||||
self.navigator.navigate_left()
|
||||
self.last_moved = current_time
|
||||
elif action == "navigate_right":
|
||||
self.reset_demo_music()
|
||||
self.navigator.navigate_right()
|
||||
self.last_moved = current_time
|
||||
elif action == "go_back":
|
||||
self.navigator.go_back()
|
||||
elif action == "diff_sort":
|
||||
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)
|
||||
self.text_fade_in.start()
|
||||
self.text_fade_out.start()
|
||||
elif action == "select_song":
|
||||
selected_song = self.navigator.select_current_item()
|
||||
if selected_song:
|
||||
self.state = State.SONG_SELECTED
|
||||
self.player_1.on_song_selected(selected_song)
|
||||
audio.play_sound('don', 'sound')
|
||||
audio.play_sound('voice_select_diff', 'voice')
|
||||
self.move_away.start()
|
||||
self.diff_fade_out.start()
|
||||
self.text_fade_out.start()
|
||||
self.text_fade_in.start()
|
||||
self.player_1.selected_diff_bounce.start()
|
||||
self.player_1.selected_diff_fadein.start()
|
||||
self.player_2.selected_diff_bounce.start()
|
||||
self.player_2.selected_diff_fadein.start()
|
||||
elif action == "add_favorite":
|
||||
self.navigator.add_favorite()
|
||||
current_box = self.navigator.get_current_item().box
|
||||
current_box.is_favorite = not current_box.is_favorite
|
||||
|
||||
def handle_input_selected(self):
|
||||
"""Handle input for selecting difficulty."""
|
||||
p2_result = False
|
||||
result = self.player_1.handle_input_selected(self.navigator.get_current_item())
|
||||
if result is None:
|
||||
result = self.player_2.handle_input_selected(self.navigator.get_current_item())
|
||||
if result is None:
|
||||
return
|
||||
p2_result = True
|
||||
if result is not None:
|
||||
print(result, p2_result)
|
||||
if result == "cancel":
|
||||
self._cancel_selection()
|
||||
elif result == "confirm":
|
||||
if p2_result:
|
||||
self._confirm_selection(2)
|
||||
else:
|
||||
self._confirm_selection(1)
|
||||
elif result == "ura_toggle":
|
||||
if p2_result:
|
||||
self.ura_switch_animation.start(not self.player_2.is_ura)
|
||||
else:
|
||||
self.ura_switch_animation.start(not self.player_1.is_ura)
|
||||
|
||||
def handle_input_diff_sort(self):
|
||||
"""
|
||||
Handle input for sorting difficulty.
|
||||
"""
|
||||
if self.diff_sort_selector is None:
|
||||
raise Exception("Diff sort selector was not able to be created")
|
||||
|
||||
result = self.player_1.handle_input_diff_sort(self.diff_sort_selector)
|
||||
|
||||
if result is not None:
|
||||
diff, level = result
|
||||
self.diff_sort_selector = None
|
||||
self.state = State.BROWSING
|
||||
self.text_fade_out.reset()
|
||||
self.text_fade_in.reset()
|
||||
if diff != -1:
|
||||
if level != -1:
|
||||
self.navigator.diff_sort_diff = diff
|
||||
self.navigator.diff_sort_level = level
|
||||
self.navigator.select_current_item()
|
||||
|
||||
def _cancel_selection(self):
|
||||
"""Reset to browsing state"""
|
||||
super()._cancel_selection()
|
||||
self.player_2.selected_song = None
|
||||
|
||||
def _confirm_selection(self, player_selected: int):
|
||||
"""Confirm song selection and create game transition"""
|
||||
audio.play_sound('don', 'sound')
|
||||
audio.play_sound(f'voice_start_song_{global_data.player_num}p', 'voice')
|
||||
if player_selected == 1:
|
||||
global_data.session_data[0].selected_difficulty = self.player_1.selected_difficulty
|
||||
self.player_1.selected_diff_highlight_fade.start()
|
||||
self.player_1.selected_diff_text_resize.start()
|
||||
self.player_1.selected_diff_text_fadein.start()
|
||||
elif player_selected == 2:
|
||||
global_data.session_data[1].selected_difficulty = self.player_2.selected_difficulty
|
||||
self.player_2.selected_diff_highlight_fade.start()
|
||||
self.player_2.selected_diff_text_resize.start()
|
||||
self.player_2.selected_diff_text_fadein.start()
|
||||
|
||||
def check_for_selection(self):
|
||||
if (self.player_1.selected_diff_highlight_fade.is_finished and
|
||||
self.player_2.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")
|
||||
|
||||
title = selected_song.tja.metadata.title.get(
|
||||
global_data.config['general']['language'], '')
|
||||
subtitle = selected_song.tja.metadata.subtitle.get(
|
||||
global_data.config['general']['language'], '')
|
||||
self.game_transition = Transition(title, subtitle)
|
||||
self.game_transition.start()
|
||||
|
||||
def update_players(self, current_time):
|
||||
self.player_1.update(current_time)
|
||||
self.player_2.update(current_time)
|
||||
if self.text_fade_out.is_finished:
|
||||
self.player_1.selected_song = True
|
||||
self.player_2.selected_song = True
|
||||
return "GAME_2P"
|
||||
|
||||
def draw_background_diffs(self):
|
||||
self.player_1.draw_background_diffs(self.state)
|
||||
self.player_2.draw_background_diffs(self.state)
|
||||
|
||||
def draw_players(self):
|
||||
self.player_1.draw(self.state)
|
||||
self.player_2.draw(self.state)
|
||||
Reference in New Issue
Block a user