From f9ef04d299ac62cda4001c24903386fe04070a4b Mon Sep 17 00:00:00 2001 From: Manuel Mauro Date: Wed, 3 Apr 2024 17:03:34 +0200 Subject: [PATCH] Make cue types selectable --- src/game/core/cue.rs | 68 ++++++++++--- src/game/mod.rs | 238 +++++++++++++++++++++++++------------------ src/game/settings.rs | 6 ++ src/menu/gui.rs | 3 + 4 files changed, 200 insertions(+), 115 deletions(-) diff --git a/src/game/core/cue.rs b/src/game/core/cue.rs index 238770b..5f489be 100644 --- a/src/game/core/cue.rs +++ b/src/game/core/cue.rs @@ -1,12 +1,16 @@ use std::collections::VecDeque; -use bevy::prelude::*; +use bevy::{prelude::*, render::color}; use rand::{ distributions::{Distribution, Standard}, Rng, }; -use crate::game::tile::{color::TileColor, position::TilePosition, sound::TileSound}; +use crate::game::tile::{ + color::TileColor, + position::{self, TilePosition}, + sound::TileSound, +}; #[derive(Component, Deref, DerefMut)] pub struct CueTimer(pub Timer); @@ -87,18 +91,36 @@ impl CueChain { #[derive(Component, Resource)] pub struct CueEngine { n: usize, - pub positions: CueChain, - pub colors: CueChain, - pub sounds: CueChain, + pub positions: Option>, + pub colors: Option>, + pub sounds: Option>, } impl CueEngine { - pub fn with_n(n: usize) -> Self { + pub fn with(n: usize, position: bool, color: bool, sound: bool) -> Self { + let positions = if position { + Some(CueChain::with_n_back(n)) + } else { + None + }; + + let colors = if color { + Some(CueChain::with_n_back(n)) + } else { + None + }; + + let sounds = if sound { + Some(CueChain::with_n_back(n)) + } else { + None + }; + CueEngine { n, - positions: CueChain::with_n_back(n), - colors: CueChain::with_n_back(n), - sounds: CueChain::with_n_back(n), + positions, + colors, + sounds, } } @@ -106,8 +128,26 @@ impl CueEngine { self.n } - pub fn new_cue(&mut self) -> (TilePosition, TileColor, TileSound) { - (self.positions.gen(), self.colors.gen(), self.sounds.gen()) + pub fn new_cue(&mut self) -> (Option, Option, Option) { + let new_position = if self.positions.is_some() { + Some(self.positions.as_mut().unwrap().gen()) + } else { + None + }; + + let new_color = if self.colors.is_some() { + Some(self.colors.as_mut().unwrap().gen()) + } else { + None + }; + + let new_sound = if self.sounds.is_some() { + Some(self.sounds.as_mut().unwrap().gen()) + } else { + None + }; + + (new_position, new_color, new_sound) } } @@ -117,9 +157,9 @@ impl Default for CueEngine { CueEngine { n, - positions: CueChain::with_n_back(n), - colors: CueChain::with_n_back(n), - sounds: CueChain::with_n_back(n), + positions: Some(CueChain::with_n_back(n)), + colors: Some(CueChain::with_n_back(n)), + sounds: Some(CueChain::with_n_back(n)), } } } diff --git a/src/game/mod.rs b/src/game/mod.rs index f1478bc..a6f4a33 100644 --- a/src/game/mod.rs +++ b/src/game/mod.rs @@ -149,7 +149,12 @@ fn setup( ..default() }, DualNBackBundle { - engine: CueEngine::with_n(settings.n), + engine: CueEngine::with( + settings.n, + settings.position, + settings.color, + settings.sound, + ), round: Round::with_total(settings.rounds), timer: CueTimer::with_duration(settings.round_time), ..default() @@ -173,95 +178,101 @@ fn setup( OnGameScreen, )) .with_children(|parent| { - parent - .spawn(GameButtonBundle { - button: ButtonBundle { - style: Style { - left: Val::Px(-100.0), - top: Val::Px(230.0), - width: Val::Px(150.0), - height: Val::Px(65.0), - border: UiRect::all(Val::Px(3.0)), - justify_content: JustifyContent::Center, - align_items: AlignItems::Center, + if settings.position { + parent + .spawn(GameButtonBundle { + button: ButtonBundle { + style: Style { + left: Val::Px(-100.0), + top: Val::Px(230.0), + width: Val::Px(150.0), + height: Val::Px(65.0), + border: UiRect::all(Val::Px(3.0)), + justify_content: JustifyContent::Center, + align_items: AlignItems::Center, + ..default() + }, + border_color: config::BUTTON_BORDER_COLOR.into(), + background_color: config::NORMAL_BUTTON.into(), ..default() }, - border_color: config::BUTTON_BORDER_COLOR.into(), - background_color: config::NORMAL_BUTTON.into(), - ..default() - }, - shortcut: Shortcut(KeyCode::KeyA), - }) - .with_children(|parent| { - parent.spawn(TextBundle::from_section( - "Position (A)", - TextStyle { - font: asset_server.load("fonts/FiraSans-Bold.ttf"), - font_size: 20.0, - color: Color::rgb(0.9, 0.9, 0.9), - }, - )); - }); + shortcut: Shortcut(KeyCode::KeyA), + }) + .with_children(|parent| { + parent.spawn(TextBundle::from_section( + "Position (A)", + TextStyle { + font: asset_server.load("fonts/FiraSans-Bold.ttf"), + font_size: 20.0, + color: Color::rgb(0.9, 0.9, 0.9), + }, + )); + }); + } - parent - .spawn(GameButtonBundle { - button: ButtonBundle { - style: Style { - left: Val::Px(0.0), - top: Val::Px(230.0), - width: Val::Px(150.0), - height: Val::Px(65.0), - border: UiRect::all(Val::Px(3.0)), - justify_content: JustifyContent::Center, - align_items: AlignItems::Center, + if settings.sound { + parent + .spawn(GameButtonBundle { + button: ButtonBundle { + style: Style { + left: Val::Px(0.0), + top: Val::Px(230.0), + width: Val::Px(150.0), + height: Val::Px(65.0), + border: UiRect::all(Val::Px(3.0)), + justify_content: JustifyContent::Center, + align_items: AlignItems::Center, + ..default() + }, + border_color: config::BUTTON_BORDER_COLOR.into(), + background_color: config::NORMAL_BUTTON.into(), ..default() }, - border_color: config::BUTTON_BORDER_COLOR.into(), - background_color: config::NORMAL_BUTTON.into(), - ..default() - }, - shortcut: Shortcut(KeyCode::KeyS), - }) - .with_children(|parent| { - parent.spawn(TextBundle::from_section( - "Sound (S)", - TextStyle { - font: asset_server.load("fonts/FiraSans-Bold.ttf"), - font_size: 20.0, - color: Color::rgb(0.9, 0.9, 0.9), - }, - )); - }); + shortcut: Shortcut(KeyCode::KeyS), + }) + .with_children(|parent| { + parent.spawn(TextBundle::from_section( + "Sound (S)", + TextStyle { + font: asset_server.load("fonts/FiraSans-Bold.ttf"), + font_size: 20.0, + color: Color::rgb(0.9, 0.9, 0.9), + }, + )); + }); + } - parent - .spawn(GameButtonBundle { - button: ButtonBundle { - style: Style { - left: Val::Px(100.0), - top: Val::Px(230.0), - width: Val::Px(150.0), - height: Val::Px(65.0), - border: UiRect::all(Val::Px(3.0)), - justify_content: JustifyContent::Center, - align_items: AlignItems::Center, + if settings.color { + parent + .spawn(GameButtonBundle { + button: ButtonBundle { + style: Style { + left: Val::Px(100.0), + top: Val::Px(230.0), + width: Val::Px(150.0), + height: Val::Px(65.0), + border: UiRect::all(Val::Px(3.0)), + justify_content: JustifyContent::Center, + align_items: AlignItems::Center, + ..default() + }, + border_color: config::BUTTON_BORDER_COLOR.into(), + background_color: config::NORMAL_BUTTON.into(), ..default() }, - border_color: config::BUTTON_BORDER_COLOR.into(), - background_color: config::NORMAL_BUTTON.into(), - ..default() - }, - shortcut: Shortcut(KeyCode::KeyD), - }) - .with_children(|parent| { - parent.spawn(TextBundle::from_section( - "Color (D)", - TextStyle { - font: asset_server.load("fonts/FiraSans-Bold.ttf"), - font_size: 20.0, - color: Color::rgb(0.9, 0.9, 0.9), - }, - )); - }); + shortcut: Shortcut(KeyCode::KeyD), + }) + .with_children(|parent| { + parent.spawn(TextBundle::from_section( + "Color (D)", + TextStyle { + font: asset_server.load("fonts/FiraSans-Bold.ttf"), + font_size: 20.0, + color: Color::rgb(0.9, 0.9, 0.9), + }, + )); + }); + } }); } @@ -309,36 +320,61 @@ fn end_of_round_system( query.get_single_mut() { if timer.just_finished() { - if round.answer.position { - if engine.positions.is_match() { - score.record_tp(); + if let Some(positions) = &engine.positions { + if round.answer.position { + if positions.is_match() { + score.record_tp(); + } else { + score.record_fp(); + } + } else if positions.is_match() { + score.record_fn(); + } else { + score.record_tn(); + } + } + + if let Some(colors) = &engine.colors { + if round.answer.color { + if colors.is_match() { + score.record_tp(); + } else { + score.record_fp(); + } + } else if colors.is_match() { + score.record_fn(); } else { - score.record_fp(); + score.record_tn(); } - } else if engine.positions.is_match() { - score.record_fn(); - } else { - score.record_tn(); } - if round.answer.color { - if engine.colors.is_match() { - score.record_tp(); + if let Some(sounds) = &engine.sounds { + if round.answer.sound { + if sounds.is_match() { + score.record_tp(); + } else { + score.record_fp(); + } + } else if sounds.is_match() { + score.record_fn(); } else { - score.record_fp(); + score.record_tn(); } - } else if engine.colors.is_match() { - score.record_fn(); - } else { - score.record_tn(); } round.answer.reset(); let (new_position, new_color, new_sound) = engine.new_cue(); - *position = new_position; - *color = new_color; - *sound = new_sound; + if let Some(new_position) = new_position { + *position = new_position; + } + if let Some(new_color) = new_color { + *color = new_color; + } + if let Some(new_sound) = new_sound { + *sound = new_sound; + } + round.current += 1; } } diff --git a/src/game/settings.rs b/src/game/settings.rs index 3eb7c83..58ae5c9 100644 --- a/src/game/settings.rs +++ b/src/game/settings.rs @@ -5,6 +5,9 @@ pub struct GameSettings { pub n: usize, pub rounds: usize, pub round_time: f32, + pub position: bool, + pub color: bool, + pub sound: bool, } impl Default for GameSettings { @@ -13,6 +16,9 @@ impl Default for GameSettings { n: 2, rounds: 24, round_time: 3.0, + position: true, + color: false, + sound: true, } } } diff --git a/src/menu/gui.rs b/src/menu/gui.rs index 53d1bba..8d66fca 100644 --- a/src/menu/gui.rs +++ b/src/menu/gui.rs @@ -29,6 +29,9 @@ pub fn menu_ui( ui.add(egui::Slider::new(&mut settings.rounds, 1..=50).text("Rounds")); ui.add(egui::Slider::new(&mut settings.round_time, 0.5..=4.0).text("Round Time")); ui.add(egui::Slider::new(&mut settings.n, 1..=7).text("N-back")); + ui.add(egui::Checkbox::new(&mut settings.position, "Position")); + ui.add(egui::Checkbox::new(&mut settings.color, "Color")); + ui.add(egui::Checkbox::new(&mut settings.sound, "Sound")); if ui.button("Play").clicked() { app_state.set(AppState::Game);