generated from 2ndbeam/bevy-template
feat: Added proper event handling for different beatmaps
This commit is contained in:
parent
f5eb328ea8
commit
21fd428108
1 changed files with 77 additions and 30 deletions
103
src/main.rs
103
src/main.rs
|
|
@ -52,15 +52,11 @@ impl Beat {
|
|||
struct BeatMap(Vec<Beat>);
|
||||
|
||||
impl BeatMap {
|
||||
pub fn beat_length(&self) -> f32 {
|
||||
let Some(last_beat) = self.0.last() else {
|
||||
pub fn accuracy(&self, compared: &BeatMap) -> f32 {
|
||||
if self.0.len() != compared.0.len() {
|
||||
return 0f32;
|
||||
};
|
||||
|
||||
last_beat.position
|
||||
}
|
||||
|
||||
pub fn accuracy(&self, compared: &BeatMap) -> f32 {
|
||||
let mut total_accuracy = 1f32;
|
||||
for i in 0..self.0.len() {
|
||||
total_accuracy *= self.0[i].accuracy(&compared.0[i]);
|
||||
|
|
@ -69,9 +65,34 @@ impl BeatMap {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Event)]
|
||||
struct DemoEvent;
|
||||
|
||||
#[derive(Event)]
|
||||
struct AnotherDemoEvent;
|
||||
|
||||
#[derive(PartialEq, PartialOrd, Eq, Ord, Debug)]
|
||||
enum BeatMapType {
|
||||
Demo,
|
||||
AnotherDemo,
|
||||
}
|
||||
|
||||
impl BeatMapType {
|
||||
fn fire_event(&self, commands: &mut Commands) {
|
||||
match self {
|
||||
Self::Demo => {
|
||||
commands.trigger(DemoEvent);
|
||||
},
|
||||
Self::AnotherDemo => {
|
||||
commands.trigger(AnotherDemoEvent);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Resource, Debug)]
|
||||
struct BeatMapManager {
|
||||
pub beatmaps: BTreeMap<String, BeatMap>,
|
||||
pub beatmaps: BTreeMap<BeatMapType, BeatMap>,
|
||||
pub input: BeatMap,
|
||||
}
|
||||
|
||||
|
|
@ -96,11 +117,15 @@ pub struct RhythmPlugin;
|
|||
impl Plugin for RhythmPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_systems(Startup, setup_metronome)
|
||||
.add_systems(Update, (tick_metronome, handle_input).chain());
|
||||
.add_systems(Update, (tick_metronome, handle_input).chain())
|
||||
.add_observer(demo_event)
|
||||
.add_observer(another_demo_event);
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_metronome(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||
use BeatMapType as BMT;
|
||||
|
||||
commands.insert_resource( MetronomeData {
|
||||
sound: asset_server.load("sfx/metronome.wav"),
|
||||
timer: Timer::new(duration_from_bpm(120f32), TimerMode::Repeating),
|
||||
|
|
@ -108,7 +133,7 @@ fn setup_metronome(mut commands: Commands, asset_server: Res<AssetServer>) {
|
|||
});
|
||||
commands.spawn(Metronome);
|
||||
|
||||
let beatmap = vec![
|
||||
let demo_beatmap = vec![
|
||||
Beat::new(0.0, BeatDirection::Down),
|
||||
Beat::new(1.0, BeatDirection::Down),
|
||||
Beat::new(2.0, BeatDirection::Left),
|
||||
|
|
@ -122,8 +147,27 @@ fn setup_metronome(mut commands: Commands, asset_server: Res<AssetServer>) {
|
|||
Beat::new(7.0, BeatDirection::Up),
|
||||
];
|
||||
|
||||
let another_beatmap = vec![
|
||||
Beat::new(0.0, BeatDirection::Up),
|
||||
Beat::new(1.0, BeatDirection::Right),
|
||||
Beat::new(1.5, BeatDirection::Right),
|
||||
Beat::new(2.0, BeatDirection::Right),
|
||||
Beat::new(3.0, BeatDirection::Left),
|
||||
Beat::new(3.5, BeatDirection::Left),
|
||||
Beat::new(4.5, BeatDirection::Down),
|
||||
Beat::new(5.0, BeatDirection::Down),
|
||||
Beat::new(6.0, BeatDirection::Up),
|
||||
Beat::new(6.5, BeatDirection::Right),
|
||||
Beat::new(7.0, BeatDirection::Up),
|
||||
Beat::new(8.0, BeatDirection::Left),
|
||||
Beat::new(8.5, BeatDirection::Down),
|
||||
Beat::new(9.5, BeatDirection::Down),
|
||||
Beat::new(10.0, BeatDirection::Right),
|
||||
];
|
||||
|
||||
let mut beatmaps = BTreeMap::new();
|
||||
beatmaps.insert("test".into(), BeatMap(beatmap));
|
||||
beatmaps.insert(BMT::Demo, BeatMap(demo_beatmap));
|
||||
beatmaps.insert(BMT::AnotherDemo, BeatMap(another_beatmap));
|
||||
|
||||
commands.insert_resource(BeatMapManager {
|
||||
beatmaps,
|
||||
|
|
@ -156,10 +200,20 @@ fn handle_input(
|
|||
mut metronome: ResMut<MetronomeData>,
|
||||
mut bm: ResMut<BeatMapManager>,
|
||||
) {
|
||||
if metronome.current_beat() > bm.beatmaps["test"].beat_length() + 1f32
|
||||
&& !bm.input.0.is_empty() {
|
||||
if keyboard_input.just_pressed(KeyCode::Space) {
|
||||
println!("checking input...");
|
||||
|
||||
for (bm_type, beatmap) in bm.beatmaps.iter() {
|
||||
let total_accuracy = beatmap.accuracy(&bm.input);
|
||||
println!("accuracy for {:?}: {}%", bm_type, total_accuracy * 100f32);
|
||||
if total_accuracy >= 0.85 {
|
||||
bm_type.fire_event(&mut commands);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
println!("cleared input");
|
||||
bm.input.0.clear();
|
||||
println!("track ended, cleared input");
|
||||
}
|
||||
|
||||
let input_directions = vec![
|
||||
|
|
@ -190,26 +244,19 @@ fn handle_input(
|
|||
bm.input.0.push(Beat::new(metronome.current_beat(), direction));
|
||||
println!("pushed {:?}", bm.input.0.last().unwrap());
|
||||
|
||||
let last_index = bm.input.0.len() - 1;
|
||||
|
||||
if bm.beatmaps["test"].0.len() > last_index {
|
||||
let accuracy = bm.beatmaps["test"].0[last_index].accuracy(bm.input.0.last().unwrap());
|
||||
println!("accuracy: {}%", accuracy * 100f32);
|
||||
}
|
||||
if bm.beatmaps["test"].0.len() == bm.input.0.len() {
|
||||
let total_accuracy = bm.beatmaps["test"].accuracy(&bm.input);
|
||||
println!("sequence completed, total accuracy: {}%", total_accuracy * 100f32);
|
||||
if total_accuracy >= 0.85 {
|
||||
println!("accuracy > 85%; imagine like something happened");
|
||||
}
|
||||
bm.input.0.clear();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn demo_event(_: On<DemoEvent>) {
|
||||
println!("demo event fired!");
|
||||
}
|
||||
|
||||
fn another_demo_event(_: On<AnotherDemoEvent>) {
|
||||
println!("another demo event fired!");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins(DefaultPlugins)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue