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
|
||||
let player = &self.player;
|
||||
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_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) {
|
||||
|
@ -25,11 +25,10 @@ impl Game {
|
|||
};
|
||||
if can_go {
|
||||
if level.get_element(new_x as i16, new_y as i16).unwrap() == LevelElement::StairDown {
|
||||
self.player.set_position(
|
||||
player_pos.get_level() + 1,
|
||||
self.levels[(player_pos.get_level() + 1) as usize].start_x as u16,
|
||||
self.levels[(player_pos.get_level() + 1) as usize].start_y as u16,
|
||||
);
|
||||
let start_x = self.levels[(player_pos.get_level() + 1) as usize].start_x;
|
||||
let start_y = self.levels[(player_pos.get_level() + 1) as usize].start_y;
|
||||
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].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 {
|
||||
self.player.set_position(
|
||||
player_pos.get_level() - 1,
|
||||
|
@ -38,6 +37,7 @@ impl Game {
|
|||
);
|
||||
} else {
|
||||
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_HEIGHT: usize = 25;
|
||||
|
||||
|
@ -7,6 +9,7 @@ pub enum LevelElement {
|
|||
Floor,
|
||||
StairDown,
|
||||
StairUp,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
|
@ -22,6 +25,7 @@ pub enum RoomType {
|
|||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub struct Level {
|
||||
pub(crate) structure: [[LevelElement; LEVEL_HEIGHT]; LEVEL_WIDTH],
|
||||
pub(crate) discovered: [[bool; LEVEL_HEIGHT]; LEVEL_WIDTH],
|
||||
pub(crate) start_x: usize,
|
||||
pub(crate) start_y: usize,
|
||||
pub(crate) end_x: usize,
|
||||
|
@ -33,10 +37,11 @@ impl Level {
|
|||
let s = [[LevelElement::Wall; LEVEL_HEIGHT]; LEVEL_WIDTH];
|
||||
Level {
|
||||
structure: s,
|
||||
discovered: [[false; LEVEL_HEIGHT]; LEVEL_WIDTH],
|
||||
start_x: 1,
|
||||
start_y: 1,
|
||||
end_x: 1,
|
||||
end_y: 1
|
||||
end_y: 1,
|
||||
}
|
||||
}
|
||||
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 {
|
||||
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 {
|
||||
structure: s,
|
||||
discovered: [[false; 1 + ROOMS_HORIZONTAL * ROOM_HEIGHT]; 1 + ROOMS_VERTICAL * ROOM_WIDTH],
|
||||
start_x,
|
||||
start_y,
|
||||
end_x,
|
||||
|
|
|
@ -101,6 +101,9 @@ impl<'a> Widget for LevelWidget<'a> {
|
|||
LevelElement::StairUp => {
|
||||
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,
|
||||
};
|
||||
|
||||
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)?;
|
||||
enable_raw_mode()?;
|
||||
|
|
Loading…
Reference in New Issue