mirror of
https://github.com/Yonokid/PyTaiko.git
synced 2026-02-04 03:30:13 +01:00
tja parser refactor
This commit is contained in:
246
libs/tja2.py
246
libs/tja2.py
@@ -1,37 +1,19 @@
|
||||
import bisect
|
||||
from enum import IntEnum
|
||||
import hashlib
|
||||
from dataclasses import dataclass, field, fields
|
||||
|
||||
from libs.tja import NoteList, TJAParser, TimelineObject, get_ms_per_measure
|
||||
|
||||
class NoteType(IntEnum):
|
||||
NONE = 0
|
||||
DON = 1
|
||||
KAT = 2
|
||||
DON_L = 3
|
||||
KAT_L = 4
|
||||
ROLL_HEAD = 5
|
||||
ROLL_HEAD_L = 6
|
||||
BALLOON_HEAD = 7
|
||||
TAIL = 8
|
||||
KUSUDAMA = 9
|
||||
|
||||
class ScrollType(IntEnum):
|
||||
NMSCROLL = 0
|
||||
BMSCROLL = 1
|
||||
HBSCROLL = 2
|
||||
from libs.tja import NoteList, ScrollType, TJAParser, TimelineObject, get_ms_per_measure
|
||||
|
||||
@dataclass()
|
||||
class Note:
|
||||
type: int = field(init=False)
|
||||
hit_ms: float = field(init=False)
|
||||
display: bool = field(init=False)
|
||||
index: int = field(init=False)
|
||||
moji: int = field(init=False)
|
||||
bpm: float = field(init=False)
|
||||
scroll_x: float = field(init=False)
|
||||
scroll_y: float = field(init=False)
|
||||
display: bool = field(init=False)
|
||||
index: int = field(init=False)
|
||||
moji: int = field(init=False)
|
||||
|
||||
def __lt__(self, other):
|
||||
return self.hit_ms < other.hit_ms
|
||||
@@ -135,89 +117,140 @@ class Balloon(Note):
|
||||
return hash_string.encode('utf-8')
|
||||
|
||||
class TJAParser2(TJAParser):
|
||||
def _build_command_registry(self):
|
||||
"""Auto-discover command handlers based on naming convention."""
|
||||
registry = {}
|
||||
for name in dir(self):
|
||||
if name.startswith('handle_'):
|
||||
cmd_name = '#' + name[7:].upper()
|
||||
registry[cmd_name] = getattr(self, name)
|
||||
return registry
|
||||
|
||||
def handle_measure(self, part: str, state: dict):
|
||||
divisor = part.find('/')
|
||||
state["time_signature"] = float(part[9:divisor]) / float(part[divisor+1:])
|
||||
|
||||
def handle_scroll(self, part: str, state: dict):
|
||||
scroll_value = part[7:]
|
||||
if 'i' in scroll_value:
|
||||
normalized = scroll_value.replace('.i', 'j').replace('i', 'j')
|
||||
normalized = normalized.replace(',', '')
|
||||
c = complex(normalized)
|
||||
state["scroll_x_modifier"] = c.real
|
||||
state["scroll_y_modifier"] = c.imag
|
||||
else:
|
||||
state["scroll_x_modifier"] = float(scroll_value)
|
||||
state["scroll_y_modifier"] = 0.0
|
||||
|
||||
def handle_bpmchange(self, part: str, state: dict):
|
||||
parsed_bpm = float(part[11:])
|
||||
if state["scroll_type"] == ScrollType.BMSCROLL or state["scroll_type"] == ScrollType.HBSCROLL:
|
||||
# Do not modify bpm, it needs to be changed live by bpmchange
|
||||
bpmchange = parsed_bpm / state["bpmchange_last_bpm"]
|
||||
state["bpmchange_last_bpm"] = parsed_bpm
|
||||
|
||||
bpmchange_timeline = TimelineObject()
|
||||
bpmchange_timeline.hit_ms = self.current_ms
|
||||
bpmchange_timeline.bpmchange = bpmchange
|
||||
state["curr_timeline"].append(bpmchange_timeline)
|
||||
else:
|
||||
timeline_obj = TimelineObject()
|
||||
timeline_obj.hit_ms = self.current_ms
|
||||
timeline_obj.bpm = parsed_bpm
|
||||
state["bpm"] = parsed_bpm
|
||||
state["curr_timeline"].append(timeline_obj)
|
||||
|
||||
def add_bar(self, state: dict):
|
||||
bar_line = Note()
|
||||
|
||||
bar_line.hit_ms = self.current_ms
|
||||
bar_line.type = 0
|
||||
bar_line.display = state["barline_display"]
|
||||
bar_line.bpm = state["bpm"]
|
||||
bar_line.scroll_x = state["scroll_x_modifier"]
|
||||
bar_line.scroll_y = state["scroll_y_modifier"]
|
||||
|
||||
if state["barline_added"]:
|
||||
bar_line.display = False
|
||||
|
||||
return bar_line
|
||||
|
||||
def add_note(self, item: str, state: dict):
|
||||
note = Note()
|
||||
note.hit_ms = self.current_ms
|
||||
note.display = True
|
||||
note.type = int(item)
|
||||
note.index = state["index"]
|
||||
note.bpm = state["bpm"]
|
||||
note.scroll_x = state["scroll_x_modifier"]
|
||||
note.scroll_y = state["scroll_y_modifier"]
|
||||
|
||||
if item in {'5', '6'}:
|
||||
note = Drumroll(note)
|
||||
note.color = 255
|
||||
elif item in {'7', '9'}:
|
||||
state["balloon_index"] += 1
|
||||
if state["balloons"] is None:
|
||||
raise Exception("Balloon note found, but no count was specified")
|
||||
if item == '9':
|
||||
note = Balloon(note, is_kusudama=True)
|
||||
else:
|
||||
note = Balloon(note)
|
||||
note.count = 1 if not state["balloons"] else state["balloons"].pop(0)
|
||||
elif item == '8':
|
||||
if state["prev_note"] is None:
|
||||
raise ValueError("No previous note found")
|
||||
|
||||
return note
|
||||
|
||||
def notes_to_position(self, diff: int):
|
||||
"""Parse a TJA's notes into a NoteList."""
|
||||
commands = self._build_command_registry()
|
||||
master_notes = NoteList()
|
||||
notes = self.data_to_notes(diff)
|
||||
balloon = self.metadata.course_data[diff].balloon.copy()
|
||||
count = 0
|
||||
index = 0
|
||||
time_signature = 4/4
|
||||
bpm = self.metadata.bpm
|
||||
scroll_x_modifier = 1
|
||||
scroll_y_modifier = 0
|
||||
barline_display = True
|
||||
curr_note_list = master_notes.play_notes
|
||||
curr_draw_list = master_notes.draw_notes
|
||||
curr_bar_list = master_notes.bars
|
||||
curr_timeline = master_notes.timeline
|
||||
|
||||
state = {
|
||||
'time_signature': 4/4,
|
||||
'bpm': self.metadata.bpm,
|
||||
'scroll_x_modifier': 1,
|
||||
'scroll_y_modifier': 0,
|
||||
'scroll_type': ScrollType.NMSCROLL,
|
||||
'bpmchange_last_bpm': self.metadata.bpm,
|
||||
'barline_display': True,
|
||||
'curr_note_list': master_notes.play_notes,
|
||||
'curr_draw_list': master_notes.draw_notes,
|
||||
'curr_bar_list': master_notes.bars,
|
||||
'curr_timeline': master_notes.timeline,
|
||||
'index': 0,
|
||||
'balloons': self.metadata.course_data[diff].balloon.copy(),
|
||||
'balloon_index': 0,
|
||||
'prev_note': None,
|
||||
'barline_added': False
|
||||
}
|
||||
init_bpm = TimelineObject()
|
||||
init_bpm.hit_ms = self.current_ms
|
||||
init_bpm.bpm = bpm
|
||||
curr_timeline.append(init_bpm)
|
||||
prev_note = None
|
||||
scroll_type = ScrollType.NMSCROLL
|
||||
|
||||
bpmchange_last_bpm = bpm
|
||||
init_bpm.bpm = state['bpm']
|
||||
state['curr_timeline'].append(init_bpm)
|
||||
|
||||
for bar in notes:
|
||||
bar_length = sum(len(part) for part in bar if '#' not in part)
|
||||
barline_added = False
|
||||
state['barline_added'] = False
|
||||
|
||||
for part in bar:
|
||||
if '#MEASURE' in part:
|
||||
divisor = part.find('/')
|
||||
time_signature = float(part[9:divisor]) / float(part[divisor+1:])
|
||||
continue
|
||||
elif '#SCROLL' in part:
|
||||
if scroll_type != ScrollType.BMSCROLL:
|
||||
scroll_value = part[7:]
|
||||
if 'i' in scroll_value:
|
||||
normalized = scroll_value.replace('.i', 'j').replace('i', 'j')
|
||||
normalized = normalized.replace(',', '')
|
||||
c = complex(normalized)
|
||||
scroll_x_modifier = c.real
|
||||
scroll_y_modifier = c.imag
|
||||
else:
|
||||
scroll_x_modifier = float(scroll_value)
|
||||
scroll_y_modifier = 0.0
|
||||
continue
|
||||
elif '#BPMCHANGE' in part:
|
||||
parsed_bpm = float(part[11:])
|
||||
if scroll_type == ScrollType.BMSCROLL or scroll_type == ScrollType.HBSCROLL:
|
||||
# Do not modify bpm, it needs to be changed live by bpmchange
|
||||
bpmchange = parsed_bpm / bpmchange_last_bpm
|
||||
bpmchange_last_bpm = parsed_bpm
|
||||
|
||||
bpmchange_timeline = TimelineObject()
|
||||
bpmchange_timeline.hit_ms = self.current_ms
|
||||
bpmchange_timeline.bpmchange = bpmchange
|
||||
bisect.insort(curr_timeline, bpmchange_timeline, key=lambda x: x.hit_ms)
|
||||
else:
|
||||
timeline_obj = TimelineObject()
|
||||
timeline_obj.hit_ms = self.current_ms
|
||||
timeline_obj.bpm = parsed_bpm
|
||||
bpm = parsed_bpm
|
||||
bisect.insort(curr_timeline, timeline_obj, key=lambda x: x.hit_ms)
|
||||
if part.startswith('#'):
|
||||
for cmd_prefix, handler in commands.items():
|
||||
if part.startswith(cmd_prefix):
|
||||
handler(part, state)
|
||||
break
|
||||
continue
|
||||
elif len(part) > 0 and not part[0].isdigit():
|
||||
continue
|
||||
|
||||
ms_per_measure = get_ms_per_measure(bpm, time_signature)
|
||||
bar_line = Note()
|
||||
ms_per_measure = get_ms_per_measure(state["bpm"], state["time_signature"])
|
||||
|
||||
bar_line.hit_ms = self.current_ms
|
||||
bar_line.type = 0
|
||||
bar_line.display = barline_display
|
||||
bar_line.bpm = bpm
|
||||
bar_line.scroll_x = scroll_x_modifier
|
||||
bar_line.scroll_y = scroll_y_modifier
|
||||
|
||||
if barline_added:
|
||||
bar_line.display = False
|
||||
|
||||
curr_bar_list.append(bar_line)
|
||||
barline_added = True
|
||||
bar = self.add_bar(state)
|
||||
state["curr_bar_list"].append(bar)
|
||||
state["barline_added"] = True
|
||||
|
||||
if len(part) == 0:
|
||||
self.current_ms += ms_per_measure
|
||||
@@ -230,36 +263,13 @@ class TJAParser2(TJAParser):
|
||||
self.current_ms += increment
|
||||
continue
|
||||
|
||||
note = Note()
|
||||
note.hit_ms = self.current_ms
|
||||
note.display = True
|
||||
note.type = int(item)
|
||||
note.index = index
|
||||
note.bpm = bpm
|
||||
note.scroll_x = scroll_x_modifier
|
||||
note.scroll_y = scroll_y_modifier
|
||||
|
||||
if item in {'5', '6'}:
|
||||
note = Drumroll(note)
|
||||
note.color = 255
|
||||
elif item in {'7', '9'}:
|
||||
count += 1
|
||||
if balloon is None:
|
||||
raise Exception("Balloon note found, but no count was specified")
|
||||
if item == '9':
|
||||
note = Balloon(note, is_kusudama=True)
|
||||
else:
|
||||
note = Balloon(note)
|
||||
note.count = 1 if not balloon else balloon.pop(0)
|
||||
elif item == '8':
|
||||
if prev_note is None:
|
||||
raise ValueError("No previous note found")
|
||||
note = self.add_note(item, state)
|
||||
|
||||
self.current_ms += increment
|
||||
curr_note_list.append(note)
|
||||
curr_draw_list.append(note)
|
||||
self.get_moji(curr_note_list, ms_per_measure)
|
||||
index += 1
|
||||
prev_note = note
|
||||
state["curr_note_list"].append(note)
|
||||
state["curr_draw_list"].append(note)
|
||||
self.get_moji(state["curr_note_list"], ms_per_measure)
|
||||
state["index"] += 1
|
||||
state["prev_note"] = note
|
||||
|
||||
return master_notes, [master_notes], [master_notes], [master_notes]
|
||||
|
||||
@@ -59,6 +59,7 @@ class Judgments(IntEnum):
|
||||
|
||||
class GameScreen(Screen):
|
||||
JUDGE_X = 414 * tex.screen_scale
|
||||
JUDGE_Y = 256 * tex.screen_scale
|
||||
def on_screen_start(self):
|
||||
super().on_screen_start()
|
||||
self.mask_shader = ray.load_shader("shader/outline.vs", "shader/mask.fs")
|
||||
@@ -879,8 +880,8 @@ class Player:
|
||||
if self.is_drumroll:
|
||||
self.check_drumroll(drum_type, background, current_time)
|
||||
elif self.is_balloon:
|
||||
if not isinstance(curr_note, Balloon):
|
||||
raise Exception("Balloon mode entered but current note is not balloon")
|
||||
#if not isinstance(curr_note, Balloon):
|
||||
#raise Exception("Balloon mode entered but current note is not balloon")
|
||||
self.check_balloon(drum_type, curr_note, current_time)
|
||||
else:
|
||||
self.curr_drumroll_count = 0
|
||||
|
||||
@@ -5,20 +5,16 @@ from enum import IntEnum
|
||||
import math
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
from itertools import chain
|
||||
|
||||
import pyray as ray
|
||||
|
||||
from libs.audio import audio
|
||||
from libs.background import Background
|
||||
from libs.texture import tex
|
||||
from libs.tja import (
|
||||
from libs.tja import calculate_base_score, NoteType
|
||||
from libs.tja2 import (
|
||||
Balloon,
|
||||
Drumroll,
|
||||
Note,
|
||||
NoteType,
|
||||
calculate_base_score,
|
||||
)
|
||||
from libs.utils import (
|
||||
get_current_ms,
|
||||
@@ -97,24 +93,21 @@ class Player2(Player):
|
||||
self.end_time = self.play_notes[-1].hit_ms
|
||||
|
||||
def get_position_x(self, note, current_ms):
|
||||
judge_line_x = 414
|
||||
return judge_line_x + ((note.hit_ms - current_ms) / 1000.0) * 866 * note.scroll_x
|
||||
speedx = note.bpm / 240000 * note.scroll_x * (tex.screen_width - GameScreen.JUDGE_X) * tex.screen_scale
|
||||
return GameScreen.JUDGE_X + (note.hit_ms - current_ms) * speedx
|
||||
|
||||
|
||||
def get_position_y(self):
|
||||
return 0
|
||||
def get_position_y(self, note, current_ms):
|
||||
speedy = note.bpm / 240000 * note.scroll_y * (tex.screen_width - GameScreen.JUDGE_Y) * tex.screen_scale
|
||||
return (note.hit_ms - current_ms) * speedy
|
||||
|
||||
def bar_manager(self, current_ms: float):
|
||||
"""Manages the bars and removes if necessary
|
||||
Also sets branch conditions"""
|
||||
#Add bar to current_bars list if it is ready to be shown on screen
|
||||
if self.draw_bar_list and current_ms + 1000 > self.draw_bar_list[0].hit_ms:
|
||||
if self.draw_bar_list and current_ms >= self.draw_bar_list[0].hit_ms - 10000:
|
||||
self.current_bars.append(self.draw_bar_list.popleft())
|
||||
|
||||
|
||||
if self.current_bars and self.current_bars[0].hit_ms < current_ms + 1000:
|
||||
self.current_bars.pop(0)
|
||||
|
||||
def draw_note_manager(self, current_ms: float):
|
||||
"""Manages the draw_notes and removes if necessary"""
|
||||
if self.draw_note_list and current_ms >= self.draw_note_list[0].hit_ms - 10000:
|
||||
@@ -139,32 +132,27 @@ class Player2(Player):
|
||||
note = self.current_notes_draw[0]
|
||||
if note.type in {NoteType.ROLL_HEAD, NoteType.ROLL_HEAD_L, NoteType.BALLOON_HEAD, NoteType.KUSUDAMA} and len(self.current_notes_draw) > 1:
|
||||
note = self.current_notes_draw[1]
|
||||
if current_ms > note.hit_ms + 200:
|
||||
if note.type == NoteType.TAIL:
|
||||
self.current_notes_draw.pop(0)
|
||||
if self.get_position_x(note, current_ms) < GameScreen.JUDGE_X:
|
||||
self.current_notes_draw.pop(0)
|
||||
|
||||
def draw_drumroll(self, current_ms: float, head: Drumroll, current_eighth: int):
|
||||
"""Draws a drumroll in the player's lane"""
|
||||
start_position = self.get_position_x(head, current_ms)
|
||||
start_position += self.judge_x
|
||||
tail = next((note for note in self.current_notes_draw[1:] if note.type == NoteType.TAIL and note.index > head.index), self.current_notes_draw[1])
|
||||
is_big = int(head.type == NoteType.ROLL_HEAD_L)
|
||||
end_position = self.get_position_x(tail, current_ms)
|
||||
end_position += self.judge_x
|
||||
length = end_position - start_position
|
||||
color = ray.Color(255, head.color, head.color, 255)
|
||||
y = tex.skin_config["notes"].y + self.get_position_y()
|
||||
y = tex.skin_config["notes"].y + self.get_position_y(head, current_ms)
|
||||
moji_y = tex.skin_config["moji"].y
|
||||
moji_x = -(tex.textures["notes"]["moji"].width//2) + (tex.textures["notes"]["1"].width//2)
|
||||
if head.display:
|
||||
if length > 0:
|
||||
tex.draw_texture('notes', "8", frame=is_big, x=start_position+(tex.textures["notes"]["5"].width//2), y=y+(self.is_2p*tex.skin_config["2p_offset"].y)+self.judge_y, x2=length+tex.skin_config["drumroll_width_offset"].width, color=color)
|
||||
if is_big:
|
||||
tex.draw_texture('notes', "drumroll_big_tail", x=end_position+tex.textures["notes"]["5"].width//2, y=y+(self.is_2p*tex.skin_config["2p_offset"].y)+self.judge_y, color=color)
|
||||
else:
|
||||
tex.draw_texture('notes', "drumroll_tail", x=end_position+tex.textures["notes"]["5"].width//2, y=y+(self.is_2p*tex.skin_config["2p_offset"].y)+self.judge_y, color=color)
|
||||
tex.draw_texture('notes', str(head.type), frame=current_eighth % 2, x=start_position, y=y+(self.is_2p*tex.skin_config["2p_offset"].y)+self.judge_y, color=color)
|
||||
tex.draw_texture('notes', "8", frame=is_big, x=start_position, y=y+(self.is_2p*tex.skin_config["2p_offset"].y)+self.judge_y, x2=length+tex.skin_config["drumroll_width_offset"].width, color=color)
|
||||
if is_big:
|
||||
tex.draw_texture('notes', "drumroll_big_tail", x=end_position, y=y+(self.is_2p*tex.skin_config["2p_offset"].y)+self.judge_y, color=color)
|
||||
else:
|
||||
tex.draw_texture('notes', "drumroll_tail", x=end_position, y=y+(self.is_2p*tex.skin_config["2p_offset"].y)+self.judge_y, color=color)
|
||||
tex.draw_texture('notes', str(head.type), frame=current_eighth % 2, x=start_position - tex.textures["notes"]["1"].width//2, y=y+(self.is_2p*tex.skin_config["2p_offset"].y)+self.judge_y, color=color)
|
||||
|
||||
tex.draw_texture('notes', 'moji_drumroll_mid', x=start_position + tex.textures["notes"]["1"].width//2, y=moji_y+(self.is_2p*tex.skin_config["2p_offset"].y)+self.judge_y, x2=length)
|
||||
tex.draw_texture('notes', 'moji', frame=head.moji, x=start_position + moji_x, y=moji_y+(self.is_2p*tex.skin_config["2p_offset"].y)+self.judge_y)
|
||||
@@ -174,12 +162,10 @@ class Player2(Player):
|
||||
"""Draws a balloon in the player's lane"""
|
||||
offset = tex.skin_config["balloon_offset"].x
|
||||
start_position = self.get_position_x(head, current_ms)
|
||||
start_position += self.judge_x
|
||||
tail = next((note for note in self.current_notes_draw[1:] if note.type == NoteType.TAIL and note.index > head.index), self.current_notes_draw[1])
|
||||
end_position = self.get_position_x(tail, current_ms)
|
||||
end_position += self.judge_x
|
||||
pause_position = tex.skin_config["balloon_pause_position"].x + self.judge_x
|
||||
y = tex.skin_config["notes"].y + self.get_position_y()
|
||||
pause_position = GameScreen.JUDGE_X
|
||||
y = tex.skin_config["notes"].y + self.get_position_y(head, current_ms)
|
||||
if current_ms >= tail.hit_ms:
|
||||
position = end_position
|
||||
elif current_ms >= head.hit_ms:
|
||||
@@ -187,8 +173,8 @@ class Player2(Player):
|
||||
else:
|
||||
position = start_position
|
||||
if head.display:
|
||||
tex.draw_texture('notes', str(head.type), frame=current_eighth % 2, x=position-offset, y=y+(self.is_2p*tex.skin_config["2p_offset"].y)+self.judge_y)
|
||||
tex.draw_texture('notes', '10', frame=current_eighth % 2, x=position-offset+tex.textures["notes"]["10"].width, y=y+(self.is_2p*tex.skin_config["2p_offset"].y)+self.judge_y)
|
||||
tex.draw_texture('notes', str(head.type), frame=current_eighth % 2, x=position-offset - tex.textures["notes"]["1"].width//2, y=y+(self.is_2p*tex.skin_config["2p_offset"].y)+self.judge_y)
|
||||
tex.draw_texture('notes', '10', frame=current_eighth % 2, x=position-offset+tex.textures["notes"]["10"].width - tex.textures["notes"]["1"].width//2, y=y+(self.is_2p*tex.skin_config["2p_offset"].y)+self.judge_y)
|
||||
|
||||
def draw_bars(self, current_ms: float):
|
||||
"""Draw bars in the player's lane"""
|
||||
@@ -199,12 +185,12 @@ class Player2(Player):
|
||||
if not bar.display:
|
||||
continue
|
||||
x_position = self.get_position_x(bar, current_ms)
|
||||
y_position = self.get_position_y()
|
||||
y_position = self.get_position_y(bar, current_ms)
|
||||
if y_position != 0:
|
||||
angle = math.degrees(math.atan2(bar.pixels_per_frame_y, bar.pixels_per_frame_x))
|
||||
angle = math.degrees(math.atan2(bar.scroll_y, bar.scroll_x))
|
||||
else:
|
||||
angle = 0
|
||||
tex.draw_texture('notes', str(bar.type), x=x_position+tex.skin_config["moji_drumroll"].x, y=y_position+tex.skin_config["moji_drumroll"].y+(self.is_2p*tex.skin_config["2p_offset"].y), rotation=angle)
|
||||
tex.draw_texture('notes', str(bar.type), x=x_position+tex.skin_config["moji_drumroll"].x- (tex.textures["notes"]["1"].width//2), y=y_position+tex.skin_config["moji_drumroll"].y+(self.is_2p*tex.skin_config["2p_offset"].y), rotation=angle)
|
||||
|
||||
|
||||
def draw_notes(self, current_ms: float, start_ms: float):
|
||||
@@ -220,14 +206,12 @@ class Player2(Player):
|
||||
|
||||
current_eighth = 0
|
||||
x_position = self.get_position_x(note, current_ms)
|
||||
y_position = self.get_position_y()
|
||||
y_position = self.get_position_y(note, current_ms)
|
||||
if isinstance(note, Drumroll):
|
||||
pass
|
||||
#self.draw_drumroll(current_ms, note, current_eighth)
|
||||
self.draw_drumroll(current_ms, note, current_eighth)
|
||||
elif isinstance(note, Balloon) and not note.is_kusudama:
|
||||
pass
|
||||
#self.draw_balloon(current_ms, note, current_eighth)
|
||||
#tex.draw_texture('notes', 'moji', frame=note.moji, x=x_position, y=tex.skin_config["moji"].y + y_position+(self.is_2p*tex.skin_config["2p_offset"].y))
|
||||
self.draw_balloon(current_ms, note, current_eighth)
|
||||
tex.draw_texture('notes', 'moji', frame=note.moji, x=x_position, y=tex.skin_config["moji"].y + y_position+(self.is_2p*tex.skin_config["2p_offset"].y))
|
||||
else:
|
||||
if note.display:
|
||||
tex.draw_texture('notes', str(note.type), frame=current_eighth % 2, x=x_position - (tex.textures["notes"]["1"].width//2), y=y_position+tex.skin_config["notes"].y+(self.is_2p*tex.skin_config["2p_offset"].y), center=True)
|
||||
|
||||
Reference in New Issue
Block a user