mirror of
https://github.com/Yonokid/PyTaiko.git
synced 2026-02-04 11:40:13 +01:00
slowly updating the animation library
This commit is contained in:
27
.github/workflows/python-app.yml
vendored
27
.github/workflows/python-app.yml
vendored
@@ -58,16 +58,17 @@ jobs:
|
||||
*.bin
|
||||
*.app/**/*
|
||||
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
repository: yonokid/PyTaiko
|
||||
files: |
|
||||
Graphics/*
|
||||
Sounds/*
|
||||
Videos/*
|
||||
config.toml
|
||||
*.exe
|
||||
*.bin
|
||||
*.app/**/*
|
||||
tag_name: 0.0.3
|
||||
# - name: Release
|
||||
# uses: softprops/action-gh-release@v2
|
||||
# with:
|
||||
# repository: yonokid/PyTaiko
|
||||
# files: |
|
||||
# Graphics/*
|
||||
# Sounds/*
|
||||
# Videos/*
|
||||
# config.toml
|
||||
# *.exe
|
||||
# *.bin
|
||||
# *.app/**/*
|
||||
# tag_name: 0.0.3
|
||||
# make_latest: true
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
from typing import Optional
|
||||
|
||||
from libs.utils import get_current_ms
|
||||
|
||||
|
||||
class Animation:
|
||||
def __init__(self, current_ms: float, duration: float, type: str):
|
||||
self.type = type
|
||||
@@ -8,23 +13,7 @@ class Animation:
|
||||
self.is_finished = False
|
||||
|
||||
def update(self, current_ms: float):
|
||||
if self.type == 'fade':
|
||||
self.fade(current_ms,
|
||||
self.duration,
|
||||
initial_opacity=self.params.get('initial_opacity', 1.0),
|
||||
final_opacity=self.params.get('final_opacity', 0.0),
|
||||
delay=self.params.get('delay', 0.0),
|
||||
ease_in=self.params.get('ease_in', None),
|
||||
ease_out=self.params.get('ease_out', None))
|
||||
if self.params.get('reverse', None) is not None and current_ms - self.start_ms >= self.duration + self.params.get('delay', 0.0):
|
||||
self.fade(current_ms,
|
||||
self.duration,
|
||||
final_opacity=self.params.get('initial_opacity', 1.0),
|
||||
initial_opacity=self.params.get('final_opacity', 0.0),
|
||||
delay=self.params.get('delay', 0.0) + self.duration + self.params.get('reverse'),
|
||||
ease_in=self.params.get('ease_in', None),
|
||||
ease_out=self.params.get('ease_out', None))
|
||||
elif self.type == 'move':
|
||||
if self.type == 'move':
|
||||
self.move(current_ms,
|
||||
self.duration,
|
||||
self.params['total_distance'],
|
||||
@@ -71,25 +60,6 @@ class Animation:
|
||||
else:
|
||||
return progress
|
||||
|
||||
def fade(self, current_ms: float, duration: float, initial_opacity: float, final_opacity: float, delay: float, ease_in: str | None, ease_out: str | None) -> None:
|
||||
elapsed_time = current_ms - self.start_ms
|
||||
if elapsed_time < delay:
|
||||
self.attribute = initial_opacity
|
||||
|
||||
elapsed_time -= delay
|
||||
if elapsed_time >= duration:
|
||||
self.attribute = final_opacity
|
||||
self.is_finished = True
|
||||
|
||||
if ease_in is not None:
|
||||
progress = self._ease_in_progress(elapsed_time / duration, ease_in)
|
||||
elif ease_out is not None:
|
||||
progress = self._ease_out_progress(elapsed_time / duration, ease_out)
|
||||
else:
|
||||
progress = elapsed_time / duration
|
||||
|
||||
current_opacity = initial_opacity + (final_opacity - initial_opacity) * progress
|
||||
self.attribute = current_opacity
|
||||
def move(self, current_ms: float, duration: float, total_distance: float, start_position: float, delay: float, ease_in: str | None, ease_out: str | None) -> None:
|
||||
elapsed_time = current_ms - self.start_ms
|
||||
if elapsed_time < delay:
|
||||
@@ -139,3 +109,137 @@ class Animation:
|
||||
else:
|
||||
self.attribute = final_size
|
||||
self.is_finished = True
|
||||
|
||||
class BaseAnimation():
|
||||
def __init__(self, duration: float, delay: float = 0.0):
|
||||
"""
|
||||
Initialize a base animation.
|
||||
|
||||
Args:
|
||||
duration: Length of the animation in milliseconds
|
||||
delay: Time to wait before starting the animation
|
||||
reverse_delay: If provided, animation will play in reverse after this delay
|
||||
"""
|
||||
self.duration = duration
|
||||
self.delay = delay
|
||||
self.start_ms = get_current_ms()
|
||||
self.is_finished = False
|
||||
self.attribute = 0
|
||||
|
||||
def update(self, current_time_ms: float) -> None:
|
||||
"""Update the animation based on the current time."""
|
||||
pass
|
||||
|
||||
def _ease_in(self, progress: float, ease_type: str) -> float:
|
||||
if ease_type == "quadratic":
|
||||
return progress * progress
|
||||
elif ease_type == "cubic":
|
||||
return progress * progress * progress
|
||||
elif ease_type == "exponential":
|
||||
return 0 if progress == 0 else pow(2, 10 * (progress - 1))
|
||||
return progress
|
||||
|
||||
def _ease_out(self, progress: float, ease_type: str) -> float:
|
||||
if ease_type == "quadratic":
|
||||
return progress * (2 - progress)
|
||||
elif ease_type == "cubic":
|
||||
return 1 - pow(1 - progress, 3)
|
||||
elif ease_type == "exponential":
|
||||
return 1 if progress == 1 else 1 - pow(2, -10 * progress)
|
||||
return progress
|
||||
|
||||
def _apply_easing(self, progress: float, ease_in: Optional[str] = None,
|
||||
ease_out: Optional[str] = None) -> float:
|
||||
if ease_in:
|
||||
return self._ease_in(progress, ease_in)
|
||||
elif ease_out:
|
||||
return self._ease_out(progress, ease_out)
|
||||
return progress
|
||||
|
||||
class FadeAnimation(BaseAnimation):
|
||||
def __init__(self, duration: float, initial_opacity: float = 1.0,
|
||||
final_opacity: float = 0.0, delay: float = 0.0,
|
||||
ease_in: Optional[str] = None, ease_out: Optional[str] = None,
|
||||
reverse_delay: Optional[float] = None):
|
||||
super().__init__(duration, delay)
|
||||
self.initial_opacity = initial_opacity
|
||||
self.final_opacity = final_opacity
|
||||
self.ease_in = ease_in
|
||||
self.ease_out = ease_out
|
||||
self.reverse_delay = reverse_delay
|
||||
|
||||
def update(self, current_time_ms: float):
|
||||
elapsed_time = current_time_ms - self.start_ms
|
||||
|
||||
if elapsed_time <= self.delay:
|
||||
self.attribute = self.initial_opacity
|
||||
elif elapsed_time >= self.delay + self.duration:
|
||||
self.attribute = self.final_opacity
|
||||
|
||||
if self.reverse_delay is not None:
|
||||
self.start_ms = current_time_ms
|
||||
self.delay = self.reverse_delay
|
||||
self.initial_opacity, self.final_opacity = self.final_opacity, self.initial_opacity
|
||||
self.reverse_delay = None
|
||||
else:
|
||||
self.is_finished = True
|
||||
else:
|
||||
animation_time = elapsed_time - self.delay
|
||||
progress = animation_time / self.duration
|
||||
progress = max(0.0, min(1.0, progress))
|
||||
progress = self._apply_easing(progress, self.ease_in, self.ease_out)
|
||||
self.attribute = self.initial_opacity + progress * (self.final_opacity - self.initial_opacity)
|
||||
|
||||
class MoveAnimation(BaseAnimation):
|
||||
def __init__(self, duration: float, total_distance: int = 0,
|
||||
start_position: int = 0, delay: float = 0.0,
|
||||
ease_in: Optional[str] = None, ease_out: Optional[str] = None):
|
||||
super().__init__(duration, delay)
|
||||
self.total_distance = total_distance
|
||||
self.start_position = start_position
|
||||
self.ease_in = ease_in
|
||||
self.ease_out = ease_out
|
||||
|
||||
def update(self, current_time_ms: float):
|
||||
elapsed_time = current_time_ms - self.start_ms
|
||||
if elapsed_time < self.delay:
|
||||
self.attribute = self.start_position
|
||||
|
||||
elif elapsed_time >= self.delay + self.duration:
|
||||
self.attribute = self.start_position + self.total_distance
|
||||
self.is_finished = True
|
||||
else:
|
||||
progress = (elapsed_time - self.delay) / self.duration
|
||||
progress = self._apply_easing(progress, self.ease_in, self.ease_out)
|
||||
self.attribute = self.start_position + (self.total_distance * progress)
|
||||
|
||||
|
||||
class Animation2:
|
||||
"""Factory for creating different types of animations."""
|
||||
|
||||
@staticmethod
|
||||
def create_fade(duration: float, **kwargs) -> FadeAnimation:
|
||||
"""Create a fade animation."""
|
||||
return FadeAnimation(duration, **kwargs)
|
||||
|
||||
@staticmethod
|
||||
def create_move(duration: float, **kwargs) -> MoveAnimation:
|
||||
"""Create a movement animation."""
|
||||
return MoveAnimation(duration, **kwargs)
|
||||
'''
|
||||
|
||||
@staticmethod
|
||||
def create_texture_change(duration: float, **kwargs) -> TextureChangeAnimation:
|
||||
"""Create a texture change animation."""
|
||||
return TextureChangeAnimation(duration, **kwargs)
|
||||
|
||||
@staticmethod
|
||||
def create_text_stretch(duration: float) -> TextStretchAnimation:
|
||||
"""Create a text stretch animation."""
|
||||
return TextStretchAnimation(duration)
|
||||
|
||||
@staticmethod
|
||||
def create_texture_resize(duration: float, **kwargs) -> TextureResizeAnimation:
|
||||
"""Create a texture resize animation."""
|
||||
return TextureResizeAnimation(duration, **kwargs)
|
||||
'''
|
||||
|
||||
@@ -365,6 +365,7 @@ class TJAParser:
|
||||
note.type = int(item)
|
||||
note.pixels_per_frame = bar.pixels_per_frame
|
||||
note.index = index
|
||||
note.moji = -1
|
||||
if item in {'5', '6'}:
|
||||
note = Drumroll(note)
|
||||
note.color = 255
|
||||
|
||||
329
scenes/game.py
329
scenes/game.py
@@ -1,11 +1,11 @@
|
||||
import bisect
|
||||
import math
|
||||
from collections import deque
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
import pyray as ray
|
||||
|
||||
from libs.animation import Animation
|
||||
from libs.animation import Animation, Animation2
|
||||
from libs.audio import audio
|
||||
from libs.tja import Balloon, Drumroll, Note, TJAParser, calculate_base_score
|
||||
from libs.utils import (
|
||||
@@ -108,12 +108,11 @@ class GameScreen:
|
||||
else:
|
||||
self.movie = None
|
||||
self.tja.distance = self.width - self.judge_x
|
||||
self.start_delay = 0
|
||||
session_data.song_title = self.tja.title
|
||||
|
||||
self.player_1 = Player(self, 1, difficulty, metadata, get_config()["general"]["judge_offset"])
|
||||
self.song_music = audio.load_sound(str(Path(self.tja.wave)))
|
||||
self.start_ms = (get_current_ms() - self.tja.offset*1000) + self.start_delay
|
||||
self.start_ms = (get_current_ms() - self.tja.offset*1000)
|
||||
|
||||
audio.play_sound(self.song_music)
|
||||
|
||||
@@ -136,23 +135,22 @@ class GameScreen:
|
||||
|
||||
def update(self):
|
||||
self.on_screen_start()
|
||||
self.current_ms = get_current_ms() - self.start_ms
|
||||
if self.movie is not None:
|
||||
self.movie.update()
|
||||
|
||||
self.current_ms = get_current_ms() - self.start_ms
|
||||
|
||||
self.player_1.update(self)
|
||||
if self.song_info is not None:
|
||||
self.song_info.update(self.current_ms)
|
||||
self.song_info.update(get_current_ms())
|
||||
|
||||
if self.result_transition is not None:
|
||||
self.result_transition.update(self.current_ms)
|
||||
self.result_transition.update(get_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):
|
||||
elif len(self.player_1.play_notes) == 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
|
||||
self.result_transition = ResultTransition(self.current_ms, self.height)
|
||||
self.result_transition = ResultTransition(get_current_ms(), self.height)
|
||||
audio.play_sound(self.sound_result_transition)
|
||||
|
||||
def draw(self):
|
||||
@@ -166,28 +164,24 @@ class GameScreen:
|
||||
|
||||
|
||||
class Player:
|
||||
TIMING_GOOD = 25.0250015258789
|
||||
TIMING_OK = 75.0750045776367
|
||||
TIMING_BAD = 108.441665649414
|
||||
|
||||
def __init__(self, game_screen: GameScreen, player_number: int, difficulty: int, metadata, judge_offset: int):
|
||||
self.timing_good = 25.0250015258789
|
||||
self.timing_ok = 75.0750045776367
|
||||
self.timing_bad = 108.441665649414
|
||||
|
||||
self.player_number = player_number
|
||||
self.difficulty = difficulty
|
||||
|
||||
self.play_note_list, self.draw_note_list, self.draw_bar_list = game_screen.tja.notes_to_position(self.difficulty)
|
||||
self.total_notes = len([note for note in self.play_note_list if 0 < note.type < 5])
|
||||
print(self.total_notes)
|
||||
self.base_score = calculate_base_score(self.play_note_list)
|
||||
self.play_notes, self.draw_note_list, self.draw_bar_list = game_screen.tja.notes_to_position(self.difficulty)
|
||||
self.total_notes = len([note for note in self.play_notes if 0 < note.type < 5])
|
||||
self.base_score = calculate_base_score(self.play_notes)
|
||||
|
||||
self.judge_offset = judge_offset
|
||||
|
||||
#Note management
|
||||
self.current_notes: deque[Note | Drumroll | Balloon] = deque()
|
||||
self.current_bars: list[Note] = []
|
||||
self.current_notes_draw: list[Note | Drumroll | Balloon] = []
|
||||
self.play_note_index = 0
|
||||
self.draw_note_index = 0
|
||||
self.bar_index = 0
|
||||
self.is_drumroll = False
|
||||
self.curr_drumroll_count = 0
|
||||
self.is_balloon = False
|
||||
@@ -206,18 +200,18 @@ class Player:
|
||||
self.arc_points = 25
|
||||
|
||||
self.draw_judge_list: list[Judgement] = []
|
||||
self.lane_hit_effect: LaneHitEffect | None = None
|
||||
self.lane_hit_effect: Optional[LaneHitEffect] = None
|
||||
self.draw_arc_list: list[NoteArc] = []
|
||||
self.draw_drum_hit_list: list[DrumHitEffect] = []
|
||||
self.drumroll_counter: DrumrollCounter | None = None
|
||||
self.balloon_anim: BalloonAnimation | None = None
|
||||
self.drumroll_counter: Optional[DrumrollCounter] = None
|
||||
self.balloon_anim: Optional[BalloonAnimation] = None
|
||||
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.combo_display = Combo(self.combo, get_current_ms())
|
||||
self.score_counter = ScoreCounter(self.score, get_current_ms())
|
||||
|
||||
self.input_log: dict[float, str] = dict()
|
||||
self.input_log: dict[float, tuple] = dict()
|
||||
|
||||
self.gauge = Gauge(game_screen.current_ms, self.difficulty, metadata[-1][self.difficulty][0])
|
||||
self.gauge = Gauge(get_current_ms(), self.difficulty, metadata[-1][self.difficulty][0])
|
||||
|
||||
def get_result_score(self):
|
||||
return self.score, self.good_count, self.ok_count, self.bad_count, self.total_drumroll, self.max_combo
|
||||
@@ -225,13 +219,13 @@ class Player:
|
||||
def get_position(self, game_screen: GameScreen, ms: float, pixels_per_frame: float) -> int:
|
||||
return int(game_screen.width + pixels_per_frame * 60 / 1000 * (ms - game_screen.current_ms + self.judge_offset) - 64)
|
||||
|
||||
def animation_manager(self, game_screen: GameScreen, animation_list: list):
|
||||
def animation_manager(self, animation_list: list):
|
||||
if len(animation_list) <= 0:
|
||||
return
|
||||
|
||||
for i in range(len(animation_list)-1, -1, -1):
|
||||
animation = animation_list[i]
|
||||
animation.update(game_screen.current_ms)
|
||||
animation.update(get_current_ms())
|
||||
if animation.is_finished:
|
||||
animation_list.pop(i)
|
||||
|
||||
@@ -251,45 +245,44 @@ class Player:
|
||||
self.current_bars.pop(i)
|
||||
|
||||
def play_note_manager(self, game_screen: GameScreen):
|
||||
#Add note to current_notes list if it is ready to be shown on screen
|
||||
if len(self.play_note_list) > 0 and game_screen.current_ms + 1000 >= self.play_note_list[0].load_ms:
|
||||
self.current_notes.append(self.play_note_list.popleft())
|
||||
if len(self.play_note_list) > 0 and self.play_note_list[0].type == 8:
|
||||
self.current_notes.append(self.play_note_list.popleft())
|
||||
|
||||
#if a note was not hit within the window, remove it
|
||||
if len(self.current_notes) == 0:
|
||||
if len(self.play_notes) == 0:
|
||||
return
|
||||
|
||||
note = self.current_notes[0]
|
||||
if note.hit_ms + self.timing_bad < game_screen.current_ms:
|
||||
note = self.play_notes[0]
|
||||
if note.hit_ms + Player.TIMING_BAD < game_screen.current_ms:
|
||||
if 0 < note.type <= 4:
|
||||
self.combo = 0
|
||||
self.bad_count += 1
|
||||
if note.type != 7:
|
||||
self.current_notes.popleft()
|
||||
if len(self.current_notes) > 2 and self.current_notes[1].type == 8 and self.current_notes[1].hit_ms + self.timing_bad < game_screen.current_ms:
|
||||
self.current_notes.popleft()
|
||||
self.play_notes.popleft()
|
||||
elif note.type != 8:
|
||||
tail = self.play_notes[1]
|
||||
if tail.hit_ms <= game_screen.current_ms:
|
||||
self.play_notes.popleft()
|
||||
self.play_notes.popleft()
|
||||
self.is_drumroll = False
|
||||
self.is_balloon = False
|
||||
self.current_notes.popleft()
|
||||
else:
|
||||
if len(self.play_notes) == 1:
|
||||
self.play_notes.popleft()
|
||||
elif (note.hit_ms <= game_screen.current_ms):
|
||||
if note.type == 5:
|
||||
self.is_drumroll = True
|
||||
elif note.type == 6:
|
||||
if note.type == 5 or note.type == 6:
|
||||
self.is_drumroll = True
|
||||
elif note.type == 7:
|
||||
self.is_balloon = True
|
||||
elif note.type == 8 and (self.is_drumroll):
|
||||
self.is_drumroll = False
|
||||
|
||||
def draw_note_manager(self, game_screen: GameScreen):
|
||||
if len(self.draw_note_list) > 0 and game_screen.current_ms + 1000 >= self.draw_note_list[0].load_ms:
|
||||
if self.draw_note_list[0].type in {5, 6, 7}:
|
||||
while self.draw_note_list[0].type != 8:
|
||||
bisect.insort_left(self.current_notes_draw, self.draw_note_list.popleft(), key=lambda x: x.index)
|
||||
bisect.insort_left(self.current_notes_draw, self.draw_note_list.popleft(), key=lambda x: x.index)
|
||||
current_note = self.draw_note_list.popleft()
|
||||
if 5 <= current_note.type <= 7:
|
||||
bisect.insort_left(self.current_notes_draw, current_note, key=lambda x: x.index)
|
||||
try:
|
||||
tail_note = next(note for note in self.draw_note_list if note.index == current_note.index+1)
|
||||
bisect.insort_left(self.current_notes_draw, tail_note, key=lambda x: x.index)
|
||||
self.draw_note_list.remove(tail_note)
|
||||
except Exception as e:
|
||||
raise(e)
|
||||
else:
|
||||
bisect.insort_left(self.current_notes_draw, self.draw_note_list.popleft(), key=lambda x: x.index)
|
||||
bisect.insort_left(self.current_notes_draw, current_note, key=lambda x: x.index)
|
||||
|
||||
if len(self.current_notes_draw) == 0:
|
||||
return
|
||||
@@ -310,6 +303,7 @@ class Player:
|
||||
self.draw_note_manager(game_screen)
|
||||
|
||||
def note_correct(self, game_screen: GameScreen, note: Note):
|
||||
self.play_notes.popleft()
|
||||
index = note.index
|
||||
if note.type == 7:
|
||||
note_type = game_screen.note_type_list[3][0]
|
||||
@@ -320,8 +314,7 @@ class Player:
|
||||
if self.combo > self.max_combo:
|
||||
self.max_combo = self.combo
|
||||
|
||||
self.draw_arc_list.append(NoteArc(note_type, game_screen.current_ms, self.player_number))
|
||||
self.current_notes.popleft()
|
||||
self.draw_arc_list.append(NoteArc(note_type, get_current_ms(), self.player_number))
|
||||
|
||||
if note in self.current_notes_draw:
|
||||
index = self.current_notes_draw.index(note)
|
||||
@@ -329,11 +322,11 @@ class Player:
|
||||
|
||||
def check_drumroll(self, game_screen: GameScreen, drum_type: int):
|
||||
note_type = game_screen.note_type_list[drum_type][0]
|
||||
self.draw_arc_list.append(NoteArc(note_type, game_screen.current_ms, self.player_number))
|
||||
self.draw_arc_list.append(NoteArc(note_type, get_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))
|
||||
self.base_score_list.append(ScoreCounterAnimation(get_current_ms(), 100))
|
||||
if not isinstance(self.current_notes_draw[0], Drumroll):
|
||||
return
|
||||
self.current_notes_draw[0].color = max(0, 255 - (self.curr_drumroll_count * 10))
|
||||
@@ -342,23 +335,23 @@ class Player:
|
||||
if drum_type != 1:
|
||||
return
|
||||
if self.balloon_anim is None:
|
||||
self.balloon_anim = BalloonAnimation(game_screen.current_ms, note.count)
|
||||
self.balloon_anim = BalloonAnimation(get_current_ms(), note.count)
|
||||
self.curr_balloon_count += 1
|
||||
self.total_drumroll += 1
|
||||
self.score += 100
|
||||
self.base_score_list.append(ScoreCounterAnimation(game_screen.current_ms, 100))
|
||||
self.base_score_list.append(ScoreCounterAnimation(get_current_ms(), 100))
|
||||
if self.curr_balloon_count == note.count:
|
||||
self.is_balloon = False
|
||||
note.popped = True
|
||||
self.balloon_anim.update(game_screen, game_screen.current_ms, self.curr_balloon_count, note.popped)
|
||||
self.balloon_anim.update(game_screen, get_current_ms(), self.curr_balloon_count, note.popped)
|
||||
audio.play_sound(game_screen.sound_balloon_pop)
|
||||
self.note_correct(game_screen, self.current_notes[0])
|
||||
self.note_correct(game_screen, self.play_notes[0])
|
||||
|
||||
def check_note(self, game_screen: GameScreen, drum_type: int):
|
||||
if len(self.current_notes) == 0:
|
||||
if len(self.play_notes) == 0:
|
||||
return
|
||||
|
||||
curr_note = self.current_notes[0]
|
||||
curr_note = self.play_notes[0]
|
||||
if self.is_drumroll:
|
||||
self.check_drumroll(game_screen, drum_type)
|
||||
elif self.is_balloon:
|
||||
@@ -369,7 +362,7 @@ class Player:
|
||||
self.curr_drumroll_count = 0
|
||||
self.curr_balloon_count = 0
|
||||
curr_note = next(
|
||||
(note for note in self.current_notes if note.type not in {5, 6, 7, 8}),
|
||||
(note for note in self.play_notes if note.type not in {5, 6, 7, 8}),
|
||||
None # Default if no matching note is found
|
||||
)
|
||||
if curr_note is None:
|
||||
@@ -380,95 +373,81 @@ class Player:
|
||||
if drum_type == 2 and curr_note.type not in {2, 4}:
|
||||
return
|
||||
#If the note is too far away, stop checking
|
||||
if game_screen.current_ms > (curr_note.hit_ms + self.timing_bad):
|
||||
if game_screen.current_ms > (curr_note.hit_ms + Player.TIMING_BAD):
|
||||
return
|
||||
big = curr_note.type in {3,4}
|
||||
if (curr_note.hit_ms - self.timing_good) + self.judge_offset <= game_screen.current_ms <= (curr_note.hit_ms + self.timing_good) + self.judge_offset:
|
||||
self.draw_judge_list.append(Judgement(game_screen.current_ms, 'GOOD', big))
|
||||
self.lane_hit_effect = LaneHitEffect(game_screen.current_ms, 'GOOD')
|
||||
big = curr_note.type == 3 or curr_note.type == 4
|
||||
if (curr_note.hit_ms - Player.TIMING_GOOD) + self.judge_offset <= game_screen.current_ms <= (curr_note.hit_ms + Player.TIMING_GOOD) + self.judge_offset:
|
||||
self.draw_judge_list.append(Judgement(get_current_ms(), 'GOOD', big))
|
||||
self.lane_hit_effect = LaneHitEffect(get_current_ms(), 'GOOD')
|
||||
self.good_count += 1
|
||||
self.score += self.base_score
|
||||
self.base_score_list.append(ScoreCounterAnimation(game_screen.current_ms, self.base_score))
|
||||
self.base_score_list.append(ScoreCounterAnimation(get_current_ms(), self.base_score))
|
||||
self.note_correct(game_screen, curr_note)
|
||||
|
||||
elif (curr_note.hit_ms - self.timing_ok) + self.judge_offset <= game_screen.current_ms <= (curr_note.hit_ms + self.timing_ok) + self.judge_offset:
|
||||
self.draw_judge_list.append(Judgement(game_screen.current_ms, 'OK', big))
|
||||
elif (curr_note.hit_ms - Player.TIMING_OK) + self.judge_offset <= game_screen.current_ms <= (curr_note.hit_ms + Player.TIMING_OK) + self.judge_offset:
|
||||
self.draw_judge_list.append(Judgement(get_current_ms(), 'OK', big))
|
||||
self.ok_count += 1
|
||||
self.score += 10 * math.floor(self.base_score / 2 / 10)
|
||||
self.base_score_list.append(ScoreCounterAnimation(game_screen.current_ms, 10 * math.floor(self.base_score / 2 / 10)))
|
||||
self.base_score_list.append(ScoreCounterAnimation(get_current_ms(), 10 * math.floor(self.base_score / 2 / 10)))
|
||||
self.note_correct(game_screen, curr_note)
|
||||
|
||||
elif (curr_note.hit_ms - self.timing_bad) + self.judge_offset <= game_screen.current_ms <= (curr_note.hit_ms + self.timing_bad) + self.judge_offset:
|
||||
self.draw_judge_list.append(Judgement(game_screen.current_ms, 'BAD', big))
|
||||
elif (curr_note.hit_ms - Player.TIMING_BAD) + self.judge_offset <= game_screen.current_ms <= (curr_note.hit_ms + Player.TIMING_BAD) + self.judge_offset:
|
||||
self.draw_judge_list.append(Judgement(get_current_ms(), 'BAD', big))
|
||||
self.bad_count += 1
|
||||
self.combo = 0
|
||||
self.current_notes.popleft()
|
||||
self.play_notes.popleft()
|
||||
|
||||
def drumroll_counter_manager(self, game_screen: GameScreen):
|
||||
if self.is_drumroll and self.curr_drumroll_count > 0 and self.drumroll_counter is None:
|
||||
self.drumroll_counter = DrumrollCounter(game_screen.current_ms)
|
||||
self.drumroll_counter = DrumrollCounter(get_current_ms())
|
||||
|
||||
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)
|
||||
self.drumroll_counter.update(game_screen, get_current_ms(), self.curr_drumroll_count)
|
||||
|
||||
def balloon_manager(self, game_screen: GameScreen):
|
||||
if self.balloon_anim is not None:
|
||||
self.balloon_anim.update(game_screen, game_screen.current_ms, self.curr_balloon_count, not self.is_balloon)
|
||||
self.balloon_anim.update(game_screen, get_current_ms(), self.curr_balloon_count, not self.is_balloon)
|
||||
if self.balloon_anim.is_finished:
|
||||
self.balloon_anim = None
|
||||
|
||||
def key_manager(self, game_screen: GameScreen):
|
||||
left_kats = get_config()["keybinds"]["left_kat"]
|
||||
left_dons = get_config()["keybinds"]["left_don"]
|
||||
right_dons = get_config()["keybinds"]["right_don"]
|
||||
right_kats = get_config()["keybinds"]["right_kat"]
|
||||
for left_don in left_dons:
|
||||
if ray.is_key_pressed(ord(left_don)):
|
||||
self.lane_hit_effect = LaneHitEffect(game_screen.current_ms, 'DON')
|
||||
self.draw_drum_hit_list.append(DrumHitEffect(game_screen.current_ms, 'DON', 'L'))
|
||||
audio.play_sound(game_screen.sound_don)
|
||||
self.check_note(game_screen, 1)
|
||||
self.input_log[game_screen.current_ms] = 'DON'
|
||||
for right_don in right_dons:
|
||||
if ray.is_key_pressed(ord(right_don)):
|
||||
self.lane_hit_effect = LaneHitEffect(game_screen.current_ms, 'DON')
|
||||
self.draw_drum_hit_list.append(DrumHitEffect(game_screen.current_ms, 'DON', 'R'))
|
||||
audio.play_sound(game_screen.sound_don)
|
||||
self.check_note(game_screen, 1)
|
||||
self.input_log[game_screen.current_ms] = 'DON'
|
||||
for left_kat in left_kats:
|
||||
if ray.is_key_pressed(ord(left_kat)):
|
||||
self.lane_hit_effect = LaneHitEffect(game_screen.current_ms, 'KAT')
|
||||
self.draw_drum_hit_list.append(DrumHitEffect(game_screen.current_ms, 'KAT', 'L'))
|
||||
audio.play_sound(game_screen.sound_kat)
|
||||
self.check_note(game_screen, 2)
|
||||
self.input_log[game_screen.current_ms] = 'KAT'
|
||||
for right_kat in right_kats:
|
||||
if ray.is_key_pressed(ord(right_kat)):
|
||||
self.lane_hit_effect = LaneHitEffect(game_screen.current_ms, 'KAT')
|
||||
self.draw_drum_hit_list.append(DrumHitEffect(game_screen.current_ms, 'KAT', 'R'))
|
||||
audio.play_sound(game_screen.sound_kat)
|
||||
self.check_note(game_screen, 2)
|
||||
self.input_log[game_screen.current_ms] = 'KAT'
|
||||
key_configs = [
|
||||
{"keys": get_config()["keybinds"]["left_don"], "type": "DON", "side": "L", "note_type": 1},
|
||||
{"keys": get_config()["keybinds"]["right_don"], "type": "DON", "side": "R", "note_type": 1},
|
||||
{"keys": get_config()["keybinds"]["left_kat"], "type": "KAT", "side": "L", "note_type": 2},
|
||||
{"keys": get_config()["keybinds"]["right_kat"], "type": "KAT", "side": "R", "note_type": 2}
|
||||
]
|
||||
for config in key_configs:
|
||||
for key in config["keys"]:
|
||||
if ray.is_key_pressed(ord(key)):
|
||||
hit_type = config["type"]
|
||||
self.lane_hit_effect = LaneHitEffect(get_current_ms(), hit_type)
|
||||
self.draw_drum_hit_list.append(DrumHitEffect(get_current_ms(), hit_type, config["side"]))
|
||||
|
||||
sound = game_screen.sound_don if hit_type == "DON" else game_screen.sound_kat
|
||||
audio.play_sound(sound)
|
||||
|
||||
self.check_note(game_screen, config["note_type"])
|
||||
self.input_log[game_screen.current_ms] = (hit_type, key)
|
||||
|
||||
def update(self, game_screen: GameScreen):
|
||||
self.note_manager(game_screen)
|
||||
self.combo_display.update(game_screen, game_screen.current_ms, self.combo)
|
||||
self.combo_display.update(game_screen, get_current_ms(), self.combo)
|
||||
self.drumroll_counter_manager(game_screen)
|
||||
self.animation_manager(game_screen, self.draw_judge_list)
|
||||
self.animation_manager(self.draw_judge_list)
|
||||
self.balloon_manager(game_screen)
|
||||
if self.lane_hit_effect is not None:
|
||||
self.lane_hit_effect.update(game_screen.current_ms)
|
||||
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.score_counter.update(game_screen.current_ms, self.score)
|
||||
self.lane_hit_effect.update(get_current_ms())
|
||||
self.animation_manager(self.draw_drum_hit_list)
|
||||
self.animation_manager(self.draw_arc_list)
|
||||
self.animation_manager(self.base_score_list)
|
||||
self.score_counter.update(get_current_ms(), self.score)
|
||||
self.key_manager(game_screen)
|
||||
|
||||
self.gauge.update(game_screen.current_ms, self.good_count, self.ok_count, self.bad_count, self.total_notes)
|
||||
self.gauge.update(get_current_ms(), self.good_count, self.ok_count, self.bad_count, self.total_notes)
|
||||
|
||||
def draw_drumroll(self, game_screen: GameScreen, head: Drumroll, current_eighth: int):
|
||||
start_position = self.get_position(game_screen, head.load_ms, head.pixels_per_frame)
|
||||
@@ -581,26 +560,23 @@ class Player:
|
||||
anim.draw(game_screen)
|
||||
|
||||
class Judgement:
|
||||
def __init__(self, current_ms: float, type: str, big: bool):
|
||||
def __init__(self, game_screen, type: str, big: bool):
|
||||
self.type = type
|
||||
self.big = big
|
||||
self.is_finished = False
|
||||
current_ms = get_current_ms()
|
||||
|
||||
self.fade_animation_1 = Animation(current_ms, 132, 'fade')
|
||||
self.fade_animation_1.params['initial_opacity'] = 0.5
|
||||
self.fade_animation_1.params['delay'] = 100
|
||||
self.fade_animation_1 = Animation2.create_fade(132, initial_opacity=0.5, delay=100)
|
||||
|
||||
self.fade_animation_2 = Animation(current_ms, 316 - 233.3, 'fade')
|
||||
self.fade_animation_2.params['delay'] = 233.3
|
||||
self.fade_animation_2 = Animation2.create_fade(316 - 233.3, delay=233.3)
|
||||
|
||||
self.move_animation = Animation(current_ms, 83, 'move')
|
||||
self.move_animation.params['total_distance'] = 15
|
||||
self.move_animation.params['start_position'] = 144
|
||||
self.move_animation = Animation2.create_move(83, total_distance=15, start_position=144)
|
||||
|
||||
self.texture_animation = Animation(current_ms, 100, 'texture_change')
|
||||
self.texture_animation.params['textures'] = [(33, 50, 1), (50, 83, 2), (83, 100, 3), (100, float('inf'), 4)]
|
||||
|
||||
def update(self, current_ms: float):
|
||||
def update(self, game_screen):
|
||||
current_ms = get_current_ms()
|
||||
self.fade_animation_1.update(current_ms)
|
||||
self.fade_animation_2.update(current_ms)
|
||||
self.move_animation.update(current_ms)
|
||||
@@ -637,16 +613,14 @@ class LaneHitEffect:
|
||||
def __init__(self, current_ms: float, type: str):
|
||||
self.type = type
|
||||
self.color = ray.fade(ray.WHITE, 0.5)
|
||||
self.animation = Animation(current_ms, 150, 'fade')
|
||||
self.animation.params['delay'] = 83
|
||||
self.animation.params['initial_opacity'] = 0.5
|
||||
self.fade = Animation2.create_fade(150, delay=83, initial_opacity=0.5)
|
||||
self.is_finished = False
|
||||
|
||||
def update(self, current_ms: float):
|
||||
self.animation.update(current_ms)
|
||||
fade_opacity = self.animation.attribute
|
||||
self.fade.update(current_ms)
|
||||
fade_opacity = self.fade.attribute
|
||||
self.color = ray.fade(ray.WHITE, fade_opacity)
|
||||
if self.animation.is_finished:
|
||||
if self.fade.is_finished:
|
||||
self.is_finished = True
|
||||
|
||||
def draw(self, textures: list[ray.Texture]):
|
||||
@@ -663,14 +637,13 @@ class DrumHitEffect:
|
||||
self.side = side
|
||||
self.color = ray.fade(ray.WHITE, 1)
|
||||
self.is_finished = False
|
||||
self.animation = Animation(current_ms, 100, 'fade')
|
||||
self.animation.params['delay'] = 67
|
||||
self.fade = Animation2.create_fade(100, delay=67)
|
||||
|
||||
def update(self, current_ms: float):
|
||||
self.animation.update(current_ms)
|
||||
fade_opacity = self.animation.attribute
|
||||
self.fade.update(current_ms)
|
||||
fade_opacity = self.fade.attribute
|
||||
self.color = ray.fade(ray.WHITE, fade_opacity)
|
||||
if self.animation.is_finished:
|
||||
if self.fade.is_finished:
|
||||
self.is_finished = True
|
||||
|
||||
def draw(self, game_screen):
|
||||
@@ -780,13 +753,12 @@ class DrumrollCounter:
|
||||
self.is_finished = False
|
||||
self.total_duration = 1349
|
||||
self.drumroll_count = 0
|
||||
self.fade_animation = Animation(current_ms, 166, 'fade')
|
||||
self.fade_animation.params['delay'] = self.total_duration - 166
|
||||
self.fade_animation = Animation2.create_fade(166, delay=self.total_duration - 166)
|
||||
self.stretch_animation = Animation(current_ms, 0, 'text_stretch')
|
||||
|
||||
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
|
||||
self.fade_animation.delay = self.total_duration - 166
|
||||
if self.drumroll_count != count:
|
||||
self.drumroll_count = count
|
||||
self.stretch_animation = Animation(current_ms, 50, 'text_stretch')
|
||||
@@ -821,7 +793,7 @@ class BalloonAnimation:
|
||||
self.balloon_count = 0
|
||||
self.balloon_total = balloon_total
|
||||
self.is_popped = False
|
||||
self.fade_animation = Animation(current_ms, 166, 'fade')
|
||||
self.fade_animation = Animation2.create_fade(166)
|
||||
self.stretch_animation = Animation(current_ms, 0, 'text_stretch')
|
||||
|
||||
def update_count(self, current_ms: float, balloon_count: int):
|
||||
@@ -840,7 +812,7 @@ class BalloonAnimation:
|
||||
self.color = ray.fade(ray.WHITE, self.fade_animation.attribute)
|
||||
else:
|
||||
self.total_duration = elapsed_time + 166
|
||||
self.fade_animation.params['delay'] = self.total_duration - 166
|
||||
self.fade_animation.delay = self.total_duration - 166
|
||||
if self.fade_animation.is_finished:
|
||||
self.is_finished = True
|
||||
|
||||
@@ -957,31 +929,12 @@ class ScoreCounter:
|
||||
class ScoreCounterAnimation:
|
||||
def __init__(self, current_ms: float, counter: int):
|
||||
self.counter = counter
|
||||
self.fade_animation_1 = Animation(current_ms, 50, 'fade')
|
||||
self.fade_animation_1.params['initial_opacity'] = 0.0
|
||||
self.fade_animation_1.params['final_opacity'] = 1.0
|
||||
|
||||
self.move_animation_1 = Animation(current_ms, 80, 'move')
|
||||
self.move_animation_1.params['total_distance'] = -20
|
||||
self.move_animation_1.params['start_position'] = 175
|
||||
|
||||
self.fade_animation_2 = Animation(current_ms, 80, 'fade')
|
||||
self.fade_animation_2.params['delay'] = 366.74
|
||||
|
||||
self.move_animation_2 = Animation(current_ms, 66, 'move')
|
||||
self.move_animation_2.params['total_distance'] = 5
|
||||
self.move_animation_2.params['start_position'] = 145
|
||||
self.move_animation_2.params['delay'] = 80
|
||||
|
||||
self.move_animation_3 = Animation(current_ms, 66, 'move')
|
||||
self.move_animation_3.params['delay'] = 279.36
|
||||
self.move_animation_3.params['total_distance'] = -2
|
||||
self.move_animation_3.params['start_position'] = 146
|
||||
|
||||
self.move_animation_4 = Animation(current_ms, 80, 'move')
|
||||
self.move_animation_4.params['delay'] = 366.74
|
||||
self.move_animation_4.params['total_distance'] = 10
|
||||
self.move_animation_4.params['start_position'] = 148
|
||||
self.fade_animation_1 = Animation2.create_fade(50, initial_opacity=0.0, final_opacity=1.0)
|
||||
self.move_animation_1 = Animation2.create_move(80, total_distance=-20, start_position=175)
|
||||
self.fade_animation_2 = Animation2.create_fade(80, delay=366.74)
|
||||
self.move_animation_2 = Animation2.create_move(66, total_distance=5, start_position=145, delay=80)
|
||||
self.move_animation_3 = Animation2.create_move(66, delay=279.36, total_distance=-2, start_position=146)
|
||||
self.move_animation_4 = Animation2.create_move(80, delay=366.74, total_distance=10, start_position=148)
|
||||
|
||||
self.color = ray.fade(ray.Color(254, 102, 0, 255), 1.0)
|
||||
self.is_finished = False
|
||||
@@ -1032,8 +985,8 @@ class SongInfo:
|
||||
DISPLAY_DURATION = 1666
|
||||
|
||||
def __init__(self, current_ms: float, song_name: str, genre: str):
|
||||
self.fade_in = self._create_fade_in_animation(current_ms)
|
||||
self.fade_out = self._create_fade_out_animation(current_ms)
|
||||
self.fade_in = Animation2.create_fade(self.FADE_DURATION, initial_opacity=0.0, final_opacity=1.0)
|
||||
self.fade_out = Animation2.create_fade(self.FADE_DURATION, delay=self.FADE_DURATION + self.DISPLAY_DURATION)
|
||||
|
||||
self.song_name = song_name
|
||||
self.genre = genre
|
||||
@@ -1043,19 +996,6 @@ class SongInfo:
|
||||
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)
|
||||
unique_codepoints = set(text)
|
||||
@@ -1077,9 +1017,8 @@ class SongInfo:
|
||||
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)
|
||||
self.fade_in = Animation2.create_fade(self.FADE_DURATION, initial_opacity=0.0, final_opacity=1.0)
|
||||
self.fade_out = Animation2.create_fade(self.FADE_DURATION, delay=self.FADE_DURATION + self.DISPLAY_DURATION)
|
||||
|
||||
def draw(self, game_screen: GameScreen):
|
||||
song_texture_index = (global_data.songs_played % 4) + 8
|
||||
@@ -1095,10 +1034,7 @@ class SongInfo:
|
||||
|
||||
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.move.params['ease_out'] = 'quadratic'
|
||||
self.move = Animation2.create_move(983.33, start_position=0, total_distance=screen_height//2, ease_out='quadratic')
|
||||
|
||||
self.is_finished = False
|
||||
|
||||
@@ -1179,12 +1115,11 @@ class Gauge:
|
||||
anim.params['textures'] = []
|
||||
for i in range(8):
|
||||
anim.params['textures'].append(((16.67* 3)*i, (16.67 * 3)*(i+1), i))
|
||||
anim.params['textures'] = tuple(anim.params['textures'])
|
||||
return anim
|
||||
|
||||
def _create_anim(self, current_ms: float, init: float, final: float):
|
||||
anim = Animation(current_ms, 450, 'fade')
|
||||
anim.params['initial_opacity'] = init
|
||||
anim.params['final_opacity'] = final
|
||||
anim = Animation2.create_fade(450, initial_opacity=init, final_opacity=final)
|
||||
return anim
|
||||
|
||||
def update(self, current_ms: float, good_count: int, ok_count: int, bad_count: int, total_notes: int):
|
||||
|
||||
@@ -3,7 +3,7 @@ from pathlib import Path
|
||||
import pyray as ray
|
||||
|
||||
from libs import utils
|
||||
from libs.animation import Animation
|
||||
from libs.animation import Animation, Animation2
|
||||
from libs.audio import audio
|
||||
from libs.utils import (
|
||||
OutlinedText,
|
||||
@@ -178,10 +178,7 @@ class ResultScreen:
|
||||
|
||||
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.fadein = Animation2.create_fade(450, initial_opacity=1.0, final_opacity=0.0, delay=100)
|
||||
self.fade = ray.fade(ray.WHITE, self.fadein.attribute)
|
||||
|
||||
self.is_finished = False
|
||||
@@ -238,9 +235,7 @@ class Gauge:
|
||||
def __init__(self, current_ms: float, gauge_length):
|
||||
self.gauge_length = gauge_length
|
||||
self.rainbow_animation = None
|
||||
self.gauge_fade_in = Animation(get_current_ms(), 366, 'fade')
|
||||
self.gauge_fade_in.params['initial_opacity'] = 0.0
|
||||
self.gauge_fade_in.params['final_opacity'] = 1.0
|
||||
self.gauge_fade_in = Animation2.create_fade(366, initial_opacity=0.0, final_opacity=1.0)
|
||||
self.is_finished = self.gauge_fade_in.is_finished
|
||||
|
||||
def _create_rainbow_anim(self, current_ms):
|
||||
@@ -251,9 +246,7 @@ class Gauge:
|
||||
return anim
|
||||
|
||||
def _create_anim(self, current_ms: float, init: float, final: float):
|
||||
anim = Animation(current_ms, 450, 'fade')
|
||||
anim.params['initial_opacity'] = init
|
||||
anim.params['final_opacity'] = final
|
||||
anim = Animation2.create_fade(450, initial_opacity=init, final_opacity=final)
|
||||
return anim
|
||||
|
||||
def update(self, current_ms: float):
|
||||
|
||||
@@ -3,7 +3,7 @@ from pathlib import Path
|
||||
|
||||
import pyray as ray
|
||||
|
||||
from libs.animation import Animation
|
||||
from libs.animation import Animation, Animation2
|
||||
from libs.audio import audio
|
||||
from libs.utils import (
|
||||
get_config,
|
||||
@@ -111,24 +111,16 @@ class TitleScreen:
|
||||
|
||||
class WarningScreen:
|
||||
class X:
|
||||
DELAY = 4250
|
||||
def __init__(self, current_ms: float):
|
||||
self.delay = 4250
|
||||
self.resize = Animation(current_ms, 166.67, 'texture_resize')
|
||||
self.resize.params['initial_size'] = 1.0
|
||||
self.resize.params['final_size'] = 1.5
|
||||
self.resize.params['delay'] = self.delay
|
||||
self.resize.params['delay'] = self.DELAY
|
||||
self.resize.params['reverse'] = 0
|
||||
|
||||
self.fadein = Animation(current_ms, 166.67, 'fade')
|
||||
self.fadein.params['delay'] = self.delay
|
||||
self.fadein.params['initial_opacity'] = 0.0
|
||||
self.fadein.params['final_opacity'] = 1.0
|
||||
self.fadein.params['reverse'] = 166.67
|
||||
|
||||
self.fadein_2 = Animation(current_ms, 166.67, 'fade')
|
||||
self.fadein_2.params['delay'] = self.delay + 166.67 + 166.67
|
||||
self.fadein_2.params['initial_opacity'] = 0.0
|
||||
self.fadein_2.params['final_opacity'] = 1.0
|
||||
self.fadein = Animation2.create_fade(166.67, delay=self.DELAY, initial_opacity=0.0, final_opacity=1.0, reverse_delay=166.67)
|
||||
self.fadein_2 = Animation2.create_fade(166.67, delay=self.DELAY + self.fadein.duration, initial_opacity=0.0, final_opacity=1.0)
|
||||
|
||||
self.sound_played = False
|
||||
|
||||
@@ -138,7 +130,7 @@ class WarningScreen:
|
||||
self.fadein_2.update(current_ms)
|
||||
self.resize.update(current_ms)
|
||||
|
||||
if self.delay + self.fadein.duration <= elapsed_time and not self.sound_played:
|
||||
if self.DELAY + self.fadein.duration <= elapsed_time and not self.sound_played:
|
||||
audio.play_sound(sound)
|
||||
self.sound_played = True
|
||||
|
||||
@@ -158,10 +150,7 @@ class WarningScreen:
|
||||
self.resize.params['initial_size'] = 0.5
|
||||
self.resize.params['final_size'] = 1.5
|
||||
|
||||
self.fadein = Animation(current_ms, 116.67, 'fade')
|
||||
self.fadein.params['initial_opacity'] = 0.0
|
||||
self.fadein.params['final_opacity'] = 1.0
|
||||
self.fadein.params['reverse'] = 0
|
||||
self.fadein = Animation2.create_fade(116.67, initial_opacity=0.0, final_opacity=1.0, reverse_delay=0)
|
||||
|
||||
self.sound_played = False
|
||||
|
||||
@@ -188,9 +177,7 @@ class WarningScreen:
|
||||
def __init__(self, current_ms: float, start_ms: float):
|
||||
self.start_ms = start_ms
|
||||
self.current_ms = current_ms
|
||||
self.shadow_fade = Animation(current_ms, 50, 'fade')
|
||||
self.shadow_fade.params['delay'] = 16.67
|
||||
self.shadow_fade.params['initial_opacity'] = 0.75
|
||||
self.shadow_fade = Animation2.create_fade(50, delay=16.67, initial_opacity=0.75)
|
||||
|
||||
self.animation_sequence = [(300.00, 5, 4), (183.33, 6, 4), (166.67, 7, 4), (166.67, 8, 9), (166.67, 11, 9), (166.67, 12, 9), (166.67, 13, 9),
|
||||
(166.67, 5, 4), (150.00, 5, 4), (133.34, 6, 4), (133.34, 7, 4), (133.34, 8, 9), (133.34, 11, 9), (133.34, 12, 9), (133.34, 13, 9),
|
||||
@@ -243,21 +230,13 @@ class WarningScreen:
|
||||
class Board:
|
||||
def __init__(self, current_ms: float, screen_width, screen_height, texture):
|
||||
#Move warning board down from top of screen
|
||||
self.move_down = Animation(current_ms, 266.67, 'move')
|
||||
self.move_down.params['start_position'] = -720
|
||||
self.move_down.params['total_distance'] = screen_height + ((screen_height - texture.height)//2) + 20
|
||||
self.move_down = Animation2.create_move(266.67, total_distance=screen_height + ((screen_height - texture.height)//2) + 20, start_position=-720)
|
||||
|
||||
#Move warning board up a little bit
|
||||
self.move_up = Animation(current_ms, 116.67, 'move')
|
||||
self.move_up.params['start_position'] = 92 + 20
|
||||
self.move_up.params['delay'] = self.move_down.duration
|
||||
self.move_up.params['total_distance'] = -30
|
||||
self.move_up = Animation2.create_move(116.67, start_position=92 + 20, delay=self.move_down.duration, total_distance =-30)
|
||||
|
||||
#And finally into its correct position
|
||||
self.move_center = Animation(current_ms, 116.67, 'move')
|
||||
self.move_center.params['start_position'] = 82
|
||||
self.move_center.params['delay'] = self.move_down.duration + self.move_up.duration
|
||||
self.move_center.params['total_distance'] = 10
|
||||
self.move_center = Animation2.create_move(116.67, start_position=82, delay=self.move_down.duration + self.move_up.duration, total_distance=10)
|
||||
self.y_pos = 0
|
||||
|
||||
def update(self, current_ms):
|
||||
@@ -278,16 +257,10 @@ class WarningScreen:
|
||||
def __init__(self, current_ms: float, title_screen: TitleScreen):
|
||||
self.start_ms = current_ms
|
||||
|
||||
self.fade_in = Animation(current_ms, 300, 'fade')
|
||||
self.fade_in.params['delay'] = 266.67
|
||||
self.fade_in.params['initial_opacity'] = 0.0
|
||||
self.fade_in.params['final_opacity'] = 1.0
|
||||
self.fade_in = Animation2.create_fade(300, delay=266.67, initial_opacity=0.0, final_opacity=1.0)
|
||||
|
||||
#Fade to black
|
||||
self.fade_out = Animation(current_ms, 500, 'fade')
|
||||
self.fade_out.params['initial_opacity'] = 0.0
|
||||
self.fade_out.params['final_opacity'] = 1.0
|
||||
self.fade_out.params['delay'] = 1000
|
||||
self.fade_out = Animation2.create_fade(500, delay=1000, initial_opacity=0.0, final_opacity=1.0)
|
||||
|
||||
self.board = self.Board(current_ms, title_screen.width, title_screen.height, title_screen.textures['keikoku'][1])
|
||||
self.warning_x = self.X(current_ms)
|
||||
@@ -311,7 +284,7 @@ class WarningScreen:
|
||||
if self.characters.is_finished:
|
||||
self.warning_bachi_hit.update(current_ms, title_screen.sound_bachi_hit)
|
||||
else:
|
||||
self.fade_out.params['delay'] = elapsed_time + 500
|
||||
self.fade_out.delay = elapsed_time + 500
|
||||
if delay <= elapsed_time and not audio.is_sound_playing(title_screen.sound_bachi_swipe):
|
||||
audio.play_sound(title_screen.sound_warning_message)
|
||||
audio.play_sound(title_screen.sound_bachi_swipe)
|
||||
|
||||
Reference in New Issue
Block a user