Skip to content

Commit

Permalink
fov!
Browse files Browse the repository at this point in the history
  • Loading branch information
jossse69 committed Sep 2, 2023
1 parent 17c20e9 commit 8136927
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 24 deletions.
42 changes: 35 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ bracket-lib = "0.8.7"
serde = { version = "1.0.188", features = ["derive"] }
serde_json = "1.0.105"
crossbeam-utils = "0.8.7"
rand = "0.8.5"
rand = "0.8.5"
bracket-geometry = "0.7"
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ impl GameState for State {
}

self.player.update(ctx, &mut self.map, &mut self.ui);
self.map.update_fov(self.player.entity.x, self.player.entity.y);
ctx.cls();
self.ui.add_message("Hello world!");

Expand Down
129 changes: 114 additions & 15 deletions src/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,116 @@ pub struct Map {
pub tiles: Vec<TileType>,
pub width: i32,
pub height: i32,
pub rooms: Vec<Rect>, // Add a vector to store rooms
pub rooms: Vec<Rect>,
pub revealed_tiles: Vec<bool>, // Track revealed tiles
pub visible_tiles: Vec<bool>, // Track visible tiles
}

impl Algorithm2D for Map {
fn dimensions(&self) -> Point {
Point::new(self.width, self.height)
}

fn in_bounds(&self, pos: Point) -> bool {
pos.x >= 0 && pos.x < self.width && pos.y >= 0 && pos.y < self.height
}

fn point2d_to_index(&self, pt: Point) -> usize {
let bounds = self.dimensions();
((pt.y * bounds.x) + pt.x)
.try_into()
.expect("Not a valid usize. Did something go negative?")
}

fn index_to_point2d(&self, idx: usize) -> Point {
let bounds = self.dimensions();
let w: usize = bounds
.x
.try_into()
.expect("Not a valid usize. Did something go negative?");
Point::new(idx % w, idx / w)
}
}

impl BaseMap for Map {
fn is_opaque(&self, idx: usize) -> bool {
self.tiles[idx] == TileType::Wall
}

fn get_available_exits(&self, idx: usize) -> SmallVec<[(usize, f32); 10]> {
let mut exits = SmallVec::new();
let pos = self.index_to_point2d(idx);
let directions = [
(-1, 0),
(1, 0),
(0, -1),
(0, 1),
(-1, -1),
(-1, 1),
(1, -1),
(1, 1),
];

for &dir in directions.iter() {
let new_pos = (pos.x + dir.0, pos.y + dir.1);
if self.in_bounds(Point::new(new_pos.0, new_pos.1)) {
let new_idx = self.point2d_to_index(Point::new(new_pos.0, new_pos.1));
if !self.is_opaque(new_idx) {
exits.push((new_idx, 1.0));
}
}
}
exits
}

fn get_pathing_distance(&self, idx1: usize, idx2: usize) -> f32 {
let pos1 = self.index_to_point2d(idx1);
let pos2 = self.index_to_point2d(idx2);
DistanceAlg::Pythagoras.distance2d(pos1, pos2)
}
}

impl Map {
pub fn new(width: i32, height: i32) -> Self {
let tiles = vec![TileType::Wall; (width * height) as usize];
let revealed_tiles = vec![false; (width * height) as usize];
let visible_tiles = vec![false; (width * height) as usize];

Map {
tiles,
width,
height,
rooms: Vec::new(), // Initialize the rooms vector
rooms: Vec::new(),
revealed_tiles,
visible_tiles,
}
}

pub fn render(&self, ctx: &mut BTerm) {
for y in 0..self.height {
for x in 0..self.width {
let idx = map_idx(x, y);
match self.tiles[idx] {
TileType::Floor => {
ctx.set(x, y, DARKGREY, BLACK, to_cp437('.'));
}
TileType::Wall => {
ctx.set(x, y, LIGHTSLATEGRAY, BLACK, to_cp437('#'));
}
TileType::UpStairs => {
ctx.set(x, y, ORANGE, BLACK, to_cp437('^'));
}
TileType::DownStairs => {
ctx.set(x, y, ORANGE, BLACK, to_cp437('v'));
}
let glyph = match self.tiles[idx] {
TileType::Floor => to_cp437('.'),
TileType::Wall => to_cp437('#'),
TileType::UpStairs => to_cp437('^'),
TileType::DownStairs => to_cp437('v'),
};
let color = match self.tiles[idx] {
TileType::Floor => DARKGREY,
TileType::Wall => LIGHTSLATEGRAY,
TileType::UpStairs => ORANGE,
TileType::DownStairs => ORANGE,
};
// if it's been revealed render it with color
if self.visible_tiles[idx] {
ctx.set(x, y, color, BLACK, glyph );
}
else if self.revealed_tiles[idx] {
ctx.set(x, y, DARKBLUE, BLACK, glyph);
}
else {
continue;
}
}
}
Expand All @@ -45,6 +124,26 @@ impl Map {
pub fn get_tile(&self, x: i32, y: i32) -> TileType {
self.tiles[map_idx(x, y)]
}

pub fn update_fov(&mut self, player_x: i32, player_y: i32) {
let player_idx = map_idx(player_x, player_y);
let player_pos = Point::new(player_x, player_y);
let fov = field_of_view_set(player_pos, 10, self);

for idx in 0..self.tiles.len() {
let tile_pos = self.index_to_point2d(idx); // Convert idx to a Point object
let tile_visible = fov.contains(&tile_pos); // Check if tile_pos is contained in the field of view

if tile_visible {
self.visible_tiles[idx] = true;
self.revealed_tiles[idx] = true;
} else {
self.visible_tiles[idx] = false;
}
}
}


}

pub fn map_idx(x: i32, y: i32) -> usize {
Expand Down
4 changes: 3 additions & 1 deletion src/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::map::{Map, self, TileType};
use crate::ui::{UI, PopupWindow};

pub struct Player {
entity: Entity,
pub entity: Entity,
pub hp: i32,
pub max_hp: i32,
pub score: i32,
Expand Down Expand Up @@ -55,6 +55,8 @@ impl Player {
_ => {}
}
}

// update fov
}

fn move_by(&mut self, dx: i32, dy: i32, map: &Map) {
Expand Down

0 comments on commit 8136927

Please sign in to comment.