From def124cd71c0254be523e239fac15442f5c33241 Mon Sep 17 00:00:00 2001 From: Alex Page Date: Thu, 3 Feb 2022 17:32:45 -0500 Subject: [PATCH 1/8] Add support for bottom flashing messages --- src/constants.rs | 1 + src/graphics/flashing_message.rs | 18 +++++++ src/graphics/mod.rs | 4 +- src/input/mod.rs | 88 ++++++++++++++++++------------- src/main.rs | 1 + src/resources/flashing_message.rs | 32 +++++++++++ src/resources/mod.rs | 3 ++ src/state.rs | 2 +- src/systems/time.rs | 2 +- 9 files changed, 112 insertions(+), 39 deletions(-) create mode 100644 src/graphics/flashing_message.rs create mode 100644 src/resources/flashing_message.rs 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); From 0e5e823b0b52a0c62c68f1eda1e4c70d768d49ec Mon Sep 17 00:00:00 2001 From: Alex Page Date: Thu, 3 Feb 2022 17:57:30 -0500 Subject: [PATCH 2/8] Add flashing message intents --- src/graphics/flashing_message.rs | 2 +- src/input/mod.rs | 29 ++++++++++++++++++++++++++--- src/resources/flashing_message.rs | 28 +++++++++++++++++++++++----- 3 files changed, 50 insertions(+), 9 deletions(-) diff --git a/src/graphics/flashing_message.rs b/src/graphics/flashing_message.rs index 5cfd69e..27ce2b2 100644 --- a/src/graphics/flashing_message.rs +++ b/src/graphics/flashing_message.rs @@ -12,7 +12,7 @@ pub fn draw(resources: &mut Resources, bterm: &mut BTerm) { MAP_Y + MAP_HEIGHT, RGB::named(vga::get_by_index(flashing_message.color)), RGB::named(vga::BLACK), - format!(" {} ", &flashing_message.message), + flashing_message.message.to_string(), ); } } diff --git a/src/input/mod.rs b/src/input/mod.rs index d7a69cd..0b6f729 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -1,13 +1,33 @@ use bracket_lib::prelude::*; use hecs::World; -use crate::resources::*; +use crate::resources::{flashing_message::FlashingMessageIntent, *}; mod player; +pub fn handle_intent(bterm: &mut BTerm, world: &mut World, resources: &mut Resources) { + if let Some(key) = bterm.key { + if let Some(flashing_message) = &resources.flashing_message { + if let Some(intent) = &flashing_message.intent { + match intent { + FlashingMessageIntent::Quit => { + if key == VirtualKeyCode::Y { + bterm.quit() + } + } + FlashingMessageIntent::Save => todo!(), + FlashingMessageIntent::Restore => todo!(), + FlashingMessageIntent::Restart => todo!(), + } + } + } + } +} + pub fn handle(world: &mut World, resources: &mut Resources, bterm: &mut BTerm) { if resources.flashing_message.is_some() { if bterm.key.is_some() { + handle_intent(bterm, world, resources); resources.flashing_message = None; } } else { @@ -45,11 +65,14 @@ pub fn handle(world: &mut World, resources: &mut Resources, bterm: &mut BTerm) { resources.show_debug_info = !resources.show_debug_info; } VirtualKeyCode::Escape | VirtualKeyCode::Q => { - bterm.quit(); + resources.flashing_message = Some(FlashingMessage::new( + " Are you sure you want to quit (Y/N)? ", + Some(FlashingMessageIntent::Quit), + )); } VirtualKeyCode::P => { resources.flashing_message = - Some(FlashingMessage::from("Press any key to resume game.")); + Some(FlashingMessage::from(" Press any key to resume game. ")); } _ => { resources diff --git a/src/resources/flashing_message.rs b/src/resources/flashing_message.rs index 03f9967..14f3c74 100644 --- a/src/resources/flashing_message.rs +++ b/src/resources/flashing_message.rs @@ -1,14 +1,36 @@ use std::time::{Duration, Instant}; +use bracket_lib::prelude::{BTerm, VirtualKeyCode}; +use hecs::World; + use crate::constants::*; +use super::Resources; + +pub enum FlashingMessageIntent { + Quit, + Save, + Restore, + Restart, +} + pub struct FlashingMessage { pub message: String, pub color: usize, pub last_changed_color: Instant, + pub intent: Option, } impl FlashingMessage { + pub fn new(message: &str, intent: Option) -> Self { + Self { + message: message.to_string(), + color: 14, + last_changed_color: Instant::now(), + intent, + } + } + pub fn next_color(&mut self) { let now = Instant::now(); if now - self.last_changed_color > Duration::from_secs_f32(FLASHING_PERIOD) { @@ -23,10 +45,6 @@ impl FlashingMessage { impl From<&str> for FlashingMessage { fn from(message: &str) -> Self { - Self { - message: message.to_string(), - color: 14, - last_changed_color: Instant::now(), - } + Self::new(message, None) } } From 550713aaf858908d2a984ad5efbe66fa3ee2b4a7 Mon Sep 17 00:00:00 2001 From: Alex Page Date: Thu, 3 Feb 2022 19:18:38 -0500 Subject: [PATCH 3/8] Better center flashing messages --- src/graphics/flashing_message.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/flashing_message.rs b/src/graphics/flashing_message.rs index 27ce2b2..23d1d02 100644 --- a/src/graphics/flashing_message.rs +++ b/src/graphics/flashing_message.rs @@ -8,7 +8,7 @@ pub fn draw(resources: &mut Resources, bterm: &mut BTerm) { flashing_message.next_color(); bterm.print_color_centered_at( - MAP_X + (MAP_WIDTH / 2) - 1, + MAP_X + (MAP_WIDTH / 2), MAP_Y + MAP_HEIGHT, RGB::named(vga::get_by_index(flashing_message.color)), RGB::named(vga::BLACK), From 094d8e8617666554fecee5d0f7c0045d7a7a7d4f Mon Sep 17 00:00:00 2001 From: Alex Page Date: Thu, 3 Feb 2022 19:19:00 -0500 Subject: [PATCH 4/8] Allow input to fall through flashing messages This is for parity with the original game --- src/input/mod.rs | 109 ++++++++++++++++----------------- src/resources/sound_effects.rs | 14 +++++ 2 files changed, 66 insertions(+), 57 deletions(-) diff --git a/src/input/mod.rs b/src/input/mod.rs index 0b6f729..0907753 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -5,7 +5,7 @@ use crate::resources::{flashing_message::FlashingMessageIntent, *}; mod player; -pub fn handle_intent(bterm: &mut BTerm, world: &mut World, resources: &mut Resources) { +pub fn handle_intent(bterm: &mut BTerm, _world: &mut World, resources: &mut Resources) { if let Some(key) = bterm.key { if let Some(flashing_message) = &resources.flashing_message { if let Some(intent) = &flashing_message.intent { @@ -25,61 +25,56 @@ pub fn handle_intent(bterm: &mut BTerm, world: &mut World, resources: &mut Resou } pub fn handle(world: &mut World, resources: &mut Resources, bterm: &mut BTerm) { - if resources.flashing_message.is_some() { - if bterm.key.is_some() { - handle_intent(bterm, world, resources); - 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 => { - resources.flashing_message = Some(FlashingMessage::new( - " Are you sure you want to quit (Y/N)? ", - Some(FlashingMessageIntent::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()); - } - }, - } + if resources.flashing_message.is_some() && bterm.key.is_some() { + handle_intent(bterm, world, resources); + resources.flashing_message = None; + } + + 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 => { + resources.flashing_message = Some(FlashingMessage::new( + " Are you sure you want to quit (Y/N)? ", + Some(FlashingMessageIntent::Quit), + )); + } + VirtualKeyCode::P => { + resources + .sound_output + .play_sound(resources.sound_effects.pause.clone()); + 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/resources/sound_effects.rs b/src/resources/sound_effects.rs index f0779c1..f0b7267 100644 --- a/src/resources/sound_effects.rs +++ b/src/resources/sound_effects.rs @@ -38,6 +38,7 @@ pub struct SoundEffects { pub slow_hit: SoundSamples, pub medium_hit: SoundSamples, pub fast_hit: SoundSamples, + pub pause: SoundSamples, rng: RandomNumberGenerator, } @@ -153,6 +154,19 @@ impl SoundEffects { duration: Duration::from_millis(25), }], }), + pause: sound_output.render_sound_effect(&SoundEffect { + sounds: { + let mut sounds = vec![Sound { + sound_type: SoundType::Tone(500), + duration: Duration::from_millis(100), + }]; + sounds.extend((100..=200).rev().step_by(10).map(|x| Sound { + sound_type: SoundType::Tone(x), + duration: Duration::from_millis(20), + })); + sounds + }, + }), rng: RandomNumberGenerator::new(), } } From e948ad1d9343244d507d2944e80d7cef657ee369 Mon Sep 17 00:00:00 2001 From: Alex Page Date: Thu, 3 Feb 2022 19:19:40 -0500 Subject: [PATCH 5/8] Remove unused imports --- src/resources/flashing_message.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/resources/flashing_message.rs b/src/resources/flashing_message.rs index 14f3c74..6155c72 100644 --- a/src/resources/flashing_message.rs +++ b/src/resources/flashing_message.rs @@ -1,12 +1,7 @@ use std::time::{Duration, Instant}; -use bracket_lib::prelude::{BTerm, VirtualKeyCode}; -use hecs::World; - use crate::constants::*; -use super::Resources; - pub enum FlashingMessageIntent { Quit, Save, From 2b484a4ad7b6020e5aa14ec88d6aa908b53f1994 Mon Sep 17 00:00:00 2001 From: Alex Page Date: Thu, 3 Feb 2022 20:11:58 -0500 Subject: [PATCH 6/8] Clear tile content when monster eats a block --- src/systems/monster_ai.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/systems/monster_ai.rs b/src/systems/monster_ai.rs index 32061dd..8123234 100644 --- a/src/systems/monster_ai.rs +++ b/src/systems/monster_ai.rs @@ -74,6 +74,7 @@ pub fn run(world: &mut World, resources: &mut Resources) { resources.stats.add_score(1); *tile = TileType::Floor; to_kill.push(entity); + resources.map.clear_tile_content_at(Point::from(*position)); } _ => { resources.map.clear_tile_content_at(Point::from(*position)); From f38a80b0c7f21a41c1e5baa5821cb7647dc6ea95 Mon Sep 17 00:00:00 2001 From: Alex Page Date: Thu, 3 Feb 2022 20:16:06 -0500 Subject: [PATCH 7/8] Implement deserializing non-random levels --- src/main.rs | 2 +- src/resources/map.rs | 91 ++++++++++++++++++++++++++------------------ src/tile_data.rs | 58 ++++++++++++++++++++++++++++ 3 files changed, 114 insertions(+), 37 deletions(-) diff --git a/src/main.rs b/src/main.rs index 7504bf0..6a847bd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -32,7 +32,7 @@ fn main() -> BError { let mut world = World::new(); - let mut map = Map::from_level(levels::get_level(starting_level)); + let mut map = Map::from(levels::get_level(starting_level)); map.spawn_entities(&mut world); let resources = Resources { diff --git a/src/resources/map.rs b/src/resources/map.rs index 76ad3b2..bef1dc5 100644 --- a/src/resources/map.rs +++ b/src/resources/map.rs @@ -44,42 +44,6 @@ impl Map { } } - pub fn from_level(level: Level) -> Self { - match level { - Level::Normal(_data) => todo!(), - Level::Randomized(data) => { - let mut rng = RandomNumberGenerator::new(); - let mut map = Self::new(); - for (tile, count) in data { - for _ in 0..count { - loop { - let point = Point { - x: rng.range(0, MAP_WIDTH as i32), - y: rng.range(0, MAP_HEIGHT as i32), - }; - if map.get_tile_at(point) == TileType::Floor { - map.set_tile_at(point, tile); - break; - } - } - } - } - loop { - let point = Point { - x: rng.range(0, MAP_WIDTH as i32), - y: rng.range(0, MAP_HEIGHT as i32), - }; - if map.get_tile_at(point) == TileType::Floor { - map.set_tile_at(point, TileType::Player); - break; - } - } - map - } - Level::End => todo!(), - } - } - pub fn spawn_entities(&mut self, world: &mut World) { for (index, tile) in self .tiles @@ -246,3 +210,58 @@ impl Map { self.tiles[index] = tile; } } + +impl From for Map { + fn from(level: Level) -> Self { + match level { + Level::Normal(data) => { + assert_eq!(data.len(), MAP_HEIGHT, "Level data is incorrect height!"); + + let mut map = Self::new(); + for (y, line) in data.iter().enumerate() { + assert_eq!(line.len(), MAP_WIDTH, "Level data is incorrect width!"); + for (x, c) in line.chars().enumerate() { + map.set_tile_at( + Point { + x: x as i32, + y: y as i32, + }, + TileType::from(c), + ); + } + } + map + } + Level::Randomized(data) => { + let mut rng = RandomNumberGenerator::new(); + let mut map = Self::new(); + for (tile, count) in data { + for _ in 0..count { + loop { + let point = Point { + x: rng.range(0, MAP_WIDTH as i32), + y: rng.range(0, MAP_HEIGHT as i32), + }; + if map.get_tile_at(point) == TileType::Floor { + map.set_tile_at(point, tile); + break; + } + } + } + } + loop { + let point = Point { + x: rng.range(0, MAP_WIDTH as i32), + y: rng.range(0, MAP_HEIGHT as i32), + }; + if map.get_tile_at(point) == TileType::Floor { + map.set_tile_at(point, TileType::Player); + break; + } + } + map + } + Level::End => todo!(), + } + } +} diff --git a/src/tile_data.rs b/src/tile_data.rs index 775889b..a6bc744 100644 --- a/src/tile_data.rs +++ b/src/tile_data.rs @@ -375,3 +375,61 @@ pub fn tile_data(tile: TileType) -> TileData { }, } } + +impl From for TileType { + fn from(c: char) -> Self { + match c { + ' ' => TileType::Floor, + '1' => TileType::Slow, + '2' => TileType::Medium, + '3' => TileType::Fast, + 'X' => TileType::Block, + 'W' => TileType::Whip, + 'L' => TileType::Stairs, + 'C' => TileType::Chest, + 'S' => TileType::SlowTime, + '+' => TileType::Gem, + 'I' => TileType::Invisible, + 'T' => TileType::Teleport, + 'K' => TileType::Key, + 'D' => TileType::Door, + '#' => TileType::Wall, + 'F' => TileType::SpeedTime, + '.' => TileType::Trap, + 'R' => TileType::River, + 'Q' => TileType::Power, + '/' => TileType::Forest, + '\\' => TileType::Tree, + 'B' => TileType::Bomb, + 'V' => TileType::Lava, + '=' => TileType::Pit, + 'A' => TileType::Tome, + 'U' => TileType::Tunnel, + 'Z' => TileType::Freeze, + '*' => TileType::Nugget, + 'E' => TileType::Quake, + ';' => TileType::InvisibleBlock, + ':' => TileType::InvisibleWall, + '`' => TileType::InvisibleDoor, + '-' => TileType::Stop, + '%' => TileType::Zap, + ']' => TileType::Create, + 'G' => TileType::Generator, + '@' => TileType::Trap2, + ')' => TileType::Trap3, + '(' => TileType::Trap4, + '$' => TileType::Trap5, + 'α' => TileType::Trap6, + 'ß' => TileType::Trap7, + 'Γ' => TileType::Trap8, + 'π' => TileType::Trap9, + 'Σ' => TileType::Trap10, + 'σ' => TileType::Trap11, + 'µ' => TileType::Trap12, + 'τ' => TileType::Trap13, + 'P' => TileType::Player, + '!' => TileType::Punctuation, + _ => TileType::Letter(c), + } + } +} From fe7eef77704f095377ffb35e2c331f3af6a484e8 Mon Sep 17 00:00:00 2001 From: Alex Page Date: Thu, 3 Feb 2022 20:16:33 -0500 Subject: [PATCH 8/8] Add changing levels when touching stairs --- src/input/player.rs | 2 +- src/main.rs | 3 ++- src/resources/mod.rs | 1 + src/state.rs | 22 ++++++++++++++++++++-- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/input/player.rs b/src/input/player.rs index 1d5c416..df9906b 100644 --- a/src/input/player.rs +++ b/src/input/player.rs @@ -93,7 +93,7 @@ fn try_step(point: Point, _world: &World, resources: &mut Resources) -> bool { true } crate::tile_data::TileType::Stairs => { - // TODO: Go to next level + resources.should_advance_level = true; true } crate::tile_data::TileType::Chest => todo!(), diff --git a/src/main.rs b/src/main.rs index 6a847bd..cd82959 100644 --- a/src/main.rs +++ b/src/main.rs @@ -57,7 +57,8 @@ fn main() -> BError { sound_effects, sound_output, selected_difficulty: Some(selected_difficulty), - flashing_message: None, + flashing_message: Some(FlashingMessage::from("Press any key to begin this level.")), + should_advance_level: false, }; // let descent_sounds: Vec = (20..100) diff --git a/src/resources/mod.rs b/src/resources/mod.rs index 4e79285..ab7b5cd 100644 --- a/src/resources/mod.rs +++ b/src/resources/mod.rs @@ -27,4 +27,5 @@ pub struct Resources { pub sound_effects: SoundEffects, pub sound_output: SoundOutput, pub flashing_message: Option, + pub should_advance_level: bool, } diff --git a/src/state.rs b/src/state.rs index d09162d..101e160 100644 --- a/src/state.rs +++ b/src/state.rs @@ -1,5 +1,6 @@ -use crate::resources::Resources; -use crate::{graphics, input, systems}; +use crate::resources::flashing_message::FlashingMessage; +use crate::resources::{Map, Resources}; +use crate::{graphics, input, levels, systems}; use bracket_lib::prelude::*; use hecs::World; @@ -13,6 +14,10 @@ impl GameState for State { input::handle(&mut self.world, &mut self.resources, bterm); systems::run(&mut self.world, &mut self.resources); graphics::draw(&self.world, &mut self.resources, bterm); + + if self.resources.should_advance_level { + self.next_level(); + } } } @@ -20,4 +25,17 @@ impl State { pub fn new(world: World, resources: Resources) -> Self { State { world, resources } } + + fn next_level(&mut self) { + self.resources.level_number += 1; + + self.world.clear(); + self.resources.map = Map::from(levels::get_level(self.resources.level_number)); + self.resources.map.spawn_entities(&mut self.world); + + self.resources.flashing_message = + Some(FlashingMessage::from("Press any key to begin this level.")); + + self.resources.should_advance_level = false; + } }