This commit is contained in:
mc08
2025-11-28 18:42:05 -08:00
7 changed files with 558 additions and 126 deletions

View File

@@ -1,4 +1,3 @@
from pathlib import Path
import pyray as ray
from libs.screen import Screen
@@ -8,12 +7,6 @@ from libs.texture import tex
class DevScreen(Screen):
def on_screen_start(self):
super().on_screen_start()
self.text = ".⁉ゃん座組ス5れへデ7x事音ょ野ダHズパに相村束虹神狂'Uqはたt朗♢弥ウち”作Wシら黒さドカモ金章よ方りj沙べ口ぃご歌こ制みわ険時行×ワ獣ぺ阿啓R哀肉乱終鼓ツ,0かVしでw?2⒒悟マ乙ィの女アラA疾浄u+も’グ怒[ャロ冒陽ね路想ベ#ト醜ペ!太悪χキn初あKン〜<原Qハ1s旅をガ分ビNゼ玄沢≠食@フ拝テM豚幻濤ま人腹世P愴)っピやナJ社びB一6c畑譚]gてd曲花Oくkル第◇校*⒓森・バコ談ヤ急め愛プ重ー勝DE:Zチ東二じ車>ブ刑ミX焼おyつλ♪オい憎aFe竜そ大84得渉/◆ソC番、l†レ悲暴う胸るG“ゆS転fゅとセo「風輔双zr―-vケp‼b…響3メ罪 クL自(Iイタニムき夜幽T&楽m学走ジ島h田i美心Yボサッリュひ寅9」達"
unique_codepoints = set(self.text)
codepoint_count = ray.ffi.new('int *', 0)
unique_string = ''.join(unique_codepoints)
codepoints = ray.load_codepoints(unique_string, codepoint_count)
self.font = ray.load_font_ex(str(Path('Graphics/Modified-DFPKanteiryu-XB.ttf')), 40, codepoints, len(unique_codepoints))
def on_screen_end(self, next_screen: str):
return super().on_screen_end(next_screen)
@@ -23,4 +16,3 @@ class DevScreen(Screen):
def draw(self):
ray.draw_rectangle(0, 0, tex.screen_width, tex.screen_height, ray.GREEN)
ray.draw_text_ex(self.font, "幽玄ノ乱", ray.Vector2(tex.screen_width//2, tex.screen_height//2), 60, 20, ray.BLACK)

View File

@@ -445,6 +445,8 @@ class Player:
self.base_score = calculate_base_score(total_notes)
#Note management
self.timeline = notes.timeline
self.timeline_index = 0
self.current_bars: list[Note] = []
self.current_notes_draw: list[Note | Drumroll | Balloon] = []
self.is_drumroll = False
@@ -456,7 +458,9 @@ class Player:
self.branch_condition_count = 0
self.branch_condition = ''
self.balloon_index = 0
self.bpm = self.play_notes[0].bpm if self.play_notes else 120
self.bpm = 120
if self.timeline and hasattr(self.timeline[self.timeline_index], 'bpm'):
self.bpm = self.timeline[self.timeline_index].bpm
def merge_branch_section(self, branch_section: NoteList, current_ms: float):
"""Merges the branch notes into the current notes"""
@@ -492,35 +496,80 @@ class Player:
if self.delay_start:
current_ms = self.delay_start
time_diff = load_ms - current_ms
if pixels_per_frame_x == 0:
return int(pixels_per_frame * 0.06 * time_diff)
return int((pixels_per_frame * 0.06 * time_diff) + ((self.tja.distance * pixels_per_frame) / pixels_per_frame_x))
def handle_tjap3_extended_commands(self, current_ms: float):
if not self.timeline:
return
timeline_object = self.timeline[self.timeline_index]
should_advance = False
if hasattr(timeline_object, 'border_color') and timeline_object.hit_ms <= current_ms:
global_data.camera.border_color = timeline_object.border_color
should_advance = True
if hasattr(timeline_object, 'cam_h_offset') and timeline_object.hit_ms <= current_ms:
orig_offset = global_data.camera.offset
global_data.camera.offset = ray.Vector2(timeline_object.cam_h_offset, orig_offset.y)
should_advance = True
if hasattr(timeline_object, 'cam_v_offset') and timeline_object.hit_ms <= current_ms:
orig_offset = global_data.camera.offset
global_data.camera.offset = ray.Vector2(orig_offset.x, timeline_object.cam_v_offset)
should_advance = True
if hasattr(timeline_object, 'cam_zoom') and timeline_object.hit_ms <= current_ms:
global_data.camera.zoom = timeline_object.cam_zoom
should_advance = True
if hasattr(timeline_object, 'cam_h_scale') and timeline_object.hit_ms <= current_ms:
global_data.camera.h_scale = timeline_object.cam_h_scale
should_advance = True
if hasattr(timeline_object, 'cam_v_scale') and timeline_object.hit_ms <= current_ms:
global_data.camera.v_scale = timeline_object.cam_v_scale
should_advance = True
if hasattr(timeline_object, 'cam_rotation') and timeline_object.hit_ms <= current_ms:
global_data.camera.rotation = timeline_object.cam_rotation
should_advance = True
if should_advance and self.timeline_index < len(self.timeline) - 1:
self.timeline_index += 1
def get_judge_position(self, current_ms: float):
"""Get the current judgment circle position based on bar data"""
judge_x = 0
judge_y = 0
if not 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
if self.timeline_index < len(self.timeline) - 1:
self.timeline_index += 1
# Find the most recent bar with judge position data
for bar in self.current_bars:
if hasattr(bar, 'judge_pos_x') and bar.hit_ms <= current_ms:
judge_x = bar.judge_pos_x * tex.screen_scale
judge_y = bar.judge_pos_y * tex.screen_scale
elif bar.hit_ms > current_ms:
break
return judge_x, judge_y
def update_bpm(self, current_ms: float):
if not self.timeline:
return
timeline_object = self.timeline[self.timeline_index]
if hasattr(timeline_object, 'bpm') and timeline_object.hit_ms <= current_ms:
self.bpm = timeline_object.bpm
if self.timeline_index < len(self.timeline) - 1:
self.timeline_index += 1
def animation_manager(self, animation_list: list, current_time: float):
if not animation_list:
return
# More efficient: use list comprehension to filter out finished animations
remaining_animations = []
for animation in animation_list:
animation.update(current_time)
if not animation.is_finished:
remaining_animations.append(animation)
# Replace the original list contents
animation_list[:] = remaining_animations
def bar_manager(self, current_ms: float):
@@ -678,6 +727,7 @@ class Player:
self.bar_manager(current_ms)
self.play_note_manager(current_ms, background)
self.draw_note_manager(current_ms)
self.handle_tjap3_extended_commands(current_ms)
def note_correct(self, note: Note, current_time: float):
"""Removes a note from the appropriate separated list"""
@@ -902,14 +952,10 @@ class Player:
# Handle drumroll and balloon hits
if self.is_drumroll or self.is_balloon:
if not self.other_notes:
return
note = self.other_notes[0]
bpm = note.bpm
if bpm == 0:
if self.bpm == 0:
subdivision_in_ms = 0
else:
subdivision_in_ms = ms_from_start // ((60000 * 4 / bpm) / 24)
subdivision_in_ms = ms_from_start // ((60000 * 4 / self.bpm) / 24)
if subdivision_in_ms > self.last_subdivision:
self.last_subdivision = subdivision_in_ms
hit_type = DrumType.DON
@@ -920,7 +966,6 @@ class Player:
else:
# Handle DON notes
while self.don_notes and ms_from_start >= self.don_notes[0].hit_ms:
note = self.don_notes[0]
hit_type = DrumType.DON
self.autoplay_hit_side = Side.RIGHT if self.autoplay_hit_side == Side.LEFT else Side.LEFT
self.spawn_hit_effects(hit_type, self.autoplay_hit_side)
@@ -929,7 +974,6 @@ class Player:
# Handle KAT notes
while self.kat_notes and ms_from_start >= self.kat_notes[0].hit_ms:
note = self.kat_notes[0]
hit_type = DrumType.KAT
self.autoplay_hit_side = Side.RIGHT if self.autoplay_hit_side == Side.LEFT else Side.LEFT
self.spawn_hit_effects(hit_type, self.autoplay_hit_side)
@@ -1029,7 +1073,9 @@ class Player:
if self.lane_hit_effect is not None:
self.lane_hit_effect.update(current_time)
self.animation_manager(self.draw_drum_hit_list, current_time)
self.judge_x, self.judge_y = self.get_judge_position(ms_from_start)
self.get_judge_position(ms_from_start)
self.handle_tjap3_extended_commands(ms_from_start)
self.update_bpm(ms_from_start)
# More efficient arc management
finished_arcs = []
@@ -1073,7 +1119,6 @@ class Player:
next_note = min(candidates, key=lambda note: note.load_ms)
if next_note:
self.bpm = next_note.bpm
if next_note.gogo_time and not self.is_gogo_time:
self.is_gogo_time = True
self.gogo_time = GogoTime(self.is_2p)