From 2c09360bfd5efdfb8fb5783e3fcb4fec3ef99b1b Mon Sep 17 00:00:00 2001 From: Anthony Samms Date: Wed, 24 Dec 2025 15:06:59 -0500 Subject: [PATCH] add more english --- dan_creator.py => dev/dan_creator.py | 0 libs/file_navigator.py | 5 ++++- libs/global_objects.py | 10 ++++++---- libs/texture.py | 7 ++++--- libs/utils.py | 18 ++++++++++++------ scenes/entry.py | 6 +++--- scenes/game.py | 2 +- scenes/song_select.py | 6 ++++-- scenes/title.py | 13 ++++++++----- 9 files changed, 42 insertions(+), 25 deletions(-) rename dan_creator.py => dev/dan_creator.py (100%) diff --git a/dan_creator.py b/dev/dan_creator.py similarity index 100% rename from dan_creator.py rename to dev/dan_creator.py diff --git a/libs/file_navigator.py b/libs/file_navigator.py index 7177453..9fc076b 100644 --- a/libs/file_navigator.py +++ b/libs/file_navigator.py @@ -120,7 +120,10 @@ class BaseBox(): self.wait = 0 def load_text(self): - self.name = OutlinedText(self.text_name, tex.skin_config["song_box_name"].font_size, ray.WHITE, outline_thickness=5, vertical=True) + font_size = tex.skin_config["song_box_name"].font_size + if len(self.text_name) >= 30: + font_size -= int(10 * tex.screen_scale) + self.name = OutlinedText(self.text_name, font_size, ray.WHITE, outline_thickness=5, vertical=True) if self.back_color is not None: self.shader = ray.load_shader('shader/dummy.vs', 'shader/colortransform.fs') source_rgb = (142, 212, 30) diff --git a/libs/global_objects.py b/libs/global_objects.py index ab70600..2470116 100644 --- a/libs/global_objects.py +++ b/libs/global_objects.py @@ -3,6 +3,7 @@ from typing import Callable import pyray as ray from libs.global_data import PlayerNum +from libs.global_data import global_data from libs.utils import OutlinedText, global_tex from libs.config import get_config from libs.audio import audio @@ -98,6 +99,7 @@ class Indicator: self.don_fade = global_tex.get_animation(6) self.blue_arrow_move = global_tex.get_animation(7) self.blue_arrow_fade = global_tex.get_animation(8) + self.select_text = OutlinedText(global_tex.skin_config["indicator_text"].text[global_data.config["general"]["language"]], global_tex.skin_config["indicator_text"].font_size, ray.WHITE, spacing=-3) def update(self, current_time_ms: float): """Update the indicator's animations.""" @@ -109,7 +111,8 @@ class Indicator: """Draw the indicator at the given position with the given fade.""" tex = global_tex tex.draw_texture('indicator', 'background', x=x, y=y, fade=fade) - tex.draw_texture('indicator', 'text', frame=self.state.value, x=x, y=y, fade=fade) + tex.draw_texture('indicator', 'text', frame=self.state.value, x=x, y=y, fade=fade, color=ray.BLACK) + self.select_text.draw(ray.BLANK, x=x+global_tex.skin_config["indicator_text"].x, y=y, fade=fade) tex.draw_texture('indicator', 'drum_face', index=self.state.value, x=x, y=y, fade=fade) if self.state == Indicator.State.SELECT: tex.draw_texture('indicator', 'drum_kat', fade=min(fade, self.don_fade.attribute), x=x, y=y) @@ -127,15 +130,14 @@ class CoinOverlay: """Coin overlay for the game.""" def __init__(self): """Initialize the coin overlay.""" - pass + self.free_play = OutlinedText(global_tex.skin_config["free_play"].text[global_data.config["general"]["language"]], global_tex.skin_config["free_play"].font_size, ray.WHITE, spacing=5, outline_thickness=4) def update(self, current_time_ms: float): """Update the coin overlay. Unimplemented""" pass def draw(self, x: int = 0, y: int = 0): """Draw the coin overlay. Only draws free play for now.""" - tex = global_tex - tex.draw_texture('overlay', 'free_play', x=x, y=y) + self.free_play.draw(ray.BLACK, x=global_tex.screen_width//2 - self.free_play.texture.width//2, y=global_tex.skin_config["free_play"].y) class AllNetIcon: """All.Net status icon for the game.""" diff --git a/libs/texture.py b/libs/texture.py index 300287b..3e4d18a 100644 --- a/libs/texture.py +++ b/libs/texture.py @@ -15,12 +15,13 @@ from libs.config import get_config logger = logging.getLogger(__name__) class SkinInfo: - def __init__(self, x: float, y: float, font_size: int, width: float, height: float): + def __init__(self, x: float, y: float, font_size: int, width: float, height: float, text: dict[str, str]): self.x = x self.y = y self.width = width self.height = height self.font_size = font_size + self.text = text def __repr__(self): return f"{self.__dict__}" @@ -78,7 +79,7 @@ class TextureWrapper: data = json.loads((self.graphics_path / "skin_config.json").read_text()) self.skin_config: dict[str, SkinInfo] = { - k: SkinInfo(v.get('x', 0), v.get('y', 0), v.get('font_size', 0), v.get('width', 0), v.get('height', 0)) for k, v in data.items() + k: SkinInfo(v.get('x', 0), v.get('y', 0), v.get('font_size', 0), v.get('width', 0), v.get('height', 0), v.get('text', dict())) for k, v in data.items() } self.screen_width = int(self.skin_config["screen"].width) self.screen_height = int(self.skin_config["screen"].height) @@ -88,7 +89,7 @@ class TextureWrapper: self.parent_graphics_path = Path("Skins") / parent parent_data = json.loads((self.parent_graphics_path / "skin_config.json").read_text()) for k, v in parent_data.items(): - self.skin_config[k] = SkinInfo(v.get('x', 0) * self.screen_scale, v.get('y', 0) * self.screen_scale, v.get('font_size', 0) * self.screen_scale, v.get('width', 0) * self.screen_scale, v.get('height', 0) * self.screen_scale) + self.skin_config[k] = SkinInfo(v.get('x', 0) * self.screen_scale, v.get('y', 0) * self.screen_scale, v.get('font_size', 0) * self.screen_scale, v.get('width', 0) * self.screen_scale, v.get('height', 0) * self.screen_scale, v.get('text', dict())) def unload_textures(self): """Unload all textures and animations.""" diff --git a/libs/utils.py b/libs/utils.py index 49012dc..e0cde8d 100644 --- a/libs/utils.py +++ b/libs/utils.py @@ -1,3 +1,4 @@ +import string import ctypes import hashlib import sys @@ -135,7 +136,7 @@ for file in Path('cache/image').iterdir(): class OutlinedText: """Create an outlined text object.""" - def __init__(self, text: str, font_size: int, color: ray.Color, outline_thickness=5.0, vertical=False): + def __init__(self, text: str, font_size: int, color: ray.Color, outline_thickness=5.0, vertical=False, spacing=1): """ Create an outlined text object. @@ -158,7 +159,7 @@ class OutlinedText: if vertical: self.texture = self._create_text_vertical(text, font_size, color, ray.BLANK, self.font) else: - self.texture = self._create_text_horizontal(text, font_size, color, ray.BLANK, self.font) + self.texture = self._create_text_horizontal(text, font_size, color, ray.BLANK, self.font, spacing=spacing) ray.gen_texture_mipmaps(self.texture) ray.set_texture_filter(self.texture, ray.TextureFilter.TEXTURE_FILTER_TRILINEAR) outline_size = ray.ffi.new('float*', self.outline_thickness) @@ -358,19 +359,25 @@ class OutlinedText: ray.unload_image(image) return texture - def _create_text_horizontal(self, text: str, font_size: int, color: ray.Color, bg_color: ray.Color, font: Optional[ray.Font]=None, padding: int=10): + def _create_text_horizontal(self, text: str, font_size: int, color: ray.Color, bg_color: ray.Color, font: Optional[ray.Font]=None, padding: int=10, spacing: int=1): if font: - text_size = ray.measure_text_ex(font, text, font_size, 0) + text_size = ray.measure_text_ex(font, text, font_size, spacing) + for char in text: + if char in string.whitespace: + text_size.x += 2 total_width = text_size.x + (padding * 2) total_height = text_size.y + (padding * 2) else: total_width = ray.measure_text(text, font_size) + (padding * 2) total_height = font_size + (padding * 2) + image = ray.gen_image_color(int(total_width), int(total_height), bg_color) + if font: - text_image = ray.image_text_ex(font, text, font_size, 0, color) + text_image = ray.image_text_ex(font, text, font_size, spacing, color) else: text_image = ray.image_text(text, font_size, color) + text_x = padding text_y = padding ray.image_draw(image, text_image, @@ -378,7 +385,6 @@ class OutlinedText: ray.Rectangle(text_x, text_y, text_image.width, text_image.height), ray.WHITE) ray.unload_image(text_image) - ray.export_image(image, f'cache/image/{self.hash}.png') texture = ray.load_texture_from_image(image) ray.unload_image(image) diff --git a/scenes/entry.py b/scenes/entry.py index 49c5cdd..1335488 100644 --- a/scenes/entry.py +++ b/scenes/entry.py @@ -439,9 +439,9 @@ class BoxManager: """BoxManager class for the entry screen""" def __init__(self): self.box_titles: list[OutlinedText] = [ - OutlinedText('演奏ゲーム', tex.skin_config["entry_box_text"].font_size, ray.WHITE, outline_thickness=5, vertical=True), - OutlinedText('特訓モード', tex.skin_config["entry_box_text"].font_size, ray.WHITE, outline_thickness=5, vertical=True), - OutlinedText('ゲーム設定', tex.skin_config["entry_box_text"].font_size, ray.WHITE, outline_thickness=5, vertical=True)] + OutlinedText(tex.skin_config["entry_game"].text[global_data.config["general"]["language"]], tex.skin_config["entry_box_text"].font_size, ray.WHITE, outline_thickness=5, vertical=True), + OutlinedText(tex.skin_config["entry_practice"].text[global_data.config["general"]["language"]], tex.skin_config["entry_box_text"].font_size, ray.WHITE, outline_thickness=5, vertical=True), + OutlinedText(tex.skin_config["entry_settings"].text[global_data.config["general"]["language"]], tex.skin_config["entry_box_text"].font_size, ray.WHITE, outline_thickness=5, vertical=True)] self.box_locations = ["SONG_SELECT", "PRACTICE_SELECT", "SETTINGS"] self.num_boxes = len(self.box_titles) self.boxes = [Box(self.box_titles[i], self.box_locations[i]) for i in range(len(self.box_titles))] diff --git a/scenes/game.py b/scenes/game.py index c44b838..578ddac 100644 --- a/scenes/game.py +++ b/scenes/game.py @@ -448,7 +448,7 @@ class Player: self.get_load_time(note) if note.type == NoteType.TAIL: note.load_ms = last_note.load_ms - note.unload_ms = last_note.unload_ms + last_note.unload_ms = note.unload_ms last_note = note self.draw_note_list = deque(sorted(self.draw_note_list, key=lambda n: n.load_ms)) diff --git a/scenes/song_select.py b/scenes/song_select.py index 0dd5e98..c42c2bb 100644 --- a/scenes/song_select.py +++ b/scenes/song_select.py @@ -69,6 +69,8 @@ class SongSelectScreen(Screen): self.dan_transition = DanTransition() self.shader = ray.load_shader('shader/dummy.vs', 'shader/colortransform.fs') self.color = None + song_format = tex.skin_config["song_num"].text[global_data.config["general"]["language"]] + self.song_num = OutlinedText(song_format.format(global_data.songs_played+1), tex.skin_config["song_num"].font_size, ray.WHITE) self.load_shader_values(self.color) session_data = global_data.session_data[global_data.player_num] @@ -387,8 +389,8 @@ class SongSelectScreen(Screen): self.indicator.draw(tex.skin_config['song_select_indicator'].x, tex.skin_config['song_select_indicator'].y) - tex.draw_texture('global', 'song_num_bg', fade=0.75) - tex.draw_texture('global', 'song_num', frame=global_data.songs_played % 4) + tex.draw_texture('global', 'song_num_bg', fade=0.75, x=-(self.song_num.texture.width-127), x2=(self.song_num.texture.width-127)) + self.song_num.draw(ray.BLACK, x=tex.skin_config["song_num"].x-self.song_num.texture.width, y=tex.skin_config["song_num"].y) if self.state == State.BROWSING or self.state == State.DIFF_SORTING: self.timer_browsing.draw() elif self.state == State.SONG_SELECTED: diff --git a/scenes/title.py b/scenes/title.py index 3a2abca..e1139c3 100644 --- a/scenes/title.py +++ b/scenes/title.py @@ -6,12 +6,14 @@ from libs.audio import audio from libs.global_objects import AllNetIcon, CoinOverlay, EntryOverlay from libs.texture import tex from libs.utils import ( + OutlinedText, get_current_ms, global_data, global_tex, is_l_don_pressed, is_r_don_pressed, ) +import pyray as ray from libs.video import VideoPlayer from libs.screen import Screen @@ -30,9 +32,6 @@ class TitleScreen(Screen): base = Path(f"Skins/{global_data.config["paths"]["skin"]}/Videos") self.op_video_list += list((base/"op_videos").glob("**/*.mp4")) self.attract_video_list += list((base/"attract_videos").glob("**/*.mp4")) - self.coin_overlay = CoinOverlay() - self.allnet_indicator = AllNetIcon() - self.entry_overlay = EntryOverlay() def on_screen_start(self): super().on_screen_start() @@ -40,6 +39,10 @@ class TitleScreen(Screen): self.op_video = None self.attract_video = None self.warning_board = None + self.coin_overlay = CoinOverlay() + self.allnet_indicator = AllNetIcon() + self.entry_overlay = EntryOverlay() + self.hit_taiko_text = OutlinedText(global_tex.skin_config["hit_taiko_to_start"].text[global_data.config["general"]["language"]], tex.skin_config["hit_taiko_to_start"].font_size, ray.WHITE, spacing=5) self.fade_out = tex.get_animation(13) self.text_overlay_fade = tex.get_animation(14) @@ -116,8 +119,8 @@ class TitleScreen(Screen): self.allnet_indicator.draw() self.entry_overlay.draw(tex.skin_config["entry_overlay_title"].x, y=tex.skin_config["entry_overlay_title"].y) - global_tex.draw_texture('overlay', 'hit_taiko_to_start', index=0, fade=self.text_overlay_fade.attribute) - global_tex.draw_texture('overlay', 'hit_taiko_to_start', index=1, fade=self.text_overlay_fade.attribute) + self.hit_taiko_text.draw(ray.BLACK, x=tex.screen_width*0.25 - self.hit_taiko_text.texture.width//2, y=tex.skin_config["hit_taiko_to_start"].y, fade=self.text_overlay_fade.attribute) + self.hit_taiko_text.draw(ray.BLACK, x=tex.screen_width*0.75 - self.hit_taiko_text.texture.width//2, y=tex.skin_config["hit_taiko_to_start"].y, fade=self.text_overlay_fade.attribute) class WarningScreen: """Warning screen for the game"""