3d model experiments

This commit is contained in:
Yonokid
2025-07-26 17:14:03 -04:00
parent fc985ca410
commit e6f2f19c1a
15 changed files with 16794 additions and 38 deletions

View File

@@ -2,6 +2,7 @@ import sqlite3
from pathlib import Path from pathlib import Path
import pyray as ray import pyray as ray
from raylib import CAMERA_ORTHOGRAPHIC
from raylib.defines import ( from raylib.defines import (
RL_FUNC_ADD, RL_FUNC_ADD,
RL_ONE, RL_ONE,
@@ -67,11 +68,18 @@ def main():
ray.set_config_flags(ray.ConfigFlags.FLAG_MSAA_4X_HINT) ray.set_config_flags(ray.ConfigFlags.FLAG_MSAA_4X_HINT)
ray.set_trace_log_level(ray.TraceLogLevel.LOG_WARNING) ray.set_trace_log_level(ray.TraceLogLevel.LOG_WARNING)
camera = ray.Camera3D()
camera.position = ray.Vector3(0.0, 0.0, 10.0) # Camera position
camera.target = ray.Vector3(0.0, 0.0, 0.0) # Camera looking at point
camera.up = ray.Vector3(0.0, 1.0, 0.0) # Camera up vector
camera.fovy = screen_height # For orthographic, this acts as the view height
camera.projection = CAMERA_ORTHOGRAPHIC
ray.init_window(screen_width, screen_height, "PyTaiko") ray.init_window(screen_width, screen_height, "PyTaiko")
if global_data.config["video"]["borderless"]: if global_data.config["video"]["borderless"]:
ray.toggle_borderless_windowed() ray.toggle_borderless_windowed()
if global_data.config["video"]["fullscreen"]: if global_data.config["video"]["fullscreen"]:
ray.maximize_window() ray.toggle_fullscreen()
current_screen = Screens.LOADING current_screen = Screens.LOADING
@@ -104,18 +112,23 @@ def main():
ray.rl_set_blend_factors_separate(RL_SRC_ALPHA, RL_ONE_MINUS_SRC_ALPHA, RL_ONE, RL_ONE_MINUS_SRC_ALPHA, RL_FUNC_ADD, RL_FUNC_ADD) ray.rl_set_blend_factors_separate(RL_SRC_ALPHA, RL_ONE_MINUS_SRC_ALPHA, RL_ONE, RL_ONE_MINUS_SRC_ALPHA, RL_FUNC_ADD, RL_FUNC_ADD)
ray.set_exit_key(ray.KeyboardKey.KEY_A) ray.set_exit_key(ray.KeyboardKey.KEY_A)
global_data.textures = load_all_textures_from_zip(Path('Graphics/lumendata/intermission.zip')) global_data.textures = load_all_textures_from_zip(Path('Graphics/lumendata/intermission.zip'))
while not ray.window_should_close():
while not ray.window_should_close():
ray.begin_texture_mode(target) ray.begin_texture_mode(target)
ray.begin_blend_mode(ray.BlendMode.BLEND_CUSTOM_SEPARATE) ray.begin_blend_mode(ray.BlendMode.BLEND_CUSTOM_SEPARATE)
screen = screen_mapping[current_screen] screen = screen_mapping[current_screen]
# Begin 3D mode with orthographic camera
if ray.is_key_pressed(ray.KeyboardKey.KEY_F11): if ray.is_key_pressed(ray.KeyboardKey.KEY_F11):
ray.toggle_fullscreen() ray.toggle_borderless_windowed()
next_screen = screen.update() next_screen = screen.update()
ray.clear_background(ray.BLACK) ray.clear_background(ray.BLACK)
screen.draw() screen.draw()
ray.begin_mode_3d(camera)
screen.draw_3d()
ray.end_mode_3d()
if next_screen is not None: if next_screen is not None:
current_screen = next_screen current_screen = next_screen
@@ -129,7 +142,7 @@ def main():
ray.draw_texture_pro( ray.draw_texture_pro(
target.texture, target.texture,
ray.Rectangle(0, 0, target.texture.width, -target.texture.height), ray.Rectangle(0, 0, target.texture.width, -target.texture.height),
ray.Rectangle(0, 0, screen_width, screen_height), ray.Rectangle(0, 0, ray.get_screen_width(), ray.get_screen_height()),
ray.Vector2(0,0), ray.Vector2(0,0),
0, 0,
ray.WHITE ray.WHITE

View File

@@ -11,14 +11,14 @@ class Background:
def __init__(self, screen_width: int, screen_height: int): def __init__(self, screen_width: int, screen_height: int):
self.screen_width = screen_width self.screen_width = screen_width
self.screen_height = screen_height self.screen_height = screen_height
self.donbg = DonBG.create(self.screen_width, self.screen_height, random.randint(6, 6), 1) self.donbg = DonBG.create(self.screen_width, self.screen_height, random.randint(1, 6), 1)
self.bg_normal = BGNormal.create(self.screen_width, self.screen_height, random.randint(1, 5)) self.bg_normal = BGNormal.create(self.screen_width, self.screen_height, random.randint(1, 5))
self.bg_fever = BGFever.create(self.screen_width, self.screen_height, 4) self.bg_fever = BGFever.create(self.screen_width, self.screen_height, 4)
self.footer = Footer(self.screen_width, self.screen_height, random.randint(1, 3)) self.footer = Footer(self.screen_width, self.screen_height, random.randint(1, 3))
self.is_clear = False self.is_clear = False
def update(self, current_time_ms: float, is_clear: bool): def update(self, current_time_ms: float, is_clear: bool):
self.is_clear = is_clear self.is_clear = is_clear
self.donbg.update(current_time_ms, is_clear) self.donbg.update(current_time_ms, self.is_clear)
self.bg_normal.update(current_time_ms) self.bg_normal.update(current_time_ms)
self.bg_fever.update(current_time_ms) self.bg_fever.update(current_time_ms)
def draw(self): def draw(self):
@@ -38,7 +38,7 @@ class DonBG:
@staticmethod @staticmethod
def create(screen_width: int, screen_height: int, index: int, player_num: int): def create(screen_width: int, screen_height: int, index: int, player_num: int):
map = [None, DonBG1, DonBG1, DonBG1, DonBG1, DonBG1, DonBG6] map = [None, DonBG1, DonBG2, DonBG3, DonBG4, DonBG5, DonBG6]
selected_obj = map[index] selected_obj = map[index]
return selected_obj(index, screen_width, screen_height, player_num) return selected_obj(index, screen_width, screen_height, player_num)
@@ -75,14 +75,123 @@ class DonBG1(DonBGBase):
def draw(self): def draw(self):
texture_index = 0 texture_index = 0
if self.is_clear: if self.is_clear:
texture_index = 2 texture_index = 3
top_texture = self.textures[self.name + f'_{self.player_num}p'][0 + texture_index] top_texture = self.textures[self.name + f'_{self.player_num}p'][0 + texture_index]
for i in range(0, self.screen_width + top_texture.width, top_texture.width): for i in range(0, self.screen_width + top_texture.width, top_texture.width):
ray.draw_texture(top_texture, i + int(self.move.attribute), 0, ray.WHITE) ray.draw_texture(top_texture, i + int(self.move.attribute), 0, ray.WHITE)
wave_texture = self.textures[self.name + f'_{self.player_num}p'][1 + texture_index]
for i in range(0, self.screen_width + (wave_texture.width+80), wave_texture.width+80):
ray.draw_texture(wave_texture, i + int(self.move.attribute * ((wave_texture.width+80)/top_texture.width)) + 100, int(self.overlay_move.attribute), ray.WHITE)
texture = self.textures[self.name + f'_{self.player_num}p'][2 + texture_index]
for i in range(0, self.screen_width + texture.width + texture.width*5, texture.width):
ray.draw_texture(texture, i + int(self.move.attribute * (texture.width/top_texture.width)*3), int(self.overlay_move.attribute) + 105, ray.WHITE)
class DonBG2(DonBGBase):
def __init__(self, index: int, screen_width: int, screen_height: int, player_num: int):
super().__init__(index, screen_width, screen_height, player_num)
self.overlay_move = Animation.create_move(1500, start_position=0, total_distance=20, reverse_delay=0)
def update(self, current_time_ms: float, is_clear: bool):
super().update(current_time_ms, is_clear)
self.overlay_move.update(current_time_ms)
if self.overlay_move.is_finished:
self.overlay_move.restart()
def draw(self):
texture_index = 0
if self.is_clear:
texture_index = 2
top_texture = self.textures[self.name + f'_{self.player_num}p'][texture_index]
for i in range(0, self.screen_width + top_texture.width, top_texture.width):
ray.draw_texture(top_texture, i + int(self.move.attribute), 0, ray.WHITE)
texture = self.textures[self.name + f'_{self.player_num}p'][1 + texture_index] texture = self.textures[self.name + f'_{self.player_num}p'][1 + texture_index]
for i in range(0, self.screen_width + texture.width, texture.width): for i in range(0, self.screen_width + texture.width, texture.width):
ray.draw_texture(texture, i + int(self.move.attribute), int(self.overlay_move.attribute) - 50, ray.WHITE) ray.draw_texture(texture, i + int(self.move.attribute), int(self.overlay_move.attribute) - 25, ray.WHITE)
class DonBG3(DonBGBase):
def __init__(self, index: int, screen_width: int, screen_height: int, player_num: int):
super().__init__(index, screen_width, screen_height, player_num)
duration = 266
bounce_distance = 40
self.bounce_up = Animation.create_move(duration, total_distance=-bounce_distance, ease_out='quadratic')
self.bounce_down = Animation.create_move(duration, total_distance=-bounce_distance, ease_in='quadratic', delay=self.bounce_up.duration)
self.overlay_move = Animation.create_move(duration*3, total_distance=20, reverse_delay=0, ease_in='quadratic', ease_out='quadratic', delay=self.bounce_up.duration+self.bounce_down.duration)
self.overlay_move_2 = Animation.create_move(duration*3, total_distance=20, reverse_delay=0, ease_in='quadratic', ease_out='quadratic', delay=self.bounce_up.duration+self.bounce_down.duration+self.overlay_move.duration)
def update(self, current_time_ms: float, is_clear: bool):
super().update(current_time_ms, is_clear)
self.bounce_up.update(current_time_ms)
self.bounce_down.update(current_time_ms)
self.overlay_move.update(current_time_ms)
self.overlay_move_2.update(current_time_ms)
if self.overlay_move_2.is_finished:
self.bounce_up.restart()
self.bounce_down.restart()
self.overlay_move.restart()
self.overlay_move_2.restart()
def draw(self):
texture_index = 0
if self.is_clear:
texture_index = 2
top_texture = self.textures[self.name + f'_{self.player_num}p'][0 + texture_index]
for i in range(0, self.screen_width + top_texture.width, top_texture.width):
ray.draw_texture(top_texture, i + int(self.move.attribute), 0, ray.WHITE)
texture = self.textures[self.name + f'_{self.player_num}p'][1 + texture_index]
for i in range(0, self.screen_width + texture.width, texture.width):
ray.draw_texture(texture, i + int(self.move.attribute*2), int(self.bounce_up.attribute) - int(self.bounce_down.attribute) - 25 + int(self.overlay_move.attribute) + int(self.overlay_move_2.attribute), ray.WHITE)
class DonBG4(DonBGBase):
def __init__(self, index: int, screen_width: int, screen_height: int, player_num: int):
super().__init__(index, screen_width, screen_height, player_num)
self.overlay_move = Animation.create_move(1500, start_position=0, total_distance=20, reverse_delay=0)
def update(self, current_time_ms: float, is_clear: bool):
super().update(current_time_ms, is_clear)
self.overlay_move.update(current_time_ms)
if self.overlay_move.is_finished:
self.overlay_move.restart()
def draw(self):
texture_index = 0
if self.is_clear:
texture_index = 2
top_texture = self.textures[self.name + f'_{self.player_num}p'][texture_index]
for i in range(0, self.screen_width + top_texture.width, top_texture.width):
ray.draw_texture(top_texture, i + int(self.move.attribute), 0, ray.WHITE)
texture = self.textures[self.name + f'_{self.player_num}p'][1 + texture_index]
for i in range(0, self.screen_width + texture.width, texture.width):
ray.draw_texture(texture, i + int(self.move.attribute), int(self.overlay_move.attribute) - 25, ray.WHITE)
class DonBG5(DonBGBase):
def __init__(self, index: int, screen_width: int, screen_height: int, player_num: int):
super().__init__(index, screen_width, screen_height, player_num)
duration = 266
bounce_distance = 40
self.bounce_up = Animation.create_move(duration, total_distance=-bounce_distance, ease_out='quadratic')
self.bounce_down = Animation.create_move(duration, total_distance=-bounce_distance, ease_in='quadratic', delay=self.bounce_up.duration)
self.adjust = Animation.create_move(1000, total_distance=10, reverse_delay=0, delay=self.bounce_up.duration+self.bounce_down.duration)
def update(self, current_time_ms: float, is_clear: bool):
super().update(current_time_ms, is_clear)
self.bounce_up.update(current_time_ms)
self.bounce_down.update(current_time_ms)
self.adjust.update(current_time_ms)
if self.adjust.is_finished:
self.bounce_up.restart()
self.bounce_down.restart()
self.adjust.restart()
def draw(self):
texture_index = 0
if self.is_clear:
texture_index = 2
top_texture = self.textures[self.name + f'_{self.player_num}p'][0 + texture_index]
for i in range(0, self.screen_width + top_texture.width, top_texture.width):
ray.draw_texture(top_texture, i + int(self.move.attribute), 0, ray.WHITE)
texture = self.textures[self.name + f'_{self.player_num}p'][1 + texture_index]
for i in range(0, self.screen_width + texture.width + texture.width*2, texture.width*2):
ray.draw_texture(texture, i + int((self.move.attribute * (texture.width/top_texture.width))*2), int(self.bounce_up.attribute) - int(self.bounce_down.attribute) - int(self.adjust.attribute), ray.WHITE)
class DonBG6(DonBGBase): class DonBG6(DonBGBase):
def __init__(self, index: int, screen_width: int, screen_height: int, player_num: int): def __init__(self, index: int, screen_width: int, screen_height: int, player_num: int):

View File

@@ -169,6 +169,8 @@ def calculate_base_score(play_note_list: deque[Note | Drumroll | Balloon]) -> in
balloon_count += note.count balloon_count += note.count
else: else:
total_notes += 1 total_notes += 1
if total_notes == 0:
return 0
total_score = (1000000 - (balloon_count * 100) - (drumroll_sec * 1692.0079999994086)) / total_notes total_score = (1000000 - (balloon_count * 100) - (drumroll_sec * 1692.0079999994086)) / total_notes
return math.ceil(total_score / 10) * 10 return math.ceil(total_score / 10) * 10

BIN
model/cos_100000_01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

BIN
model/cos_100000_02.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

76
model/mikudon.mtl Normal file
View File

@@ -0,0 +1,76 @@
# Blender 4.5.0 MTL File: 'None'
# www.blender.org
newmtl RGB_don_color_S_CUS_0x10000001_
Ns 360.000000
Ka 1.000000 1.000000 1.000000
Kd 0.968627 0.945098 0.882352
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
newmtl cos_100000_HEADBODY_01_color_S_CUS_0x10000000__AT_ZERO___CULLNO
Ns 360.000000
Ka 1.000000 1.000000 1.000000
Kd 0.800000 0.800000 0.800000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
map_Kd cos_100000_01.png
illum 2
newmtl cos_100000_HEADBODY_02_color_S_CUS_0x10000000__AT_ZERO___CULLNO
Ns 360.000000
Ka 1.000000 1.000000 1.000000
Kd 0.800000 0.800000 0.800000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
map_Kd cos_100000_02.png
illum 2
newmtl cos_100000_HEADBODY_03_color_S_CUS_0x10000000__A_AB_AA_ADD_AT_O
Ns 360.000000
Ka 1.000000 1.000000 1.000000
Kd 0.800000 0.800000 0.800000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
map_Kd cos_100000_01.png
illum 2
newmtl cos_100000_HEADBODY_04_color_S_CUS_0x10000000__A_AB_AA_ADD_AT_O
Ns 360.000000
Ka 1.000000 1.000000 1.000000
Kd 0.800000 0.800000 0.800000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
map_Kd cos_100000_02.png
illum 2
newmtl don_FACEHIP_color_S_CUS_0x10000001_
Ns 360.000000
Ka 1.000000 1.000000 1.000000
Kd 0.968627 0.945098 0.882352
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2
newmtl face2_FACIAL_S_CUS_0x10000002_A_AB_AA_ADD
Ns 360.000000
Ka 1.000000 1.000000 1.000000
Kd 0.968627 0.286274 0.156862
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

16482
model/mikudon.obj Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,16 @@
import pyray as ray import pyray as ray
class DevScreen: class DevScreen:
def __init__(self, width: int, height: int): def __init__(self, width: int, height: int):
self.width = width self.width = width
self.height = height self.height = height
self.screen_init = False self.screen_init = False
self.model = ray.load_model("model/mikudon.obj")
self.model_position = ray.Vector3(-450.0, 100.0, -180.0)
self.model_scale = 1000.0
self.model_rotation_y = 45.0 # Face towards camera (rotate 180 degrees on Y-axis)
self.model_rotation_x = 0.0 # No up/down tilt
self.model_rotation_z = 0.0 # No roll
def on_screen_start(self): def on_screen_start(self):
if not self.screen_init: if not self.screen_init:
@@ -13,12 +18,26 @@ class DevScreen:
def on_screen_end(self, next_screen: str): def on_screen_end(self, next_screen: str):
self.screen_init = False self.screen_init = False
ray.unload_model(self.model)
return next_screen return next_screen
def update(self): def update(self):
self.on_screen_start() self.on_screen_start()
if ray.is_key_pressed(ray.KeyboardKey.KEY_ENTER): if ray.is_key_pressed(ray.KeyboardKey.KEY_ENTER):
return self.on_screen_end('RESULT') return self.on_screen_end('GAME')
def draw(self): def draw(self):
pass pass
def draw_3d(self):
# Method 1: Using draw_model_ex for full control over rotation
rotation_axis = ray.Vector3(0.0, 1.0, 0.0) # Y-axis for horizontal rotation
ray.draw_model_ex(
self.model,
self.model_position,
rotation_axis,
self.model_rotation_y,
ray.Vector3(self.model_scale, self.model_scale, self.model_scale),
ray.WHITE
)

View File

@@ -304,3 +304,6 @@ class EntryScreen:
src = ray.Rectangle(0, 0, self.texture_black.width, self.texture_black.height) src = ray.Rectangle(0, 0, self.texture_black.width, self.texture_black.height)
dest = ray.Rectangle(0, 0, self.width, self.height) dest = ray.Rectangle(0, 0, self.width, self.height)
ray.draw_texture_pro(self.texture_black, src, dest, ray.Vector2(0, 0), 0, ray.WHITE) ray.draw_texture_pro(self.texture_black, src, dest, ray.Vector2(0, 0), 0, ray.WHITE)
def draw_3d(self):
pass

View File

@@ -1,6 +1,7 @@
import bisect import bisect
import math import math
import sqlite3 import sqlite3
from collections import deque
from pathlib import Path from pathlib import Path
from typing import Optional from typing import Optional
@@ -103,22 +104,26 @@ class GameScreen:
self.textures['onp_renda_dai'][0], self.textures['onp_renda_dai'][1], self.textures['onp_renda_dai'][0], self.textures['onp_renda_dai'][1],
self.textures['onp_fusen'][0]] self.textures['onp_fusen'][0]]
self.tja = TJAParser(song, start_delay=self.start_delay, distance=self.width - GameScreen.JUDGE_X) if song == Path(''):
if self.tja.metadata.bgmovie != Path() and self.tja.metadata.bgmovie.exists(): self.start_ms = get_current_ms()
self.movie = VideoPlayer(self.tja.metadata.bgmovie) self.tja = None
self.movie.set_volume(0.0)
else: else:
self.movie = None self.tja = TJAParser(song, start_delay=self.start_delay, distance=self.width - GameScreen.JUDGE_X)
session_data.song_title = self.tja.metadata.title.get(global_data.config['general']['language'].lower(), self.tja.metadata.title['en']) if self.tja.metadata.bgmovie != Path() and self.tja.metadata.bgmovie.exists():
self.movie = VideoPlayer(self.tja.metadata.bgmovie)
self.movie.set_volume(0.0)
else:
self.movie = None
session_data.song_title = self.tja.metadata.title.get(global_data.config['general']['language'].lower(), self.tja.metadata.title['en'])
if not hasattr(self, 'song_music'):
if self.tja.metadata.wave.exists() and self.tja.metadata.wave.is_file():
self.song_music = audio.load_sound(self.tja.metadata.wave)
audio.normalize_sound(self.song_music, 0.1935)
else:
self.song_music = None
self.start_ms = (get_current_ms() - self.tja.metadata.offset*1000)
self.player_1 = Player(self, 1, difficulty) self.player_1 = Player(self, 1, difficulty)
if not hasattr(self, 'song_music'):
if self.tja.metadata.wave.exists() and self.tja.metadata.wave.is_file():
self.song_music = audio.load_sound(self.tja.metadata.wave)
audio.normalize_sound(self.song_music, 0.1935)
else:
self.song_music = None
self.start_ms = (get_current_ms() - self.tja.metadata.offset*1000)
def on_screen_start(self): def on_screen_start(self):
if not self.screen_init: if not self.screen_init:
@@ -146,6 +151,8 @@ class GameScreen:
return next_screen return next_screen
def write_score(self): def write_score(self):
if self.tja is None:
return
if global_data.config['general']['autoplay']: if global_data.config['general']['autoplay']:
return return
with sqlite3.connect('scores.db') as con: with sqlite3.connect('scores.db') as con:
@@ -173,14 +180,15 @@ class GameScreen:
if self.transition is not None: if self.transition is not None:
self.transition.update(get_current_ms()) self.transition.update(get_current_ms())
self.current_ms = get_current_ms() - self.start_ms self.current_ms = get_current_ms() - self.start_ms
if (self.current_ms >= self.tja.metadata.offset*1000 + self.start_delay - global_data.config["general"]["judge_offset"]) and not self.song_started: if self.tja is not None:
if self.song_music is not None: if (self.current_ms >= self.tja.metadata.offset*1000 + self.start_delay - global_data.config["general"]["judge_offset"]) and not self.song_started:
if not audio.is_sound_playing(self.song_music): if self.song_music is not None:
audio.play_sound(self.song_music) if not audio.is_sound_playing(self.song_music):
print(f"Song started at {self.current_ms}") audio.play_sound(self.song_music)
if self.movie is not None: print(f"Song started at {self.current_ms}")
self.movie.start(get_current_ms()) if self.movie is not None:
self.song_started = True self.movie.start(get_current_ms())
self.song_started = True
if self.movie is not None: if self.movie is not None:
self.movie.update() self.movie.update()
else: else:
@@ -228,6 +236,9 @@ class GameScreen:
if self.result_transition is not None: if self.result_transition is not None:
self.result_transition.draw(self.width, self.height, global_data.textures['shutter'][0], global_data.textures['shutter'][1]) self.result_transition.draw(self.width, self.height, global_data.textures['shutter'][0], global_data.textures['shutter'][1])
def draw_3d(self):
self.player_1.draw_3d(self)
class Player: class Player:
TIMING_GOOD = 25.0250015258789 TIMING_GOOD = 25.0250015258789
TIMING_OK = 75.0750045776367 TIMING_OK = 75.0750045776367
@@ -239,7 +250,10 @@ class Player:
self.difficulty = difficulty self.difficulty = difficulty
self.visual_offset = global_data.config["general"]["visual_offset"] self.visual_offset = global_data.config["general"]["visual_offset"]
self.play_notes, self.draw_note_list, self.draw_bar_list = game_screen.tja.notes_to_position(self.difficulty) if game_screen.tja is not None:
self.play_notes, self.draw_note_list, self.draw_bar_list = game_screen.tja.notes_to_position(self.difficulty)
else:
self.play_notes, self.draw_note_list, self.draw_bar_list = deque(), deque(), deque()
self.total_notes = len([note for note in self.play_notes if 0 < note.type < 5]) self.total_notes = len([note for note in self.play_notes if 0 < note.type < 5])
self.base_score = calculate_base_score(self.play_notes) self.base_score = calculate_base_score(self.play_notes)
@@ -275,12 +289,23 @@ class Player:
self.input_log: dict[float, tuple] = dict() self.input_log: dict[float, tuple] = dict()
self.gauge = Gauge(self.difficulty, game_screen.tja.metadata.course_data[self.difficulty].level, self.total_notes) if game_screen.tja is not None:
stars = game_screen.tja.metadata.course_data[self.difficulty].level
else:
stars = 0
self.gauge = Gauge(self.difficulty, stars, self.total_notes)
self.gauge_hit_effect: list[GaugeHitEffect] = [] self.gauge_hit_effect: list[GaugeHitEffect] = []
self.autoplay_hit_side = 'L' self.autoplay_hit_side = 'L'
self.last_subdivision = -1 self.last_subdivision = -1
self.model = ray.load_model("model/mikudon.obj")
self.model_position = ray.Vector3(-475.0, 160.0, -180.0)
self.model_scale = 850.0
self.model_rotation_y = 30.0 # Face towards camera (rotate 180 degrees on Y-axis)
self.model_rotation_x = 0.0 # No up/down tilt
self.model_rotation_z = 0.0
def get_result_score(self): def get_result_score(self):
return self.score, self.good_count, self.ok_count, self.bad_count, self.total_drumroll, self.max_combo return self.score, self.good_count, self.ok_count, self.bad_count, self.total_drumroll, self.max_combo
@@ -383,9 +408,10 @@ class Player:
else: else:
note_type = game_screen.note_type_list[note.type][0] note_type = game_screen.note_type_list[note.type][0]
self.combo += 1 if note.type < 7:
if self.combo > self.max_combo: self.combo += 1
self.max_combo = self.combo if self.combo > self.max_combo:
self.max_combo = self.combo
self.draw_arc_list.append(NoteArc(note_type, get_current_ms(), self.player_number, note.type == 3 or note.type == 4) or note.type == 7) self.draw_arc_list.append(NoteArc(note_type, get_current_ms(), self.player_number, note.type == 3 or note.type == 4) or note.type == 7)
#game_screen.background.chibis.append(game_screen.background.Chibi()) #game_screen.background.chibis.append(game_screen.background.Chibi())
@@ -710,6 +736,20 @@ class Player:
anim.draw(game_screen) anim.draw(game_screen)
#ray.draw_circle(game_screen.width//2, game_screen.height, 300, ray.ORANGE) #ray.draw_circle(game_screen.width//2, game_screen.height, 300, ray.ORANGE)
def draw_3d(self):
'''
rotation_axis = ray.Vector3(0.0, 1.0, 0.0) # Y-axis for horizontal rotation
ray.draw_model_ex(
self.model,
self.model_position,
rotation_axis,
self.model_rotation_y,
ray.Vector3(self.model_scale, self.model_scale, self.model_scale),
ray.WHITE
)
'''
pass
class Judgement: class Judgement:
def __init__(self, type: str, big: bool, ms_display: Optional[float]=None): def __init__(self, type: str, big: bool, ms_display: Optional[float]=None):
self.type = type self.type = type

View File

@@ -112,3 +112,5 @@ class LoadScreen:
if self.fade_in is not None: if self.fade_in is not None:
ray.draw_rectangle(0, 0, self.width, self.height, ray.fade(ray.WHITE, self.fade_in.attribute)) ray.draw_rectangle(0, 0, self.width, self.height, ray.fade(ray.WHITE, self.fade_in.attribute))
def draw_3d(self):
pass

View File

@@ -1,4 +1,3 @@
import math
from pathlib import Path from pathlib import Path
import pyray as ray import pyray as ray
@@ -252,6 +251,9 @@ class ResultScreen:
if self.fade_out is not None: if self.fade_out is not None:
self.fade_out.draw(self.width, self.height) self.fade_out.draw(self.width, self.height)
def draw_3d(self):
pass
class Crown: class Crown:
def __init__(self): def __init__(self):
duration = 466 duration = 466

View File

@@ -264,3 +264,5 @@ class SettingsScreen:
else: else:
# Draw exit instruction # Draw exit instruction
ray.draw_text("Press Don to exit settings", 250, 100, 20, ray.GREEN) ray.draw_text("Press Don to exit settings", 250, 100, 20, ray.GREEN)
def draw_3d(self):
pass

View File

@@ -314,6 +314,9 @@ class SongSelectScreen:
if self.game_transition is not None: if self.game_transition is not None:
self.game_transition.draw(self.screen_height) self.game_transition.draw(self.screen_height)
def draw_3d(self):
pass
class SongBox: class SongBox:
OUTLINE_MAP = { OUTLINE_MAP = {
555: ray.Color(0, 77, 104, 255), 555: ray.Color(0, 77, 104, 255),

View File

@@ -127,6 +127,9 @@ class TitleScreen:
dest = ray.Rectangle(0, 0, self.width, self.height) dest = ray.Rectangle(0, 0, self.width, self.height)
ray.draw_texture_pro(self.texture_black, src, dest, ray.Vector2(0, 0), 0, ray.fade(ray.WHITE, self.fade_out.attribute)) ray.draw_texture_pro(self.texture_black, src, dest, ray.Vector2(0, 0), 0, ray.fade(ray.WHITE, self.fade_out.attribute))
def draw_3d(self):
pass
class WarningScreen: class WarningScreen:
class X: class X:
DELAY = 4250 DELAY = 4250