rosu_renderer/
lib.rs

1pub mod layout;
2
3use crate::layout::mania::{ManiaRenderer, NoteStyle};
4use rosu_map::section::general::GameMode;
5use rosu_map::Beatmap;
6use std::time::Instant;
7
8pub struct Player {
9    beatmap: Beatmap,
10    renderer: GameModeRenderer,
11    start_time: Instant,
12    speed: f64,
13    scroll_time_ms: f32,
14}
15
16enum GameModeRenderer {
17    Mania(ManiaRenderer),
18    // TODO: Ajouter d'autres modes
19    // Standard(StandardRenderer),
20    // Taiko(TaikoRenderer),
21    // Catch(CatchRenderer),
22}
23
24impl Player {
25    pub fn new(beatmap: Beatmap, column_width: f32, note_size: f32, height: f32) -> Option<Self> {
26        // Créer le renderer approprié en fonction du mode de jeu
27        let renderer = match beatmap.mode {
28            GameMode::Mania => {
29                GameModeRenderer::Mania(ManiaRenderer::with_sizes(column_width, note_size, height))
30            }
31            // TODO: Ajouter d'autres modes
32            // GameMode::Osu => GameModeRenderer::Standard(...),
33            // GameMode::Taiko => GameModeRenderer::Taiko(...),
34            // GameMode::Catch => GameModeRenderer::Catch(...),
35            _ => return None, // Mode non supporté
36        };
37
38        Some(Self {
39            beatmap,
40            renderer,
41            start_time: Instant::now(),
42            speed: 1.0,
43            scroll_time_ms: 1000.0,
44        })
45    }
46
47    pub fn set_note_style(&mut self, style: NoteStyle) {
48        #[allow(irrefutable_let_patterns)]
49        if let GameModeRenderer::Mania(mania) = &mut self.renderer {
50            mania.set_note_style(style);
51        }
52    }
53
54    pub fn get_required_size(&self) -> [f32; 2] {
55        match &self.renderer {
56            GameModeRenderer::Mania(mania) => {
57                let keycount = self.beatmap.circle_size as usize;
58                [mania.required_width(keycount), mania.required_height()]
59            }
60            // TODO: Ajouter d'autres modes
61            // GameModeRenderer::Standard(std) => std.get_required_size(),
62            // GameModeRenderer::Taiko(taiko) => taiko.get_required_size(),
63            // GameModeRenderer::Catch(catch) => catch.get_required_size(),
64        }
65    }
66
67    pub fn set_speed(&mut self, speed: f64) {
68        self.speed = speed;
69    }
70
71    pub fn set_scroll_time(&mut self, ms: f32) {
72        self.scroll_time_ms = ms;
73    }
74
75    pub fn render(&mut self, ui: &mut egui::Ui) {
76        let current_time = self.start_time.elapsed().as_secs_f64() * 1000.0;
77        let hit_objects = &self.beatmap.hit_objects;
78
79        match &mut self.renderer {
80            GameModeRenderer::Mania(mania) => {
81                let keycount = self.beatmap.circle_size as usize;
82                mania.render(
83                    ui,
84                    hit_objects,
85                    current_time,
86                    self.scroll_time_ms,
87                    self.speed,
88                    keycount,
89                );
90            }
91            // TODO: Ajouter d'autres modes
92            // GameModeRenderer::Standard(std) => std.render(...),
93            // GameModeRenderer::Taiko(taiko) => taiko.render(...),
94            // GameModeRenderer::Catch(catch) => catch.render(...),
95        }
96    }
97
98    pub fn reset_time(&mut self) {
99        self.start_time = Instant::now();
100    }
101
102    pub fn set_current_time(&mut self, time_ms: f64) {
103        self.start_time = Instant::now() - std::time::Duration::from_secs_f64(time_ms / 1000.0);
104    }
105
106    pub fn current_time(&self) -> f64 {
107        self.start_time.elapsed().as_secs_f64() * 1000.0
108    }
109}