Add breakable walls and monster collision with them
This commit is contained in:
parent
c2db40dd6b
commit
9ad3d9de0b
7 changed files with 91 additions and 33 deletions
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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<Point> for Position {
|
||||
fn eq(&self, other: &Point) -> bool {
|
||||
return self.x == other.x && self.y == other.y;
|
||||
}
|
||||
}
|
||||
|
|
14
src/main.rs
14
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::<Position>();
|
||||
gs.ecs.register::<Renderable>();
|
||||
|
@ -225,11 +232,6 @@ fn main() -> BError {
|
|||
})
|
||||
.with(Player {
|
||||
last_moved: Instant::now(),
|
||||
score: 1290,
|
||||
gems: 14,
|
||||
whips: 7,
|
||||
teleports: 0,
|
||||
keys: 0,
|
||||
})
|
||||
.build();
|
||||
|
||||
|
|
29
src/map.rs
29
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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::<Player>();
|
||||
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::<Stats>();
|
||||
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(
|
||||
|
|
|
@ -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) {
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue