mirror of
https://github.com/Yonokid/PyTaiko.git
synced 2026-02-04 11:40:13 +01:00
add skin_config.json
This commit is contained in:
@@ -5,7 +5,7 @@ from libs.utils import global_tex
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class Chara2D:
|
class Chara2D:
|
||||||
def __init__(self, index: int, bpm: float, path: str = 'chara'):
|
def __init__(self, index: int, bpm: float = 100, path: str = 'chara'):
|
||||||
"""
|
"""
|
||||||
Initialize a Chara2D object.
|
Initialize a Chara2D object.
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ class Chara2D:
|
|||||||
self.current_anim = name
|
self.current_anim = name
|
||||||
self.anims[name].start()
|
self.anims[name].start()
|
||||||
logger.debug(f"Animation set: {name}")
|
logger.debug(f"Animation set: {name}")
|
||||||
def update(self, current_time_ms: float, bpm: float, is_clear: bool, is_rainbow: bool):
|
def update(self, current_time_ms: float, bpm: float = 100, is_clear: bool = False, is_rainbow: bool = False):
|
||||||
"""
|
"""
|
||||||
Update the character's animation state and appearance.
|
Update the character's animation state and appearance.
|
||||||
|
|
||||||
|
|||||||
@@ -45,12 +45,12 @@ class Nameplate:
|
|||||||
"""Unload the Nameplate object."""
|
"""Unload the Nameplate object."""
|
||||||
self.name.unload()
|
self.name.unload()
|
||||||
self.title.unload()
|
self.title.unload()
|
||||||
def draw(self, x: int, y: int, fade: float = 1.0):
|
def draw(self, x: float, y: float, fade: float = 1.0):
|
||||||
"""Draw the Nameplate object.
|
"""Draw the Nameplate object.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
x (int): The x-coordinate of the Nameplate object.
|
x (float): The x-coordinate of the Nameplate object.
|
||||||
y (int): The y-coordinate of the Nameplate object.
|
y (float): The y-coordinate of the Nameplate object.
|
||||||
fade (float): The fade value of the Nameplate object.
|
fade (float): The fade value of the Nameplate object.
|
||||||
"""
|
"""
|
||||||
tex = global_tex
|
tex = global_tex
|
||||||
@@ -103,7 +103,7 @@ class Indicator:
|
|||||||
self.blue_arrow_move.update(current_time_ms)
|
self.blue_arrow_move.update(current_time_ms)
|
||||||
self.blue_arrow_fade.update(current_time_ms)
|
self.blue_arrow_fade.update(current_time_ms)
|
||||||
|
|
||||||
def draw(self, x: int, y: int, fade=1.0):
|
def draw(self, x: float, y: float, fade=1.0):
|
||||||
"""Draw the indicator at the given position with the given fade."""
|
"""Draw the indicator at the given position with the given fade."""
|
||||||
tex = global_tex
|
tex = global_tex
|
||||||
tex.draw_texture('indicator', 'background', x=x, y=y, fade=fade)
|
tex.draw_texture('indicator', 'background', x=x, y=y, fade=fade)
|
||||||
@@ -156,7 +156,7 @@ class EntryOverlay:
|
|||||||
def update(self, current_time_ms: float):
|
def update(self, current_time_ms: float):
|
||||||
"""Update the Banapass and Camera status icons."""
|
"""Update the Banapass and Camera status icons."""
|
||||||
pass
|
pass
|
||||||
def draw(self, x: int = 0, y: int = 0):
|
def draw(self, x: float = 0, y: float = 0):
|
||||||
"""Draw the Banapass and Camera status icons."""
|
"""Draw the Banapass and Camera status icons."""
|
||||||
tex = global_tex
|
tex = global_tex
|
||||||
tex.draw_texture('overlay', 'banapass_or', x=x, y=y, frame=self.online)
|
tex.draw_texture('overlay', 'banapass_or', x=x, y=y, frame=self.online)
|
||||||
|
|||||||
@@ -16,6 +16,11 @@ SCREEN_HEIGHT = 720
|
|||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class Coordinates:
|
||||||
|
def __init__(self, x: float, y: float):
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
|
||||||
class Texture:
|
class Texture:
|
||||||
"""Texture class for managing textures and animations."""
|
"""Texture class for managing textures and animations."""
|
||||||
def __init__(self, name: str, texture: Union[ray.Texture, list[ray.Texture]], init_vals: dict[str, int]):
|
def __init__(self, name: str, texture: Union[ray.Texture, list[ray.Texture]], init_vals: dict[str, int]):
|
||||||
@@ -41,7 +46,13 @@ class TextureWrapper:
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.textures: dict[str, dict[str, Texture]] = dict()
|
self.textures: dict[str, dict[str, Texture]] = dict()
|
||||||
self.animations: dict[int, BaseAnimation] = dict()
|
self.animations: dict[int, BaseAnimation] = dict()
|
||||||
|
self.skin_config: dict[str, Coordinates] = dict()
|
||||||
self.graphics_path = Path("Graphics")
|
self.graphics_path = Path("Graphics")
|
||||||
|
if (self.graphics_path / "skin_config.json").exists():
|
||||||
|
data = json.loads((self.graphics_path / "skin_config.json").read_text())
|
||||||
|
self.skin_config: dict[str, Coordinates] = {
|
||||||
|
k: Coordinates(v['x'], v['y']) for k, v in data.items()
|
||||||
|
}
|
||||||
|
|
||||||
def unload_textures(self):
|
def unload_textures(self):
|
||||||
"""Unload all textures and animations."""
|
"""Unload all textures and animations."""
|
||||||
|
|||||||
@@ -11,14 +11,11 @@ from libs.global_objects import AllNetIcon
|
|||||||
from libs.tja import TJAParser
|
from libs.tja import TJAParser
|
||||||
from libs.transition import Transition
|
from libs.transition import Transition
|
||||||
from libs.utils import OutlinedText, get_current_ms
|
from libs.utils import OutlinedText, get_current_ms
|
||||||
from libs.texture import tex
|
from libs.texture import SCREEN_WIDTH, tex
|
||||||
from scenes.game import ClearAnimation, FCAnimation, FailAnimation, GameScreen, Gauge, ResultTransition, SongInfo
|
from scenes.game import ClearAnimation, FCAnimation, FailAnimation, GameScreen, Gauge, ResultTransition, SongInfo
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
SCREEN_WIDTH = 1280
|
|
||||||
SCREEN_HEIGHT = 720
|
|
||||||
|
|
||||||
class DanGameScreen(GameScreen):
|
class DanGameScreen(GameScreen):
|
||||||
JUDGE_X = 414
|
JUDGE_X = 414
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from libs.audio import audio
|
|||||||
from libs.chara_2d import Chara2D
|
from libs.chara_2d import Chara2D
|
||||||
from libs.global_data import PlayerNum
|
from libs.global_data import PlayerNum
|
||||||
from libs.global_objects import AllNetIcon, CoinOverlay, Nameplate, Indicator, EntryOverlay, Timer
|
from libs.global_objects import AllNetIcon, CoinOverlay, Nameplate, Indicator, EntryOverlay, Timer
|
||||||
from libs.texture import tex
|
from libs.texture import SCREEN_HEIGHT, SCREEN_WIDTH, tex
|
||||||
from libs.screen import Screen
|
from libs.screen import Screen
|
||||||
from libs.utils import (
|
from libs.utils import (
|
||||||
OutlinedText,
|
OutlinedText,
|
||||||
@@ -45,7 +45,7 @@ class EntryScreen(Screen):
|
|||||||
self.side_select_fade = tex.get_animation(0)
|
self.side_select_fade = tex.get_animation(0)
|
||||||
self.bg_flicker = tex.get_animation(1)
|
self.bg_flicker = tex.get_animation(1)
|
||||||
self.side_select_fade.start()
|
self.side_select_fade.start()
|
||||||
self.chara = Chara2D(0, 100)
|
self.chara = Chara2D(0)
|
||||||
self.announce_played = False
|
self.announce_played = False
|
||||||
self.players: list[Optional[EntryPlayer]] = [None, None]
|
self.players: list[Optional[EntryPlayer]] = [None, None]
|
||||||
audio.play_sound('bgm', 'music')
|
audio.play_sound('bgm', 'music')
|
||||||
@@ -158,7 +158,7 @@ class EntryScreen(Screen):
|
|||||||
|
|
||||||
tex.draw_texture('side_select', 'question', fade=fade)
|
tex.draw_texture('side_select', 'question', fade=fade)
|
||||||
|
|
||||||
self.chara.draw(480, 240)
|
self.chara.draw(tex.skin_config["chara_entry"].x, tex.skin_config["chara_entry"].y)
|
||||||
|
|
||||||
tex.draw_texture('side_select', '1P', fade=fade)
|
tex.draw_texture('side_select', '1P', fade=fade)
|
||||||
tex.draw_texture('side_select', 'cancel', fade=fade)
|
tex.draw_texture('side_select', 'cancel', fade=fade)
|
||||||
@@ -173,7 +173,7 @@ class EntryScreen(Screen):
|
|||||||
tex.draw_texture('side_select', '2P_highlight', fade=fade)
|
tex.draw_texture('side_select', '2P_highlight', fade=fade)
|
||||||
tex.draw_texture('side_select', '1P2P_outline', index=1, fade=fade)
|
tex.draw_texture('side_select', '1P2P_outline', index=1, fade=fade)
|
||||||
tex.draw_texture('side_select', 'cancel_text', fade=fade)
|
tex.draw_texture('side_select', 'cancel_text', fade=fade)
|
||||||
self.nameplate.draw(500, 185)
|
self.nameplate.draw(tex.skin_config["nameplate_entry"].x, tex.skin_config["nameplate_entry"].y)
|
||||||
|
|
||||||
def draw_player_drum(self):
|
def draw_player_drum(self):
|
||||||
for player in self.players:
|
for player in self.players:
|
||||||
@@ -212,10 +212,10 @@ class EntryScreen(Screen):
|
|||||||
tex.draw_texture('global', 'player_entry')
|
tex.draw_texture('global', 'player_entry')
|
||||||
|
|
||||||
if self.box_manager.is_finished():
|
if self.box_manager.is_finished():
|
||||||
ray.draw_rectangle(0, 0, 1280, 720, ray.BLACK)
|
ray.draw_rectangle(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, ray.BLACK)
|
||||||
|
|
||||||
self.timer.draw()
|
self.timer.draw()
|
||||||
self.entry_overlay.draw(y=-10)
|
self.entry_overlay.draw(y=tex.skin_config['entry_overlay_entry'].y)
|
||||||
self.coin_overlay.draw()
|
self.coin_overlay.draw()
|
||||||
self.allnet_indicator.draw()
|
self.allnet_indicator.draw()
|
||||||
|
|
||||||
@@ -248,7 +248,7 @@ class EntryPlayer:
|
|||||||
|
|
||||||
# Character (0 for red/1P, 1 for blue/2P)
|
# Character (0 for red/1P, 1 for blue/2P)
|
||||||
chara_id = 0 if side == 0 else 1
|
chara_id = 0 if side == 0 else 1
|
||||||
self.chara = Chara2D(chara_id, 100)
|
self.chara = Chara2D(chara_id)
|
||||||
|
|
||||||
# Animations
|
# Animations
|
||||||
self.drum_move_1 = tex.get_animation(2)
|
self.drum_move_1 = tex.get_animation(2)
|
||||||
@@ -283,7 +283,7 @@ class EntryPlayer:
|
|||||||
self.nameplate_fadein.update(current_time)
|
self.nameplate_fadein.update(current_time)
|
||||||
self.nameplate.update(current_time)
|
self.nameplate.update(current_time)
|
||||||
self.indicator.update(current_time)
|
self.indicator.update(current_time)
|
||||||
self.chara.update(current_time, 100, False, False)
|
self.chara.update(current_time)
|
||||||
|
|
||||||
def draw_drum(self):
|
def draw_drum(self):
|
||||||
"""Draw the player's drum with animations"""
|
"""Draw the player's drum with animations"""
|
||||||
@@ -323,11 +323,11 @@ class EntryPlayer:
|
|||||||
def draw_nameplate_and_indicator(self, fade: float = 1.0):
|
def draw_nameplate_and_indicator(self, fade: float = 1.0):
|
||||||
"""Draw nameplate and indicator at player-specific position"""
|
"""Draw nameplate and indicator at player-specific position"""
|
||||||
if self.side == 0: # Left side
|
if self.side == 0: # Left side
|
||||||
self.nameplate.draw(30, 640, fade=fade)
|
self.nameplate.draw(tex.skin_config['nameplate_entry_left'].x, tex.skin_config['nameplate_entry_left'].y, fade=fade)
|
||||||
self.indicator.draw(50, 575, fade=fade)
|
self.indicator.draw(tex.skin_config['indicator_entry_left'].x, tex.skin_config['indicator_entry_left'].y, fade=fade)
|
||||||
else: # Right side
|
else: # Right side
|
||||||
self.nameplate.draw(950, 640, fade=fade)
|
self.nameplate.draw(tex.skin_config['nameplate_entry_right'].x, tex.skin_config['nameplate_entry_right'].y, fade=fade)
|
||||||
self.indicator.draw(770, 575, fade=fade)
|
self.indicator.draw(tex.skin_config['indicator_entry_right'].x, tex.skin_config['indicator_entry_right'].y, fade=fade)
|
||||||
|
|
||||||
def is_cloud_animation_finished(self) -> bool:
|
def is_cloud_animation_finished(self) -> bool:
|
||||||
"""Check if cloud texture change animation is finished"""
|
"""Check if cloud texture change animation is finished"""
|
||||||
@@ -368,6 +368,7 @@ class Box:
|
|||||||
self.is_selected = False
|
self.is_selected = False
|
||||||
self.moving_left = False
|
self.moving_left = False
|
||||||
self.moving_right = False
|
self.moving_right = False
|
||||||
|
self.outline_color = ray.Color(109, 68, 24, 255)
|
||||||
|
|
||||||
def set_positions(self, x: int):
|
def set_positions(self, x: int):
|
||||||
"""Set the positions of the box"""
|
"""Set the positions of the box"""
|
||||||
@@ -425,7 +426,7 @@ class Box:
|
|||||||
if self.is_selected:
|
if self.is_selected:
|
||||||
self.text.draw(outline_color=ray.BLACK, x=text_x, y=text_y, color=color)
|
self.text.draw(outline_color=ray.BLACK, x=text_x, y=text_y, color=color)
|
||||||
else:
|
else:
|
||||||
self.text.draw(outline_color=ray.Color(109, 68, 24, 255), x=text_x, y=text_y, color=color)
|
self.text.draw(outline_color=self.outline_color, x=text_x, y=text_y, color=color)
|
||||||
|
|
||||||
def draw(self, fade: float):
|
def draw(self, fade: float):
|
||||||
color = ray.fade(ray.WHITE, fade)
|
color = ray.fade(ray.WHITE, fade)
|
||||||
@@ -451,7 +452,7 @@ class BoxManager:
|
|||||||
spacing = 80
|
spacing = 80
|
||||||
box_width = self.boxes[0].texture.width
|
box_width = self.boxes[0].texture.width
|
||||||
total_width = self.num_boxes * box_width + (self.num_boxes - 1) * spacing
|
total_width = self.num_boxes * box_width + (self.num_boxes - 1) * spacing
|
||||||
start_x = 640 - total_width//2
|
start_x = SCREEN_WIDTH//2 - total_width//2
|
||||||
for i, box in enumerate(self.boxes):
|
for i, box in enumerate(self.boxes):
|
||||||
box.set_positions(start_x + i * (box_width + spacing))
|
box.set_positions(start_x + i * (box_width + spacing))
|
||||||
if i > 0:
|
if i > 0:
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ from libs.chara_2d import Chara2D
|
|||||||
from libs.global_data import Crown, Difficulty, Modifiers, PlayerNum
|
from libs.global_data import Crown, Difficulty, Modifiers, PlayerNum
|
||||||
from libs.global_objects import AllNetIcon, Nameplate
|
from libs.global_objects import AllNetIcon, Nameplate
|
||||||
from libs.screen import Screen
|
from libs.screen import Screen
|
||||||
from libs.texture import tex
|
from libs.texture import SCREEN_HEIGHT, SCREEN_WIDTH, tex
|
||||||
from libs.tja import (
|
from libs.tja import (
|
||||||
Balloon,
|
Balloon,
|
||||||
Drumroll,
|
Drumroll,
|
||||||
@@ -41,9 +41,6 @@ from libs.utils import (
|
|||||||
)
|
)
|
||||||
from libs.video import VideoPlayer
|
from libs.video import VideoPlayer
|
||||||
|
|
||||||
SCREEN_WIDTH = 1280
|
|
||||||
SCREEN_HEIGHT = 720
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class GameScreen(Screen):
|
class GameScreen(Screen):
|
||||||
|
|||||||
@@ -336,9 +336,9 @@ class PracticePlayer(Player):
|
|||||||
|
|
||||||
# Group 2: Judgement and hit effects
|
# Group 2: Judgement and hit effects
|
||||||
if self.gogo_time is not None:
|
if self.gogo_time is not None:
|
||||||
self.gogo_time.draw()
|
self.gogo_time.draw(self.judge_x, self.judge_y)
|
||||||
for anim in self.draw_judge_list:
|
for anim in self.draw_judge_list:
|
||||||
anim.draw()
|
anim.draw(self.judge_x, self.judge_y)
|
||||||
|
|
||||||
# Group 3: Notes and bars (game content)
|
# Group 3: Notes and bars (game content)
|
||||||
if not self.paused:
|
if not self.paused:
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ from libs.file_navigator import Directory, SongBox, SongFile
|
|||||||
from libs.global_data import Difficulty, Modifiers, PlayerNum
|
from libs.global_data import Difficulty, Modifiers, PlayerNum
|
||||||
from libs.global_objects import AllNetIcon, CoinOverlay, Nameplate, Indicator, Timer
|
from libs.global_objects import AllNetIcon, CoinOverlay, Nameplate, Indicator, Timer
|
||||||
from libs.screen import Screen
|
from libs.screen import Screen
|
||||||
from libs.texture import tex
|
from libs.texture import SCREEN_WIDTH, tex
|
||||||
from libs.transition import Transition
|
from libs.transition import Transition
|
||||||
from libs.utils import (
|
from libs.utils import (
|
||||||
OutlinedText,
|
OutlinedText,
|
||||||
@@ -329,7 +329,7 @@ class SongSelectScreen(Screen):
|
|||||||
|
|
||||||
for item in self.navigator.items:
|
for item in self.navigator.items:
|
||||||
box = item.box
|
box = item.box
|
||||||
if -156 <= box.position <= 1280 + 144:
|
if -156 <= box.position <= SCREEN_WIDTH + 144:
|
||||||
if box.position <= 500:
|
if box.position <= 500:
|
||||||
box.draw(box.position - int(self.move_away.attribute), 95, self.player_1.is_ura, fade_override=self.diff_fade_out.attribute)
|
box.draw(box.position - int(self.move_away.attribute), 95, self.player_1.is_ura, fade_override=self.diff_fade_out.attribute)
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ class TitleScreen(Screen):
|
|||||||
tex.draw_texture('movie', 'background', fade=self.fade_out.attribute)
|
tex.draw_texture('movie', 'background', fade=self.fade_out.attribute)
|
||||||
self.coin_overlay.draw()
|
self.coin_overlay.draw()
|
||||||
self.allnet_indicator.draw()
|
self.allnet_indicator.draw()
|
||||||
self.entry_overlay.draw(x=155, y=-10)
|
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=0, fade=self.text_overlay_fade.attribute)
|
||||||
global_tex.draw_texture('overlay', 'hit_taiko_to_start', index=1, fade=self.text_overlay_fade.attribute)
|
global_tex.draw_texture('overlay', 'hit_taiko_to_start', index=1, fade=self.text_overlay_fade.attribute)
|
||||||
@@ -252,6 +252,7 @@ class WarningScreen:
|
|||||||
self.fade_in.update(current_ms)
|
self.fade_in.update(current_ms)
|
||||||
self.fade_out.update(current_ms)
|
self.fade_out.update(current_ms)
|
||||||
delay = 566.67
|
delay = 566.67
|
||||||
|
fade_out_delay = 500
|
||||||
elapsed_time = current_ms - self.start_ms
|
elapsed_time = current_ms - self.start_ms
|
||||||
self.warning_x.update(current_ms)
|
self.warning_x.update(current_ms)
|
||||||
self.characters.update(current_ms)
|
self.characters.update(current_ms)
|
||||||
@@ -259,7 +260,7 @@ class WarningScreen:
|
|||||||
if self.characters.is_finished:
|
if self.characters.is_finished:
|
||||||
self.warning_bachi_hit.update(current_ms)
|
self.warning_bachi_hit.update(current_ms)
|
||||||
else:
|
else:
|
||||||
self.fade_out.delay = elapsed_time + 500
|
self.fade_out.delay = elapsed_time + fade_out_delay
|
||||||
if delay <= elapsed_time and not audio.is_sound_playing('bachi_swipe'):
|
if delay <= elapsed_time and not audio.is_sound_playing('bachi_swipe'):
|
||||||
audio.play_sound('warning_voiceover', 'attract_mode')
|
audio.play_sound('warning_voiceover', 'attract_mode')
|
||||||
audio.play_sound('bachi_swipe', 'attract_mode')
|
audio.play_sound('bachi_swipe', 'attract_mode')
|
||||||
|
|||||||
Reference in New Issue
Block a user