slowly updating the animation library

This commit is contained in:
Yonokid
2025-05-08 01:08:17 -04:00
parent 2e22bd006d
commit bc08f24c9d
6 changed files with 306 additions and 299 deletions

View File

@@ -58,16 +58,17 @@ jobs:
*.bin *.bin
*.app/**/* *.app/**/*
- name: Release # - name: Release
uses: softprops/action-gh-release@v2 # uses: softprops/action-gh-release@v2
with: # with:
repository: yonokid/PyTaiko # repository: yonokid/PyTaiko
files: | # files: |
Graphics/* # Graphics/*
Sounds/* # Sounds/*
Videos/* # Videos/*
config.toml # config.toml
*.exe # *.exe
*.bin # *.bin
*.app/**/* # *.app/**/*
tag_name: 0.0.3 # tag_name: 0.0.3
# make_latest: true

View File

@@ -1,3 +1,8 @@
from typing import Optional
from libs.utils import get_current_ms
class Animation: class Animation:
def __init__(self, current_ms: float, duration: float, type: str): def __init__(self, current_ms: float, duration: float, type: str):
self.type = type self.type = type
@@ -8,23 +13,7 @@ class Animation:
self.is_finished = False self.is_finished = False
def update(self, current_ms: float): def update(self, current_ms: float):
if self.type == 'fade': if self.type == 'move':
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':
self.move(current_ms, self.move(current_ms,
self.duration, self.duration,
self.params['total_distance'], self.params['total_distance'],
@@ -71,25 +60,6 @@ class Animation:
else: else:
return progress 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: 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 elapsed_time = current_ms - self.start_ms
if elapsed_time < delay: if elapsed_time < delay:
@@ -139,3 +109,137 @@ class Animation:
else: else:
self.attribute = final_size self.attribute = final_size
self.is_finished = True 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)
'''

View File

@@ -365,6 +365,7 @@ class TJAParser:
note.type = int(item) note.type = int(item)
note.pixels_per_frame = bar.pixels_per_frame note.pixels_per_frame = bar.pixels_per_frame
note.index = index note.index = index
note.moji = -1
if item in {'5', '6'}: if item in {'5', '6'}:
note = Drumroll(note) note = Drumroll(note)
note.color = 255 note.color = 255

View File

@@ -1,11 +1,11 @@
import bisect import bisect
import math import math
from collections import deque
from pathlib import Path from pathlib import Path
from typing import Optional
import pyray as ray import pyray as ray
from libs.animation import Animation from libs.animation import Animation, Animation2
from libs.audio import audio from libs.audio import audio
from libs.tja import Balloon, Drumroll, Note, TJAParser, calculate_base_score from libs.tja import Balloon, Drumroll, Note, TJAParser, calculate_base_score
from libs.utils import ( from libs.utils import (
@@ -108,12 +108,11 @@ class GameScreen:
else: else:
self.movie = None self.movie = None
self.tja.distance = self.width - self.judge_x self.tja.distance = self.width - self.judge_x
self.start_delay = 0
session_data.song_title = self.tja.title session_data.song_title = self.tja.title
self.player_1 = Player(self, 1, difficulty, metadata, get_config()["general"]["judge_offset"]) 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.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) audio.play_sound(self.song_music)
@@ -136,23 +135,22 @@ class GameScreen:
def update(self): def update(self):
self.on_screen_start() self.on_screen_start()
self.current_ms = get_current_ms() - self.start_ms
if self.movie is not None: if self.movie is not None:
self.movie.update() self.movie.update()
self.current_ms = get_current_ms() - self.start_ms
self.player_1.update(self) self.player_1.update(self)
if self.song_info is not None: 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: 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: if self.result_transition.is_finished:
return self.on_screen_end() 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_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.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) audio.play_sound(self.sound_result_transition)
def draw(self): def draw(self):
@@ -166,28 +164,24 @@ class GameScreen:
class Player: 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): 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.player_number = player_number
self.difficulty = difficulty self.difficulty = difficulty
self.play_note_list, self.draw_note_list, self.draw_bar_list = game_screen.tja.notes_to_position(self.difficulty) 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_note_list if 0 < note.type < 5]) self.total_notes = len([note for note in self.play_notes if 0 < note.type < 5])
print(self.total_notes) self.base_score = calculate_base_score(self.play_notes)
self.base_score = calculate_base_score(self.play_note_list)
self.judge_offset = judge_offset self.judge_offset = judge_offset
#Note management #Note management
self.current_notes: deque[Note | Drumroll | Balloon] = deque()
self.current_bars: list[Note] = [] self.current_bars: list[Note] = []
self.current_notes_draw: list[Note | Drumroll | Balloon] = [] 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.is_drumroll = False
self.curr_drumroll_count = 0 self.curr_drumroll_count = 0
self.is_balloon = False self.is_balloon = False
@@ -206,18 +200,18 @@ class Player:
self.arc_points = 25 self.arc_points = 25
self.draw_judge_list: list[Judgement] = [] 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_arc_list: list[NoteArc] = []
self.draw_drum_hit_list: list[DrumHitEffect] = [] self.draw_drum_hit_list: list[DrumHitEffect] = []
self.drumroll_counter: DrumrollCounter | None = None self.drumroll_counter: Optional[DrumrollCounter] = None
self.balloon_anim: BalloonAnimation | None = None self.balloon_anim: Optional[BalloonAnimation] = None
self.base_score_list: list[ScoreCounterAnimation] = [] self.base_score_list: list[ScoreCounterAnimation] = []
self.combo_display = Combo(self.combo, game_screen.current_ms) self.combo_display = Combo(self.combo, get_current_ms())
self.score_counter = ScoreCounter(self.score, game_screen.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): def get_result_score(self):
return self.score, self.good_count, self.ok_count, self.bad_count, self.total_drumroll, self.max_combo 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: 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) 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: if len(animation_list) <= 0:
return return
for i in range(len(animation_list)-1, -1, -1): for i in range(len(animation_list)-1, -1, -1):
animation = animation_list[i] animation = animation_list[i]
animation.update(game_screen.current_ms) animation.update(get_current_ms())
if animation.is_finished: if animation.is_finished:
animation_list.pop(i) animation_list.pop(i)
@@ -251,45 +245,44 @@ class Player:
self.current_bars.pop(i) self.current_bars.pop(i)
def play_note_manager(self, game_screen: GameScreen): 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_notes) == 0:
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:
return return
note = self.current_notes[0] note = self.play_notes[0]
if note.hit_ms + self.timing_bad < game_screen.current_ms: if note.hit_ms + Player.TIMING_BAD < game_screen.current_ms:
if 0 < note.type <= 4: if 0 < note.type <= 4:
self.combo = 0 self.combo = 0
self.bad_count += 1 self.bad_count += 1
if note.type != 7: self.play_notes.popleft()
self.current_notes.popleft() elif note.type != 8:
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: tail = self.play_notes[1]
self.current_notes.popleft() if tail.hit_ms <= game_screen.current_ms:
self.is_balloon = False self.play_notes.popleft()
self.current_notes.popleft() self.play_notes.popleft()
self.is_drumroll = False
self.is_balloon = False
else:
if len(self.play_notes) == 1:
self.play_notes.popleft()
elif (note.hit_ms <= game_screen.current_ms): elif (note.hit_ms <= game_screen.current_ms):
if note.type == 5: if note.type == 5 or note.type == 6:
self.is_drumroll = True
elif note.type == 6:
self.is_drumroll = True self.is_drumroll = True
elif note.type == 7: elif note.type == 7:
self.is_balloon = True self.is_balloon = True
elif note.type == 8 and (self.is_drumroll):
self.is_drumroll = False
def draw_note_manager(self, game_screen: GameScreen): 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 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}: current_note = self.draw_note_list.popleft()
while self.draw_note_list[0].type != 8: if 5 <= current_note.type <= 7:
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)
bisect.insort_left(self.current_notes_draw, self.draw_note_list.popleft(), 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: 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: if len(self.current_notes_draw) == 0:
return return
@@ -310,6 +303,7 @@ class Player:
self.draw_note_manager(game_screen) self.draw_note_manager(game_screen)
def note_correct(self, game_screen: GameScreen, note: Note): def note_correct(self, game_screen: GameScreen, note: Note):
self.play_notes.popleft()
index = note.index index = note.index
if note.type == 7: if note.type == 7:
note_type = game_screen.note_type_list[3][0] note_type = game_screen.note_type_list[3][0]
@@ -320,8 +314,7 @@ class Player:
if self.combo > self.max_combo: if self.combo > self.max_combo:
self.max_combo = self.combo self.max_combo = self.combo
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.current_notes.popleft()
if note in self.current_notes_draw: if note in self.current_notes_draw:
index = self.current_notes_draw.index(note) index = self.current_notes_draw.index(note)
@@ -329,11 +322,11 @@ class Player:
def check_drumroll(self, game_screen: GameScreen, drum_type: int): def check_drumroll(self, game_screen: GameScreen, drum_type: int):
note_type = game_screen.note_type_list[drum_type][0] 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.curr_drumroll_count += 1
self.total_drumroll += 1 self.total_drumroll += 1
self.score += 100 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): if not isinstance(self.current_notes_draw[0], Drumroll):
return return
self.current_notes_draw[0].color = max(0, 255 - (self.curr_drumroll_count * 10)) self.current_notes_draw[0].color = max(0, 255 - (self.curr_drumroll_count * 10))
@@ -342,23 +335,23 @@ class Player:
if drum_type != 1: if drum_type != 1:
return return
if self.balloon_anim is None: 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.curr_balloon_count += 1
self.total_drumroll += 1 self.total_drumroll += 1
self.score += 100 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: if self.curr_balloon_count == note.count:
self.is_balloon = False self.is_balloon = False
note.popped = True 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) 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): def check_note(self, game_screen: GameScreen, drum_type: int):
if len(self.current_notes) == 0: if len(self.play_notes) == 0:
return return
curr_note = self.current_notes[0] curr_note = self.play_notes[0]
if self.is_drumroll: if self.is_drumroll:
self.check_drumroll(game_screen, drum_type) self.check_drumroll(game_screen, drum_type)
elif self.is_balloon: elif self.is_balloon:
@@ -369,7 +362,7 @@ class Player:
self.curr_drumroll_count = 0 self.curr_drumroll_count = 0
self.curr_balloon_count = 0 self.curr_balloon_count = 0
curr_note = next( 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 None # Default if no matching note is found
) )
if curr_note is None: if curr_note is None:
@@ -380,95 +373,81 @@ class Player:
if drum_type == 2 and curr_note.type not in {2, 4}: if drum_type == 2 and curr_note.type not in {2, 4}:
return return
#If the note is too far away, stop checking #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 return
big = curr_note.type in {3,4} big = curr_note.type == 3 or curr_note.type == 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: 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(game_screen.current_ms, 'GOOD', big)) self.draw_judge_list.append(Judgement(get_current_ms(), 'GOOD', big))
self.lane_hit_effect = LaneHitEffect(game_screen.current_ms, 'GOOD') self.lane_hit_effect = LaneHitEffect(get_current_ms(), 'GOOD')
self.good_count += 1 self.good_count += 1
self.score += self.base_score 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) 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: 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(game_screen.current_ms, 'OK', big)) self.draw_judge_list.append(Judgement(get_current_ms(), 'OK', big))
self.ok_count += 1 self.ok_count += 1
self.score += 10 * math.floor(self.base_score / 2 / 10) 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) 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: 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(game_screen.current_ms, 'BAD', big)) self.draw_judge_list.append(Judgement(get_current_ms(), 'BAD', big))
self.bad_count += 1 self.bad_count += 1
self.combo = 0 self.combo = 0
self.current_notes.popleft() self.play_notes.popleft()
def drumroll_counter_manager(self, game_screen: GameScreen): def drumroll_counter_manager(self, game_screen: GameScreen):
if self.is_drumroll and self.curr_drumroll_count > 0 and self.drumroll_counter is None: 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 not None:
if self.drumroll_counter.is_finished and not self.is_drumroll: if self.drumroll_counter.is_finished and not self.is_drumroll:
self.drumroll_counter = None self.drumroll_counter = None
else: 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): def balloon_manager(self, game_screen: GameScreen):
if self.balloon_anim is not None: 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: if self.balloon_anim.is_finished:
self.balloon_anim = None self.balloon_anim = None
def key_manager(self, game_screen: GameScreen): def key_manager(self, game_screen: GameScreen):
left_kats = get_config()["keybinds"]["left_kat"] key_configs = [
left_dons = get_config()["keybinds"]["left_don"] {"keys": get_config()["keybinds"]["left_don"], "type": "DON", "side": "L", "note_type": 1},
right_dons = get_config()["keybinds"]["right_don"] {"keys": get_config()["keybinds"]["right_don"], "type": "DON", "side": "R", "note_type": 1},
right_kats = get_config()["keybinds"]["right_kat"] {"keys": get_config()["keybinds"]["left_kat"], "type": "KAT", "side": "L", "note_type": 2},
for left_don in left_dons: {"keys": get_config()["keybinds"]["right_kat"], "type": "KAT", "side": "R", "note_type": 2}
if ray.is_key_pressed(ord(left_don)): ]
self.lane_hit_effect = LaneHitEffect(game_screen.current_ms, 'DON') for config in key_configs:
self.draw_drum_hit_list.append(DrumHitEffect(game_screen.current_ms, 'DON', 'L')) for key in config["keys"]:
audio.play_sound(game_screen.sound_don) if ray.is_key_pressed(ord(key)):
self.check_note(game_screen, 1) hit_type = config["type"]
self.input_log[game_screen.current_ms] = 'DON' self.lane_hit_effect = LaneHitEffect(get_current_ms(), hit_type)
for right_don in right_dons: self.draw_drum_hit_list.append(DrumHitEffect(get_current_ms(), hit_type, config["side"]))
if ray.is_key_pressed(ord(right_don)):
self.lane_hit_effect = LaneHitEffect(game_screen.current_ms, 'DON') sound = game_screen.sound_don if hit_type == "DON" else game_screen.sound_kat
self.draw_drum_hit_list.append(DrumHitEffect(game_screen.current_ms, 'DON', 'R')) audio.play_sound(sound)
audio.play_sound(game_screen.sound_don)
self.check_note(game_screen, 1) self.check_note(game_screen, config["note_type"])
self.input_log[game_screen.current_ms] = 'DON' self.input_log[game_screen.current_ms] = (hit_type, key)
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'
def update(self, game_screen: GameScreen): def update(self, game_screen: GameScreen):
self.note_manager(game_screen) 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.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) self.balloon_manager(game_screen)
if self.lane_hit_effect is not None: if self.lane_hit_effect is not None:
self.lane_hit_effect.update(game_screen.current_ms) self.lane_hit_effect.update(get_current_ms())
self.animation_manager(game_screen, self.draw_drum_hit_list) self.animation_manager(self.draw_drum_hit_list)
self.animation_manager(game_screen, self.draw_arc_list) self.animation_manager(self.draw_arc_list)
self.animation_manager(game_screen, self.base_score_list) self.animation_manager(self.base_score_list)
self.score_counter.update(game_screen.current_ms, self.score) self.score_counter.update(get_current_ms(), self.score)
self.key_manager(game_screen) 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): 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) start_position = self.get_position(game_screen, head.load_ms, head.pixels_per_frame)
@@ -581,26 +560,23 @@ class Player:
anim.draw(game_screen) anim.draw(game_screen)
class Judgement: 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.type = type
self.big = big self.big = big
self.is_finished = False self.is_finished = False
current_ms = get_current_ms()
self.fade_animation_1 = Animation(current_ms, 132, 'fade') self.fade_animation_1 = Animation2.create_fade(132, initial_opacity=0.5, delay=100)
self.fade_animation_1.params['initial_opacity'] = 0.5
self.fade_animation_1.params['delay'] = 100
self.fade_animation_2 = Animation(current_ms, 316 - 233.3, 'fade') self.fade_animation_2 = Animation2.create_fade(316 - 233.3, delay=233.3)
self.fade_animation_2.params['delay'] = 233.3
self.move_animation = Animation(current_ms, 83, 'move') self.move_animation = Animation2.create_move(83, total_distance=15, start_position=144)
self.move_animation.params['total_distance'] = 15
self.move_animation.params['start_position'] = 144
self.texture_animation = Animation(current_ms, 100, 'texture_change') 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)] 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_1.update(current_ms)
self.fade_animation_2.update(current_ms) self.fade_animation_2.update(current_ms)
self.move_animation.update(current_ms) self.move_animation.update(current_ms)
@@ -637,16 +613,14 @@ class LaneHitEffect:
def __init__(self, current_ms: float, type: str): def __init__(self, current_ms: float, type: str):
self.type = type self.type = type
self.color = ray.fade(ray.WHITE, 0.5) self.color = ray.fade(ray.WHITE, 0.5)
self.animation = Animation(current_ms, 150, 'fade') self.fade = Animation2.create_fade(150, delay=83, initial_opacity=0.5)
self.animation.params['delay'] = 83
self.animation.params['initial_opacity'] = 0.5
self.is_finished = False self.is_finished = False
def update(self, current_ms: float): def update(self, current_ms: float):
self.animation.update(current_ms) self.fade.update(current_ms)
fade_opacity = self.animation.attribute fade_opacity = self.fade.attribute
self.color = ray.fade(ray.WHITE, fade_opacity) self.color = ray.fade(ray.WHITE, fade_opacity)
if self.animation.is_finished: if self.fade.is_finished:
self.is_finished = True self.is_finished = True
def draw(self, textures: list[ray.Texture]): def draw(self, textures: list[ray.Texture]):
@@ -663,14 +637,13 @@ class DrumHitEffect:
self.side = side self.side = side
self.color = ray.fade(ray.WHITE, 1) self.color = ray.fade(ray.WHITE, 1)
self.is_finished = False self.is_finished = False
self.animation = Animation(current_ms, 100, 'fade') self.fade = Animation2.create_fade(100, delay=67)
self.animation.params['delay'] = 67
def update(self, current_ms: float): def update(self, current_ms: float):
self.animation.update(current_ms) self.fade.update(current_ms)
fade_opacity = self.animation.attribute fade_opacity = self.fade.attribute
self.color = ray.fade(ray.WHITE, fade_opacity) self.color = ray.fade(ray.WHITE, fade_opacity)
if self.animation.is_finished: if self.fade.is_finished:
self.is_finished = True self.is_finished = True
def draw(self, game_screen): def draw(self, game_screen):
@@ -780,13 +753,12 @@ class DrumrollCounter:
self.is_finished = False self.is_finished = False
self.total_duration = 1349 self.total_duration = 1349
self.drumroll_count = 0 self.drumroll_count = 0
self.fade_animation = Animation(current_ms, 166, 'fade') self.fade_animation = Animation2.create_fade(166, delay=self.total_duration - 166)
self.fade_animation.params['delay'] = self.total_duration - 166
self.stretch_animation = Animation(current_ms, 0, 'text_stretch') self.stretch_animation = Animation(current_ms, 0, 'text_stretch')
def update_count(self, current_ms: float, count: int, elapsed_time: float): def update_count(self, current_ms: float, count: int, elapsed_time: float):
self.total_duration = elapsed_time + 1349 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: if self.drumroll_count != count:
self.drumroll_count = count self.drumroll_count = count
self.stretch_animation = Animation(current_ms, 50, 'text_stretch') self.stretch_animation = Animation(current_ms, 50, 'text_stretch')
@@ -821,7 +793,7 @@ class BalloonAnimation:
self.balloon_count = 0 self.balloon_count = 0
self.balloon_total = balloon_total self.balloon_total = balloon_total
self.is_popped = False 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') self.stretch_animation = Animation(current_ms, 0, 'text_stretch')
def update_count(self, current_ms: float, balloon_count: int): 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) self.color = ray.fade(ray.WHITE, self.fade_animation.attribute)
else: else:
self.total_duration = elapsed_time + 166 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: if self.fade_animation.is_finished:
self.is_finished = True self.is_finished = True
@@ -957,31 +929,12 @@ class ScoreCounter:
class ScoreCounterAnimation: class ScoreCounterAnimation:
def __init__(self, current_ms: float, counter: int): def __init__(self, current_ms: float, counter: int):
self.counter = counter self.counter = counter
self.fade_animation_1 = Animation(current_ms, 50, 'fade') self.fade_animation_1 = Animation2.create_fade(50, initial_opacity=0.0, final_opacity=1.0)
self.fade_animation_1.params['initial_opacity'] = 0.0 self.move_animation_1 = Animation2.create_move(80, total_distance=-20, start_position=175)
self.fade_animation_1.params['final_opacity'] = 1.0 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_1 = Animation(current_ms, 80, 'move') self.move_animation_3 = Animation2.create_move(66, delay=279.36, total_distance=-2, start_position=146)
self.move_animation_1.params['total_distance'] = -20 self.move_animation_4 = Animation2.create_move(80, delay=366.74, total_distance=10, start_position=148)
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.color = ray.fade(ray.Color(254, 102, 0, 255), 1.0) self.color = ray.fade(ray.Color(254, 102, 0, 255), 1.0)
self.is_finished = False self.is_finished = False
@@ -1032,8 +985,8 @@ class SongInfo:
DISPLAY_DURATION = 1666 DISPLAY_DURATION = 1666
def __init__(self, current_ms: float, song_name: str, genre: str): def __init__(self, current_ms: float, song_name: str, genre: str):
self.fade_in = self._create_fade_in_animation(current_ms) self.fade_in = Animation2.create_fade(self.FADE_DURATION, initial_opacity=0.0, final_opacity=1.0)
self.fade_out = self._create_fade_out_animation(current_ms) self.fade_out = Animation2.create_fade(self.FADE_DURATION, delay=self.FADE_DURATION + self.DISPLAY_DURATION)
self.song_name = song_name self.song_name = song_name
self.genre = genre self.genre = genre
@@ -1043,19 +996,6 @@ class SongInfo:
self.font, song_name, 40, ray.WHITE, ray.BLACK, outline_thickness=5 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: def _load_font_for_text(self, text: str) -> ray.Font:
codepoint_count = ray.ffi.new('int *', 0) codepoint_count = ray.ffi.new('int *', 0)
unique_codepoints = set(text) unique_codepoints = set(text)
@@ -1077,9 +1017,8 @@ class SongInfo:
self._reset_animations(current_ms) self._reset_animations(current_ms)
def _reset_animations(self, current_ms: float): def _reset_animations(self, current_ms: float):
next_cycle_start = current_ms + self.DISPLAY_DURATION self.fade_in = Animation2.create_fade(self.FADE_DURATION, initial_opacity=0.0, final_opacity=1.0)
self.fade_in = self._create_fade_in_animation(next_cycle_start) self.fade_out = Animation2.create_fade(self.FADE_DURATION, delay=self.FADE_DURATION + self.DISPLAY_DURATION)
self.fade_out = self._create_fade_out_animation(next_cycle_start)
def draw(self, game_screen: GameScreen): def draw(self, game_screen: GameScreen):
song_texture_index = (global_data.songs_played % 4) + 8 song_texture_index = (global_data.songs_played % 4) + 8
@@ -1095,10 +1034,7 @@ class SongInfo:
class ResultTransition: class ResultTransition:
def __init__(self, current_ms: float, screen_height: int): def __init__(self, current_ms: float, screen_height: int):
self.move = Animation(current_ms, 983.33, 'move') self.move = Animation2.create_move(983.33, start_position=0, total_distance=screen_height//2, ease_out='quadratic')
self.move.params['start_position'] = 0.0
self.move.params['total_distance'] = screen_height//2
self.move.params['ease_out'] = 'quadratic'
self.is_finished = False self.is_finished = False
@@ -1179,12 +1115,11 @@ class Gauge:
anim.params['textures'] = [] anim.params['textures'] = []
for i in range(8): for i in range(8):
anim.params['textures'].append(((16.67* 3)*i, (16.67 * 3)*(i+1), i)) anim.params['textures'].append(((16.67* 3)*i, (16.67 * 3)*(i+1), i))
anim.params['textures'] = tuple(anim.params['textures'])
return anim return anim
def _create_anim(self, current_ms: float, init: float, final: float): def _create_anim(self, current_ms: float, init: float, final: float):
anim = Animation(current_ms, 450, 'fade') anim = Animation2.create_fade(450, initial_opacity=init, final_opacity=final)
anim.params['initial_opacity'] = init
anim.params['final_opacity'] = final
return anim return anim
def update(self, current_ms: float, good_count: int, ok_count: int, bad_count: int, total_notes: int): def update(self, current_ms: float, good_count: int, ok_count: int, bad_count: int, total_notes: int):

View File

@@ -3,7 +3,7 @@ from pathlib import Path
import pyray as ray import pyray as ray
from libs import utils from libs import utils
from libs.animation import Animation from libs.animation import Animation, Animation2
from libs.audio import audio from libs.audio import audio
from libs.utils import ( from libs.utils import (
OutlinedText, OutlinedText,
@@ -178,10 +178,7 @@ class ResultScreen:
class FadeIn: class FadeIn:
def __init__(self, current_ms: float): def __init__(self, current_ms: float):
self.fadein = Animation(current_ms, 450, 'fade') self.fadein = Animation2.create_fade(450, initial_opacity=1.0, final_opacity=0.0, delay=100)
self.fadein.params['initial_opacity'] = 1.0
self.fadein.params['final_opacity'] = 0.0
self.fadein.params['delay'] = 100
self.fade = ray.fade(ray.WHITE, self.fadein.attribute) self.fade = ray.fade(ray.WHITE, self.fadein.attribute)
self.is_finished = False self.is_finished = False
@@ -238,9 +235,7 @@ class Gauge:
def __init__(self, current_ms: float, gauge_length): def __init__(self, current_ms: float, gauge_length):
self.gauge_length = gauge_length self.gauge_length = gauge_length
self.rainbow_animation = None self.rainbow_animation = None
self.gauge_fade_in = Animation(get_current_ms(), 366, 'fade') self.gauge_fade_in = Animation2.create_fade(366, initial_opacity=0.0, final_opacity=1.0)
self.gauge_fade_in.params['initial_opacity'] = 0.0
self.gauge_fade_in.params['final_opacity'] = 1.0
self.is_finished = self.gauge_fade_in.is_finished self.is_finished = self.gauge_fade_in.is_finished
def _create_rainbow_anim(self, current_ms): def _create_rainbow_anim(self, current_ms):
@@ -251,9 +246,7 @@ class Gauge:
return anim return anim
def _create_anim(self, current_ms: float, init: float, final: float): def _create_anim(self, current_ms: float, init: float, final: float):
anim = Animation(current_ms, 450, 'fade') anim = Animation2.create_fade(450, initial_opacity=init, final_opacity=final)
anim.params['initial_opacity'] = init
anim.params['final_opacity'] = final
return anim return anim
def update(self, current_ms: float): def update(self, current_ms: float):

View File

@@ -3,7 +3,7 @@ from pathlib import Path
import pyray as ray import pyray as ray
from libs.animation import Animation from libs.animation import Animation, Animation2
from libs.audio import audio from libs.audio import audio
from libs.utils import ( from libs.utils import (
get_config, get_config,
@@ -111,24 +111,16 @@ class TitleScreen:
class WarningScreen: class WarningScreen:
class X: class X:
DELAY = 4250
def __init__(self, current_ms: float): def __init__(self, current_ms: float):
self.delay = 4250
self.resize = Animation(current_ms, 166.67, 'texture_resize') self.resize = Animation(current_ms, 166.67, 'texture_resize')
self.resize.params['initial_size'] = 1.0 self.resize.params['initial_size'] = 1.0
self.resize.params['final_size'] = 1.5 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.resize.params['reverse'] = 0
self.fadein = Animation(current_ms, 166.67, 'fade') self.fadein = Animation2.create_fade(166.67, delay=self.DELAY, initial_opacity=0.0, final_opacity=1.0, reverse_delay=166.67)
self.fadein.params['delay'] = self.delay self.fadein_2 = Animation2.create_fade(166.67, delay=self.DELAY + self.fadein.duration, initial_opacity=0.0, final_opacity=1.0)
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.sound_played = False self.sound_played = False
@@ -138,7 +130,7 @@ class WarningScreen:
self.fadein_2.update(current_ms) self.fadein_2.update(current_ms)
self.resize.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) audio.play_sound(sound)
self.sound_played = True self.sound_played = True
@@ -158,10 +150,7 @@ class WarningScreen:
self.resize.params['initial_size'] = 0.5 self.resize.params['initial_size'] = 0.5
self.resize.params['final_size'] = 1.5 self.resize.params['final_size'] = 1.5
self.fadein = Animation(current_ms, 116.67, 'fade') self.fadein = Animation2.create_fade(116.67, initial_opacity=0.0, final_opacity=1.0, reverse_delay=0)
self.fadein.params['initial_opacity'] = 0.0
self.fadein.params['final_opacity'] = 1.0
self.fadein.params['reverse'] = 0
self.sound_played = False self.sound_played = False
@@ -188,9 +177,7 @@ class WarningScreen:
def __init__(self, current_ms: float, start_ms: float): def __init__(self, current_ms: float, start_ms: float):
self.start_ms = start_ms self.start_ms = start_ms
self.current_ms = current_ms self.current_ms = current_ms
self.shadow_fade = Animation(current_ms, 50, 'fade') self.shadow_fade = Animation2.create_fade(50, delay=16.67, initial_opacity=0.75)
self.shadow_fade.params['delay'] = 16.67
self.shadow_fade.params['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), 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), (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: class Board:
def __init__(self, current_ms: float, screen_width, screen_height, texture): def __init__(self, current_ms: float, screen_width, screen_height, texture):
#Move warning board down from top of screen #Move warning board down from top of screen
self.move_down = Animation(current_ms, 266.67, 'move') self.move_down = Animation2.create_move(266.67, total_distance=screen_height + ((screen_height - texture.height)//2) + 20, start_position=-720)
self.move_down.params['start_position'] = -720
self.move_down.params['total_distance'] = screen_height + ((screen_height - texture.height)//2) + 20
#Move warning board up a little bit #Move warning board up a little bit
self.move_up = Animation(current_ms, 116.67, 'move') self.move_up = Animation2.create_move(116.67, start_position=92 + 20, delay=self.move_down.duration, total_distance =-30)
self.move_up.params['start_position'] = 92 + 20
self.move_up.params['delay'] = self.move_down.duration
self.move_up.params['total_distance'] = -30
#And finally into its correct position #And finally into its correct position
self.move_center = Animation(current_ms, 116.67, 'move') self.move_center = Animation2.create_move(116.67, start_position=82, delay=self.move_down.duration + self.move_up.duration, total_distance=10)
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.y_pos = 0 self.y_pos = 0
def update(self, current_ms): def update(self, current_ms):
@@ -278,16 +257,10 @@ class WarningScreen:
def __init__(self, current_ms: float, title_screen: TitleScreen): def __init__(self, current_ms: float, title_screen: TitleScreen):
self.start_ms = current_ms self.start_ms = current_ms
self.fade_in = Animation(current_ms, 300, 'fade') self.fade_in = Animation2.create_fade(300, delay=266.67, initial_opacity=0.0, final_opacity=1.0)
self.fade_in.params['delay'] = 266.67
self.fade_in.params['initial_opacity'] = 0.0
self.fade_in.params['final_opacity'] = 1.0
#Fade to black #Fade to black
self.fade_out = Animation(current_ms, 500, 'fade') self.fade_out = Animation2.create_fade(500, delay=1000, initial_opacity=0.0, final_opacity=1.0)
self.fade_out.params['initial_opacity'] = 0.0
self.fade_out.params['final_opacity'] = 1.0
self.fade_out.params['delay'] = 1000
self.board = self.Board(current_ms, title_screen.width, title_screen.height, title_screen.textures['keikoku'][1]) self.board = self.Board(current_ms, title_screen.width, title_screen.height, title_screen.textures['keikoku'][1])
self.warning_x = self.X(current_ms) self.warning_x = self.X(current_ms)
@@ -311,7 +284,7 @@ class WarningScreen:
if self.characters.is_finished: if self.characters.is_finished:
self.warning_bachi_hit.update(current_ms, title_screen.sound_bachi_hit) self.warning_bachi_hit.update(current_ms, title_screen.sound_bachi_hit)
else: 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): 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_warning_message)
audio.play_sound(title_screen.sound_bachi_swipe) audio.play_sound(title_screen.sound_bachi_swipe)