From b56b5dbff6c71ef3f06ac9703076331326859241 Mon Sep 17 00:00:00 2001 From: Anthony Samms Date: Sat, 29 Nov 2025 12:34:54 -0500 Subject: [PATCH] fix jposcroll --- libs/tja.py | 45 +++++++++++++++++++++++++-------------------- scenes/game.py | 28 +++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 25 deletions(-) diff --git a/libs/tja.py b/libs/tja.py index 2b920c4..aa88251 100644 --- a/libs/tja.py +++ b/libs/tja.py @@ -53,6 +53,8 @@ class TimelineObject: judge_pos_x: float = field(init=False) judge_pos_y: float = field(init=False) + delta_x: float = field(init=False) + delta_y: float = field(init=False) border_color: ray.Color = field(init=False) cam_h_offset: float = field(init=False) cam_v_offset: float = field(init=False) @@ -729,8 +731,6 @@ class TJAParser: sudden_moving = 0 judge_pos_x = 0 judge_pos_y = 0 - judge_target_x = 0 - judge_target_y = 0 border_color = ray.BLACK cam_h_offset = 0 cam_v_offset = 0 @@ -1183,7 +1183,7 @@ class TJAParser: if len(parts) >= 4: duration_ms = float(parts[1]) * 1000 distance_str = parts[2] - direction = int(parts[3]) # 0 = normal, 1 = reverse + direction = int(parts[3]) delta_x = 0 delta_y = 0 if 'i' in distance_str: @@ -1196,27 +1196,32 @@ class TJAParser: distance = float(distance_str) delta_x = distance delta_y = 0 - if direction == 0: delta_x = -delta_x delta_y = -delta_y - judge_target_x = judge_pos_x + delta_x - judge_target_y = judge_pos_y + delta_y - interpolation_interval_ms = 8 - num_steps = int(duration_ms / interpolation_interval_ms) - for step in range(num_steps + 1): - t = step / max(num_steps, 1) - interpolated_ms = self.current_ms + (step * interpolation_interval_ms) - interp_x = judge_pos_x + (delta_x * t) - interp_y = judge_pos_y + (delta_y * t) - jpos_timeline = TimelineObject() - jpos_timeline.hit_ms = interpolated_ms - jpos_timeline.judge_pos_x = interp_x - jpos_timeline.judge_pos_y = interp_y - bisect.insort(curr_timeline, jpos_timeline, key=lambda x: x.hit_ms) - judge_pos_x = judge_target_x - judge_pos_y = judge_target_y + for obj in reversed(curr_timeline): + if hasattr(obj, 'delta_x') and hasattr(obj, 'delta_y'): + if obj.hit_ms > self.current_ms: + available_time = self.current_ms - obj.load_ms + total_duration = obj.hit_ms - obj.load_ms + ratio = min(1.0, available_time / total_duration) if total_duration > 0 else 1.0 + obj.delta_x *= ratio + obj.delta_y *= ratio + obj.hit_ms = self.current_ms + break + + jpos_scroll = TimelineObject() + jpos_scroll.load_ms = self.current_ms + jpos_scroll.hit_ms = self.current_ms + duration_ms + jpos_scroll.judge_pos_x = judge_pos_x + jpos_scroll.judge_pos_y = judge_pos_y + jpos_scroll.delta_x = delta_x + jpos_scroll.delta_y = delta_y + curr_timeline.append(jpos_scroll) + + judge_pos_x += delta_x + judge_pos_y += delta_y continue elif '#NMSCROLL' in part: scroll_type = ScrollType.NMSCROLL diff --git a/scenes/game.py b/scenes/game.py index c795070..bc37b87 100644 --- a/scenes/game.py +++ b/scenes/game.py @@ -532,14 +532,32 @@ class Player: self.timeline_index += 1 def get_judge_position(self, current_ms: float): - """Get the current judgment circle position based on bar data""" + """Get the current judgment circle position based on bar data with on-demand interpolation""" if not self.timeline or self.timeline_index >= len(self.timeline): return + timeline_object = self.timeline[self.timeline_index] - if hasattr(timeline_object, 'judge_pos_x') and timeline_object.hit_ms <= current_ms: - self.judge_x = timeline_object.judge_pos_x * tex.screen_scale - self.judge_y = timeline_object.judge_pos_y * tex.screen_scale - self.timeline_index += 1 + + if hasattr(timeline_object, 'delta_x'): + if timeline_object.load_ms <= current_ms <= timeline_object.hit_ms: + duration = timeline_object.hit_ms - timeline_object.load_ms + if duration > 0: + t = (current_ms - timeline_object.load_ms) / duration + t = max(0.0, min(1.0, t)) + + self.judge_x = (timeline_object.judge_pos_x + (timeline_object.delta_x * t)) * tex.screen_scale + self.judge_y = (timeline_object.judge_pos_y + (timeline_object.delta_y * t)) * tex.screen_scale + else: + self.judge_x = (timeline_object.judge_pos_x + timeline_object.delta_x) * tex.screen_scale + self.judge_y = (timeline_object.judge_pos_y + timeline_object.delta_y) * tex.screen_scale + + if current_ms > timeline_object.hit_ms: + self.timeline_index += 1 + if self.timeline_index < len(self.timeline): + next_timeline_object = self.timeline[self.timeline_index] + if hasattr(next_timeline_object, 'delta_x'): + next_timeline_object.judge_pos_x = self.judge_x / tex.screen_scale + next_timeline_object.judge_pos_y = self.judge_y / tex.screen_scale def handle_scroll_type_commands(self, current_ms: float): if not self.timeline or self.timeline_index >= len(self.timeline):