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
107
src/main.rs
107
src/main.rs
|
|
@ -52,15 +52,11 @@ impl Beat {
|
||||||
struct BeatMap(Vec<Beat>);
|
struct BeatMap(Vec<Beat>);
|
||||||
|
|
||||||
impl BeatMap {
|
impl BeatMap {
|
||||||
pub fn beat_length(&self) -> f32 {
|
|
||||||
let Some(last_beat) = self.0.last() else {
|
|
||||||
return 0f32;
|
|
||||||
};
|
|
||||||
|
|
||||||
last_beat.position
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn accuracy(&self, compared: &BeatMap) -> f32 {
|
pub fn accuracy(&self, compared: &BeatMap) -> f32 {
|
||||||
|
if self.0.len() != compared.0.len() {
|
||||||
|
return 0f32;
|
||||||
|
}
|
||||||
|
|
||||||
let mut total_accuracy = 1f32;
|
let mut total_accuracy = 1f32;
|
||||||
for i in 0..self.0.len() {
|
for i in 0..self.0.len() {
|
||||||
total_accuracy *= self.0[i].accuracy(&compared.0[i]);
|
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)]
|
#[derive(Resource, Debug)]
|
||||||
struct BeatMapManager {
|
struct BeatMapManager {
|
||||||
pub beatmaps: BTreeMap<String, BeatMap>,
|
pub beatmaps: BTreeMap<BeatMapType, BeatMap>,
|
||||||
pub input: BeatMap,
|
pub input: BeatMap,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -96,11 +117,15 @@ pub struct RhythmPlugin;
|
||||||
impl Plugin for RhythmPlugin {
|
impl Plugin for RhythmPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.add_systems(Startup, setup_metronome)
|
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>) {
|
fn setup_metronome(mut commands: Commands, asset_server: Res<AssetServer>) {
|
||||||
|
use BeatMapType as BMT;
|
||||||
|
|
||||||
commands.insert_resource( MetronomeData {
|
commands.insert_resource( MetronomeData {
|
||||||
sound: asset_server.load("sfx/metronome.wav"),
|
sound: asset_server.load("sfx/metronome.wav"),
|
||||||
timer: Timer::new(duration_from_bpm(120f32), TimerMode::Repeating),
|
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);
|
commands.spawn(Metronome);
|
||||||
|
|
||||||
let beatmap = vec![
|
let demo_beatmap = vec![
|
||||||
Beat::new(0.0, BeatDirection::Down),
|
Beat::new(0.0, BeatDirection::Down),
|
||||||
Beat::new(1.0, BeatDirection::Down),
|
Beat::new(1.0, BeatDirection::Down),
|
||||||
Beat::new(2.0, BeatDirection::Left),
|
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),
|
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();
|
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 {
|
commands.insert_resource(BeatMapManager {
|
||||||
beatmaps,
|
beatmaps,
|
||||||
|
|
@ -156,10 +200,20 @@ fn handle_input(
|
||||||
mut metronome: ResMut<MetronomeData>,
|
mut metronome: ResMut<MetronomeData>,
|
||||||
mut bm: ResMut<BeatMapManager>,
|
mut bm: ResMut<BeatMapManager>,
|
||||||
) {
|
) {
|
||||||
if metronome.current_beat() > bm.beatmaps["test"].beat_length() + 1f32
|
if keyboard_input.just_pressed(KeyCode::Space) {
|
||||||
&& !bm.input.0.is_empty() {
|
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();
|
bm.input.0.clear();
|
||||||
println!("track ended, cleared input");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let input_directions = vec![
|
let input_directions = vec![
|
||||||
|
|
@ -190,26 +244,19 @@ fn handle_input(
|
||||||
bm.input.0.push(Beat::new(metronome.current_beat(), direction));
|
bm.input.0.push(Beat::new(metronome.current_beat(), direction));
|
||||||
println!("pushed {:?}", bm.input.0.last().unwrap());
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn demo_event(_: On<DemoEvent>) {
|
||||||
|
println!("demo event fired!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn another_demo_event(_: On<AnotherDemoEvent>) {
|
||||||
|
println!("another demo event fired!");
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
App::new()
|
App::new()
|
||||||
.add_plugins(DefaultPlugins)
|
.add_plugins(DefaultPlugins)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue