From 9ad3d9de0b8eaf7e76682d0b87b37af5cc5696c4 Mon Sep 17 00:00:00 2001 From: Alex Page Date: Wed, 26 Jan 2022 16:06:27 -0500 Subject: [PATCH] Add breakable walls and monster collision with them --- src/components/player.rs | 5 ---- src/components/position.rs | 7 ++++++ src/main.rs | 14 ++++++----- src/map.rs | 29 +++++++++++++++++++---- src/resources/mod.rs | 8 +++++++ src/sidebar.rs | 17 ++++++-------- src/systems/monster_motion.rs | 44 ++++++++++++++++++++++++++++------- 7 files changed, 91 insertions(+), 33 deletions(-) diff --git a/src/components/player.rs b/src/components/player.rs index 0b3c6d8..3f2c48d 100644 --- a/src/components/player.rs +++ b/src/components/player.rs @@ -6,9 +6,4 @@ use specs_derive::Component; #[derive(Component, Debug)] pub struct Player { pub last_moved: Instant, - pub score: u32, - pub gems: u32, - pub whips: u32, - pub teleports: u32, - pub keys: u32, } diff --git a/src/components/position.rs b/src/components/position.rs index a641718..7263675 100644 --- a/src/components/position.rs +++ b/src/components/position.rs @@ -1,3 +1,4 @@ +use bracket_lib::prelude::*; use specs::prelude::*; use specs_derive::Component; @@ -6,3 +7,9 @@ pub struct Position { pub x: i32, pub y: i32, } + +impl PartialEq for Position { + fn eq(&self, other: &Point) -> bool { + return self.x == other.x && self.y == other.y; + } +} diff --git a/src/main.rs b/src/main.rs index 04668f8..2ce6038 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,7 +17,7 @@ use components::{ }; use constants::*; use map::{Map, TileType}; -use resources::{Clock, LevelNumber, ShowDebugInfo}; +use resources::{Clock, LevelNumber, ShowDebugInfo, Stats}; use sound::SoundSystem; use sound_effects::SoundEffects; use specs::prelude::*; @@ -178,6 +178,13 @@ fn main() -> BError { ticks: 0, }); gs.ecs.insert(sound_effects); + gs.ecs.insert(Stats { + score: 1290, + gems: 14, + whips: 7, + teleports: 0, + keys: 0, + }); gs.ecs.register::(); gs.ecs.register::(); @@ -225,11 +232,6 @@ fn main() -> BError { }) .with(Player { last_moved: Instant::now(), - score: 1290, - gems: 14, - whips: 7, - teleports: 0, - keys: 0, }) .build(); diff --git a/src/map.rs b/src/map.rs index f571a25..75b2fe2 100644 --- a/src/map.rs +++ b/src/map.rs @@ -7,6 +7,7 @@ use bracket_lib::{prelude::*, random::RandomNumberGenerator}; #[derive(PartialEq, Copy, Clone)] pub enum TileType { Wall, + BreakableWall, Floor, } @@ -35,8 +36,10 @@ impl Map { let mut tiles = vec![TileType::Floor; MAP_SIZE]; let mut rng = RandomNumberGenerator::new(); for tile in &mut tiles { - if rng.roll_dice(1, 4) < 2 { + if rng.roll_dice(1, 16) < 2 { *tile = TileType::Wall; + } else if rng.roll_dice(1, 16) < 2 { + *tile = TileType::BreakableWall; } } Self { @@ -78,7 +81,7 @@ impl Map { to_cp437(' '), ); } - TileType::Wall => { + TileType::BreakableWall => { ctx.set( x + MAP_X, y + MAP_Y, @@ -87,15 +90,33 @@ impl Map { to_cp437('▓'), ); } + TileType::Wall => { + ctx.set( + x + MAP_X, + y + MAP_Y, + RGB::named(vga::YELLOW), + RGB::named(vga::BLACK), + to_cp437('█'), + ); + } } } } - pub fn tile_at(&self, point: Point) -> TileType { + pub fn get_tile_at(&self, point: Point) -> TileType { self.tiles[self.point2d_to_index(point)] } + pub fn set_tile_at(&mut self, point: Point, tile: TileType) { + let index = self.point2d_to_index(point); + self.tiles[index] = tile; + } + pub fn is_solid(&self, point: Point) -> bool { - self.tile_at(point) == TileType::Wall + match self.get_tile_at(point) { + TileType::Wall => true, + TileType::BreakableWall => true, + _ => false, + } } } diff --git a/src/resources/mod.rs b/src/resources/mod.rs index e69b810..59ff897 100644 --- a/src/resources/mod.rs +++ b/src/resources/mod.rs @@ -32,3 +32,11 @@ impl Clock { self.ticks += 1; } } + +pub struct Stats { + pub score: u32, + pub gems: u32, + pub whips: u32, + pub teleports: u32, + pub keys: u32, +} diff --git a/src/sidebar.rs b/src/sidebar.rs index 895f541..08f66b2 100644 --- a/src/sidebar.rs +++ b/src/sidebar.rs @@ -1,7 +1,6 @@ use crate::constants::{SIDEBAR_POS_X, SIDEBAR_POS_Y}; -use crate::resources::{Clock, ShowDebugInfo}; +use crate::resources::{Clock, LevelNumber, ShowDebugInfo, Stats}; use crate::vga_color as vga; -use crate::{LevelNumber, Player}; use bracket_lib::prelude::*; use specs::prelude::*; @@ -47,14 +46,12 @@ pub fn draw(ecs: &World, ctx: &mut BTerm) { ctx.print(SIDEBAR_POS_X + 2, SIDEBAR_POS_Y + 12, "Teleports"); ctx.print(SIDEBAR_POS_X + 4, SIDEBAR_POS_Y + 15, "Keys"); - let players = ecs.read_storage::(); - for player in players.join() { - ctx.print_centered_at(SIDEBAR_POS_X + 6, SIDEBAR_POS_Y + 1, player.score); - ctx.print_centered_at(SIDEBAR_POS_X + 6, SIDEBAR_POS_Y + 7, player.gems); - ctx.print_centered_at(SIDEBAR_POS_X + 6, SIDEBAR_POS_Y + 10, player.whips); - ctx.print_centered_at(SIDEBAR_POS_X + 6, SIDEBAR_POS_Y + 13, player.teleports); - ctx.print_centered_at(SIDEBAR_POS_X + 6, SIDEBAR_POS_Y + 16, player.keys); - } + let stats = ecs.read_resource::(); + ctx.print_centered_at(SIDEBAR_POS_X + 6, SIDEBAR_POS_Y + 1, stats.score); + ctx.print_centered_at(SIDEBAR_POS_X + 6, SIDEBAR_POS_Y + 7, stats.gems); + ctx.print_centered_at(SIDEBAR_POS_X + 6, SIDEBAR_POS_Y + 10, stats.whips); + ctx.print_centered_at(SIDEBAR_POS_X + 6, SIDEBAR_POS_Y + 13, stats.teleports); + ctx.print_centered_at(SIDEBAR_POS_X + 6, SIDEBAR_POS_Y + 16, stats.keys); // Hotkey list ctx.print_color( diff --git a/src/systems/monster_motion.rs b/src/systems/monster_motion.rs index 899ac1b..6164b02 100644 --- a/src/systems/monster_motion.rs +++ b/src/systems/monster_motion.rs @@ -3,8 +3,8 @@ use crate::{ monster::{self, ticks_for_kind}, Monster, Position, Renderable, }, - map::Map, - resources::Clock, + map::{Map, TileType}, + resources::{Clock, Stats}, }; use bracket_lib::{prelude::*, random::RandomNumberGenerator}; use specs::prelude::*; @@ -14,9 +14,11 @@ pub struct MonsterMotion {} #[allow(clippy::type_complexity)] impl<'a> System<'a> for MonsterMotion { type SystemData = ( + Entities<'a>, ReadExpect<'a, Clock>, ReadExpect<'a, Point>, - ReadExpect<'a, Map>, + WriteExpect<'a, Map>, + WriteExpect<'a, Stats>, WriteStorage<'a, Monster>, WriteStorage<'a, Position>, WriteStorage<'a, Renderable>, @@ -24,9 +26,19 @@ impl<'a> System<'a> for MonsterMotion { fn run( &mut self, - (clock, player_pos, map, mut monster, mut position, mut renderable): Self::SystemData, + ( + entities, + clock, + player_pos, + mut map, + mut stats, + mut monster, + mut position, + mut renderable, + ): Self::SystemData, ) { - for (monster, position, renderable) in (&mut monster, &mut position, &mut renderable).join() + for (entity, monster, position, renderable) in + (&entities, &mut monster, &mut position, &mut renderable).join() { if clock.has_ticked { monster.ticks_until_move -= 1; @@ -57,10 +69,26 @@ impl<'a> System<'a> for MonsterMotion { x: position.x + delta_x, y: position.y + delta_y, }; - if !map.is_solid(destination) { - position.x = destination.x; - position.y = destination.y; + + if destination == *player_pos { + // TODO: Sound + stats.gems -= 1; + let _ = entities.delete(entity); } + + match map.get_tile_at(destination) { + TileType::Wall => {} + TileType::BreakableWall => { + // TODO: Sound + map.set_tile_at(destination, TileType::Floor); + let _ = entities.delete(entity); + } + TileType::Floor => { + position.x = destination.x; + position.y = destination.y; + } + } + monster.ticks_until_move = ticks_for_kind(monster.kind); } }