diff --git a/src/constants.rs b/src/constants.rs index c4028d7..2a90aec 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -2,6 +2,7 @@ /// Fast PC mode at 400 cycles/ms. pub const CLOCK_PERIOD: f32 = 0.184; pub const PLAYER_STEP_PERIOD: f32 = 1.0 / 7.5; +pub const FLASHING_PERIOD: f32 = 0.02; pub const SIDEBAR_POS_X: i32 = 66; pub const SIDEBAR_POS_Y: i32 = 0; diff --git a/src/graphics/flashing_message.rs b/src/graphics/flashing_message.rs new file mode 100644 index 0000000..5cfd69e --- /dev/null +++ b/src/graphics/flashing_message.rs @@ -0,0 +1,18 @@ +use crate::constants::*; +use crate::graphics::vga_color as vga; +use crate::resources::Resources; +use bracket_lib::prelude::*; + +pub fn draw(resources: &mut Resources, bterm: &mut BTerm) { + if let Some(flashing_message) = &mut resources.flashing_message { + flashing_message.next_color(); + + bterm.print_color_centered_at( + MAP_X + (MAP_WIDTH / 2) - 1, + MAP_Y + MAP_HEIGHT, + RGB::named(vga::get_by_index(flashing_message.color)), + RGB::named(vga::BLACK), + format!(" {} ", &flashing_message.message), + ); + } +} diff --git a/src/graphics/mod.rs b/src/graphics/mod.rs index c2ef34b..b587b48 100644 --- a/src/graphics/mod.rs +++ b/src/graphics/mod.rs @@ -4,15 +4,17 @@ use hecs::World; use crate::resources::Resources; mod entities; +mod flashing_message; mod map; mod sidebar; pub mod vga_color; mod whip; -pub fn draw(world: &World, resources: &Resources, bterm: &mut BTerm) { +pub fn draw(world: &World, resources: &mut Resources, bterm: &mut BTerm) { bterm.cls(); map::draw(resources, bterm); entities::draw(world, bterm); whip::draw(world, resources, bterm); + flashing_message::draw(resources, bterm); sidebar::draw(resources, bterm); } diff --git a/src/input/mod.rs b/src/input/mod.rs index 15c2318..d7a69cd 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -6,41 +6,57 @@ use crate::resources::*; mod player; pub fn handle(world: &mut World, resources: &mut Resources, bterm: &mut BTerm) { - match bterm.key { - None => {} - Some(key) => match key { - VirtualKeyCode::Left | VirtualKeyCode::J => { - player::try_move(-1, 0, world, resources); - } - VirtualKeyCode::U | VirtualKeyCode::Home => player::try_move(-1, -1, world, resources), - VirtualKeyCode::Up | VirtualKeyCode::I => { - player::try_move(0, -1, world, resources); - } - VirtualKeyCode::O | VirtualKeyCode::PageUp => player::try_move(1, -1, world, resources), - VirtualKeyCode::Right | VirtualKeyCode::K => { - player::try_move(1, 0, world, resources); - } - VirtualKeyCode::Comma | VirtualKeyCode::PageDown => { - player::try_move(1, 1, world, resources) - } - VirtualKeyCode::Down | VirtualKeyCode::M => { - player::try_move(0, 1, world, resources); - } - VirtualKeyCode::N | VirtualKeyCode::End => player::try_move(-1, 1, world, resources), - VirtualKeyCode::W => { - player::whip(world, resources); - } - VirtualKeyCode::D => { - resources.show_debug_info = !resources.show_debug_info; - } - VirtualKeyCode::Escape | VirtualKeyCode::Q => { - bterm.quit(); - } - _ => { - resources - .sound_output - .play_sound(resources.sound_effects.bad_key.clone()); - } - }, + if resources.flashing_message.is_some() { + if bterm.key.is_some() { + resources.flashing_message = None; + } + } else { + match bterm.key { + None => {} + Some(key) => match key { + VirtualKeyCode::Left | VirtualKeyCode::J => { + player::try_move(-1, 0, world, resources); + } + VirtualKeyCode::U | VirtualKeyCode::Home => { + player::try_move(-1, -1, world, resources) + } + VirtualKeyCode::Up | VirtualKeyCode::I => { + player::try_move(0, -1, world, resources); + } + VirtualKeyCode::O | VirtualKeyCode::PageUp => { + player::try_move(1, -1, world, resources) + } + VirtualKeyCode::Right | VirtualKeyCode::K => { + player::try_move(1, 0, world, resources); + } + VirtualKeyCode::Comma | VirtualKeyCode::PageDown => { + player::try_move(1, 1, world, resources) + } + VirtualKeyCode::Down | VirtualKeyCode::M => { + player::try_move(0, 1, world, resources); + } + VirtualKeyCode::N | VirtualKeyCode::End => { + player::try_move(-1, 1, world, resources) + } + VirtualKeyCode::W => { + player::whip(world, resources); + } + VirtualKeyCode::D => { + resources.show_debug_info = !resources.show_debug_info; + } + VirtualKeyCode::Escape | VirtualKeyCode::Q => { + bterm.quit(); + } + VirtualKeyCode::P => { + resources.flashing_message = + Some(FlashingMessage::from("Press any key to resume game.")); + } + _ => { + resources + .sound_output + .play_sound(resources.sound_effects.bad_key.clone()); + } + }, + } } } diff --git a/src/main.rs b/src/main.rs index 317ae33..7504bf0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -57,6 +57,7 @@ fn main() -> BError { sound_effects, sound_output, selected_difficulty: Some(selected_difficulty), + flashing_message: None, }; // let descent_sounds: Vec = (20..100) diff --git a/src/resources/flashing_message.rs b/src/resources/flashing_message.rs new file mode 100644 index 0000000..03f9967 --- /dev/null +++ b/src/resources/flashing_message.rs @@ -0,0 +1,32 @@ +use std::time::{Duration, Instant}; + +use crate::constants::*; + +pub struct FlashingMessage { + pub message: String, + pub color: usize, + pub last_changed_color: Instant, +} + +impl FlashingMessage { + pub fn next_color(&mut self) { + let now = Instant::now(); + if now - self.last_changed_color > Duration::from_secs_f32(FLASHING_PERIOD) { + self.color += 1; + if self.color > 15 { + self.color = 13 + } + self.last_changed_color = now; + } + } +} + +impl From<&str> for FlashingMessage { + fn from(message: &str) -> Self { + Self { + message: message.to_string(), + color: 14, + last_changed_color: Instant::now(), + } + } +} diff --git a/src/resources/mod.rs b/src/resources/mod.rs index 0a3425d..4e79285 100644 --- a/src/resources/mod.rs +++ b/src/resources/mod.rs @@ -1,5 +1,6 @@ pub mod clock; pub mod difficulty; +pub mod flashing_message; pub mod map; pub mod sound_effects; pub mod sound_output; @@ -8,6 +9,7 @@ pub mod stats; use bracket_lib::prelude::*; pub use clock::{Clock, StopClock}; pub use difficulty::Difficulty; +pub use flashing_message::FlashingMessage; pub use map::Map; pub use sound_effects::SoundEffects; pub use sound_output::SoundOutput; @@ -24,4 +26,5 @@ pub struct Resources { pub selected_difficulty: Option, pub sound_effects: SoundEffects, pub sound_output: SoundOutput, + pub flashing_message: Option, } diff --git a/src/state.rs b/src/state.rs index b992e9f..d09162d 100644 --- a/src/state.rs +++ b/src/state.rs @@ -12,7 +12,7 @@ impl GameState for State { fn tick(&mut self, bterm: &mut BTerm) { input::handle(&mut self.world, &mut self.resources, bterm); systems::run(&mut self.world, &mut self.resources); - graphics::draw(&self.world, &self.resources, bterm); + graphics::draw(&self.world, &mut self.resources, bterm); } } diff --git a/src/systems/time.rs b/src/systems/time.rs index 4686e31..e924f47 100644 --- a/src/systems/time.rs +++ b/src/systems/time.rs @@ -5,7 +5,7 @@ use crate::constants::CLOCK_PERIOD; use crate::resources::{Clock, Resources}; pub fn run(resources: &mut Resources) { - if !resources.stop_clock { + if !resources.stop_clock && resources.flashing_message.is_none() { try_tick(&mut resources.clock); } else { reset(&mut resources.clock);