Implement fog of dungeon
This commit is contained in:
parent
d44c0fd53e
commit
1cfe16c4ef
12
src/game.rs
12
src/game.rs
|
@ -11,7 +11,7 @@ impl Game {
|
||||||
// check if move is allowed first
|
// check if move is allowed first
|
||||||
let player = &self.player;
|
let player = &self.player;
|
||||||
let player_pos = player.get_position();
|
let player_pos = player.get_position();
|
||||||
let level = &self.levels[player_pos.get_level() as usize];
|
let mut level = &self.levels[player_pos.get_level() as usize];
|
||||||
let new_x = ((player_pos.get_x() as i16) + dx as i16) as u16;
|
let new_x = ((player_pos.get_x() as i16) + dx as i16) as u16;
|
||||||
let new_y = ((player_pos.get_y() as i16) + dy as i16) as u16;
|
let new_y = ((player_pos.get_y() as i16) + dy as i16) as u16;
|
||||||
let can_go: bool = match level.get_element(new_x as i16, new_y as i16) {
|
let can_go: bool = match level.get_element(new_x as i16, new_y as i16) {
|
||||||
|
@ -25,11 +25,10 @@ impl Game {
|
||||||
};
|
};
|
||||||
if can_go {
|
if can_go {
|
||||||
if level.get_element(new_x as i16, new_y as i16).unwrap() == LevelElement::StairDown {
|
if level.get_element(new_x as i16, new_y as i16).unwrap() == LevelElement::StairDown {
|
||||||
self.player.set_position(
|
let start_x = self.levels[(player_pos.get_level() + 1) as usize].start_x;
|
||||||
player_pos.get_level() + 1,
|
let start_y = self.levels[(player_pos.get_level() + 1) as usize].start_y;
|
||||||
self.levels[(player_pos.get_level() + 1) as usize].start_x as u16,
|
self.player.set_position(player_pos.get_level() + 1, start_x as u16, start_y as u16);
|
||||||
self.levels[(player_pos.get_level() + 1) as usize].start_y as u16,
|
self.levels[(player_pos.get_level() + 1) as usize].discover(start_x as i16, start_y as i16);
|
||||||
);
|
|
||||||
} else if level.get_element(new_x as i16, new_y as i16).unwrap() == LevelElement::StairUp {
|
} else if level.get_element(new_x as i16, new_y as i16).unwrap() == LevelElement::StairUp {
|
||||||
self.player.set_position(
|
self.player.set_position(
|
||||||
player_pos.get_level() - 1,
|
player_pos.get_level() - 1,
|
||||||
|
@ -38,6 +37,7 @@ impl Game {
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
self.player.change_position(dx, dy);
|
self.player.change_position(dx, dy);
|
||||||
|
self.levels[player_pos.get_level() as usize].discover(new_x as i16, new_y as i16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
50
src/level.rs
50
src/level.rs
|
@ -1,3 +1,5 @@
|
||||||
|
use std::cmp::{max, min};
|
||||||
|
|
||||||
pub const LEVEL_WIDTH: usize = 50;
|
pub const LEVEL_WIDTH: usize = 50;
|
||||||
pub const LEVEL_HEIGHT: usize = 25;
|
pub const LEVEL_HEIGHT: usize = 25;
|
||||||
|
|
||||||
|
@ -7,6 +9,7 @@ pub enum LevelElement {
|
||||||
Floor,
|
Floor,
|
||||||
StairDown,
|
StairDown,
|
||||||
StairUp,
|
StairUp,
|
||||||
|
Unknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
|
@ -22,6 +25,7 @@ pub enum RoomType {
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
pub struct Level {
|
pub struct Level {
|
||||||
pub(crate) structure: [[LevelElement; LEVEL_HEIGHT]; LEVEL_WIDTH],
|
pub(crate) structure: [[LevelElement; LEVEL_HEIGHT]; LEVEL_WIDTH],
|
||||||
|
pub(crate) discovered: [[bool; LEVEL_HEIGHT]; LEVEL_WIDTH],
|
||||||
pub(crate) start_x: usize,
|
pub(crate) start_x: usize,
|
||||||
pub(crate) start_y: usize,
|
pub(crate) start_y: usize,
|
||||||
pub(crate) end_x: usize,
|
pub(crate) end_x: usize,
|
||||||
|
@ -33,10 +37,11 @@ impl Level {
|
||||||
let s = [[LevelElement::Wall; LEVEL_HEIGHT]; LEVEL_WIDTH];
|
let s = [[LevelElement::Wall; LEVEL_HEIGHT]; LEVEL_WIDTH];
|
||||||
Level {
|
Level {
|
||||||
structure: s,
|
structure: s,
|
||||||
|
discovered: [[false; LEVEL_HEIGHT]; LEVEL_WIDTH],
|
||||||
start_x: 1,
|
start_x: 1,
|
||||||
start_y: 1,
|
start_y: 1,
|
||||||
end_x: 1,
|
end_x: 1,
|
||||||
end_y: 1
|
end_y: 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn get_element(&self, x: i16, y: i16) -> Option<LevelElement> {
|
pub fn get_element(&self, x: i16, y: i16) -> Option<LevelElement> {
|
||||||
|
@ -46,7 +51,48 @@ impl Level {
|
||||||
if x >= LEVEL_WIDTH as i16 || y >= LEVEL_HEIGHT as i16 {
|
if x >= LEVEL_WIDTH as i16 || y >= LEVEL_HEIGHT as i16 {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
Some(self.structure[x as usize][y as usize])
|
if self.discovered[x as usize][y as usize] {
|
||||||
|
return Some(self.structure[x as usize][y as usize]);
|
||||||
|
}
|
||||||
|
return Some(LevelElement::Unknown);
|
||||||
|
}
|
||||||
|
/// discover the area with in the level around the given position
|
||||||
|
pub fn discover(&mut self, x: i16, y: i16) {
|
||||||
|
for x_r in x - 1..=x + 1 {
|
||||||
|
for y_r in y - 1..=y + 1 {
|
||||||
|
let tx = min(max(x_r, 0), (LEVEL_WIDTH - 1) as i16) as usize;
|
||||||
|
let ty = min(max(y_r, 0), (LEVEL_HEIGHT - 1) as i16) as usize;
|
||||||
|
self.discovered[tx][ty] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for x_r in x..=x + 2 {
|
||||||
|
let tx = min(max(x_r, 0), (LEVEL_WIDTH - 1) as i16) as usize;
|
||||||
|
self.discovered[tx][y as usize] = true;
|
||||||
|
if self.structure[tx][y as usize] == LevelElement::Wall {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for y_r in y..=y + 2 {
|
||||||
|
let ty = min(max(y_r, 0), (LEVEL_HEIGHT - 1) as i16) as usize;
|
||||||
|
self.discovered[x as usize][ty] = true;
|
||||||
|
if self.structure[x as usize][ty] == LevelElement::Wall {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for x_r in (x-2..x).rev() {
|
||||||
|
let tx = min(max(x_r, 0), (LEVEL_WIDTH - 1) as i16) as usize;
|
||||||
|
self.discovered[tx][y as usize] = true;
|
||||||
|
if self.structure[tx][y as usize] == LevelElement::Wall {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for y_r in (y-2..y).rev() {
|
||||||
|
let ty = min(max(y_r, 0), (LEVEL_HEIGHT - 1) as i16) as usize;
|
||||||
|
self.discovered[x as usize][ty] = true;
|
||||||
|
if self.structure[x as usize][ty] == LevelElement::Wall {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -284,6 +284,7 @@ impl LevelGenerator {
|
||||||
}
|
}
|
||||||
Level {
|
Level {
|
||||||
structure: s,
|
structure: s,
|
||||||
|
discovered: [[false; 1 + ROOMS_HORIZONTAL * ROOM_HEIGHT]; 1 + ROOMS_VERTICAL * ROOM_WIDTH],
|
||||||
start_x,
|
start_x,
|
||||||
start_y,
|
start_y,
|
||||||
end_x,
|
end_x,
|
||||||
|
|
|
@ -101,6 +101,9 @@ impl<'a> Widget for LevelWidget<'a> {
|
||||||
LevelElement::StairUp => {
|
LevelElement::StairUp => {
|
||||||
self.set_cell(buf, x, y, "<", Color::Black, Color::Gray);
|
self.set_cell(buf, x, y, "<", Color::Black, Color::Gray);
|
||||||
}
|
}
|
||||||
|
LevelElement::Unknown => {
|
||||||
|
self.set_cell(buf, x, y, "▒", Color::DarkGray, Color::Gray);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ fn main() -> Result<()> {
|
||||||
levels,
|
levels,
|
||||||
};
|
};
|
||||||
|
|
||||||
g.player.change_position((levels[0].start_x) as i8, (levels[0].start_y) as i8);
|
g.move_player((levels[0].start_x) as i8, (levels[0].start_y) as i8);
|
||||||
|
|
||||||
stdout().execute(EnterAlternateScreen)?;
|
stdout().execute(EnterAlternateScreen)?;
|
||||||
enable_raw_mode()?;
|
enable_raw_mode()?;
|
||||||
|
|
Loading…
Reference in New Issue