mirror of
https://github.com/Yonokid/PyTaiko.git
synced 2026-02-04 11:40:13 +01:00
3d model experiments
This commit is contained in:
@@ -1,11 +1,16 @@
|
||||
import pyray as ray
|
||||
|
||||
|
||||
class DevScreen:
|
||||
def __init__(self, width: int, height: int):
|
||||
self.width = width
|
||||
self.height = height
|
||||
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):
|
||||
if not self.screen_init:
|
||||
@@ -13,12 +18,26 @@ class DevScreen:
|
||||
|
||||
def on_screen_end(self, next_screen: str):
|
||||
self.screen_init = False
|
||||
ray.unload_model(self.model)
|
||||
return next_screen
|
||||
|
||||
def update(self):
|
||||
self.on_screen_start()
|
||||
|
||||
if ray.is_key_pressed(ray.KeyboardKey.KEY_ENTER):
|
||||
return self.on_screen_end('RESULT')
|
||||
return self.on_screen_end('GAME')
|
||||
|
||||
def draw(self):
|
||||
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
|
||||
)
|
||||
|
||||
@@ -304,3 +304,6 @@ class EntryScreen:
|
||||
src = ray.Rectangle(0, 0, self.texture_black.width, self.texture_black.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)
|
||||
|
||||
def draw_3d(self):
|
||||
pass
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import bisect
|
||||
import math
|
||||
import sqlite3
|
||||
from collections import deque
|
||||
from pathlib import Path
|
||||
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_fusen'][0]]
|
||||
|
||||
self.tja = TJAParser(song, start_delay=self.start_delay, distance=self.width - GameScreen.JUDGE_X)
|
||||
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)
|
||||
if song == Path(''):
|
||||
self.start_ms = get_current_ms()
|
||||
self.tja = None
|
||||
else:
|
||||
self.movie = None
|
||||
session_data.song_title = self.tja.metadata.title.get(global_data.config['general']['language'].lower(), self.tja.metadata.title['en'])
|
||||
self.tja = TJAParser(song, start_delay=self.start_delay, distance=self.width - GameScreen.JUDGE_X)
|
||||
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)
|
||||
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):
|
||||
if not self.screen_init:
|
||||
@@ -146,6 +151,8 @@ class GameScreen:
|
||||
return next_screen
|
||||
|
||||
def write_score(self):
|
||||
if self.tja is None:
|
||||
return
|
||||
if global_data.config['general']['autoplay']:
|
||||
return
|
||||
with sqlite3.connect('scores.db') as con:
|
||||
@@ -173,14 +180,15 @@ class GameScreen:
|
||||
if self.transition is not None:
|
||||
self.transition.update(get_current_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.song_music is not None:
|
||||
if not audio.is_sound_playing(self.song_music):
|
||||
audio.play_sound(self.song_music)
|
||||
print(f"Song started at {self.current_ms}")
|
||||
if self.movie is not None:
|
||||
self.movie.start(get_current_ms())
|
||||
self.song_started = True
|
||||
if self.tja 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 self.song_music is not None:
|
||||
if not audio.is_sound_playing(self.song_music):
|
||||
audio.play_sound(self.song_music)
|
||||
print(f"Song started at {self.current_ms}")
|
||||
if self.movie is not None:
|
||||
self.movie.start(get_current_ms())
|
||||
self.song_started = True
|
||||
if self.movie is not None:
|
||||
self.movie.update()
|
||||
else:
|
||||
@@ -228,6 +236,9 @@ class GameScreen:
|
||||
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])
|
||||
|
||||
def draw_3d(self):
|
||||
self.player_1.draw_3d(self)
|
||||
|
||||
class Player:
|
||||
TIMING_GOOD = 25.0250015258789
|
||||
TIMING_OK = 75.0750045776367
|
||||
@@ -239,7 +250,10 @@ class Player:
|
||||
self.difficulty = difficulty
|
||||
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.base_score = calculate_base_score(self.play_notes)
|
||||
|
||||
@@ -275,12 +289,23 @@ class Player:
|
||||
|
||||
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.autoplay_hit_side = 'L'
|
||||
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):
|
||||
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:
|
||||
note_type = game_screen.note_type_list[note.type][0]
|
||||
|
||||
self.combo += 1
|
||||
if self.combo > self.max_combo:
|
||||
self.max_combo = self.combo
|
||||
if note.type < 7:
|
||||
self.combo += 1
|
||||
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)
|
||||
#game_screen.background.chibis.append(game_screen.background.Chibi())
|
||||
@@ -710,6 +736,20 @@ class Player:
|
||||
anim.draw(game_screen)
|
||||
#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:
|
||||
def __init__(self, type: str, big: bool, ms_display: Optional[float]=None):
|
||||
self.type = type
|
||||
|
||||
@@ -112,3 +112,5 @@ class LoadScreen:
|
||||
|
||||
if self.fade_in is not None:
|
||||
ray.draw_rectangle(0, 0, self.width, self.height, ray.fade(ray.WHITE, self.fade_in.attribute))
|
||||
def draw_3d(self):
|
||||
pass
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import math
|
||||
from pathlib import Path
|
||||
|
||||
import pyray as ray
|
||||
@@ -252,6 +251,9 @@ class ResultScreen:
|
||||
if self.fade_out is not None:
|
||||
self.fade_out.draw(self.width, self.height)
|
||||
|
||||
def draw_3d(self):
|
||||
pass
|
||||
|
||||
class Crown:
|
||||
def __init__(self):
|
||||
duration = 466
|
||||
|
||||
@@ -264,3 +264,5 @@ class SettingsScreen:
|
||||
else:
|
||||
# Draw exit instruction
|
||||
ray.draw_text("Press Don to exit settings", 250, 100, 20, ray.GREEN)
|
||||
def draw_3d(self):
|
||||
pass
|
||||
|
||||
@@ -314,6 +314,9 @@ class SongSelectScreen:
|
||||
if self.game_transition is not None:
|
||||
self.game_transition.draw(self.screen_height)
|
||||
|
||||
def draw_3d(self):
|
||||
pass
|
||||
|
||||
class SongBox:
|
||||
OUTLINE_MAP = {
|
||||
555: ray.Color(0, 77, 104, 255),
|
||||
|
||||
@@ -127,6 +127,9 @@ class TitleScreen:
|
||||
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))
|
||||
|
||||
def draw_3d(self):
|
||||
pass
|
||||
|
||||
class WarningScreen:
|
||||
class X:
|
||||
DELAY = 4250
|
||||
|
||||
Reference in New Issue
Block a user