visible area limited
This commit is contained in:
parent
1e7fb1e98b
commit
af9db4789b
|
@ -0,0 +1,8 @@
|
||||||
|
use rltk;
|
||||||
|
use specs::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct Viewshed {
|
||||||
|
pub visible_tiles: Vec<rltk::Point>,
|
||||||
|
pub range: i32,
|
||||||
|
}
|
13
src/main.rs
13
src/main.rs
|
@ -4,26 +4,33 @@ extern crate specs_derive;
|
||||||
use rltk::{Rltk, RGB};
|
use rltk::{Rltk, RGB};
|
||||||
use specs::prelude::*;
|
use specs::prelude::*;
|
||||||
|
|
||||||
|
mod component;
|
||||||
mod entity;
|
mod entity;
|
||||||
mod map;
|
mod map;
|
||||||
mod player;
|
mod player;
|
||||||
mod rect;
|
mod rect;
|
||||||
mod state;
|
mod state;
|
||||||
|
mod visibility;
|
||||||
|
|
||||||
|
use crate::component::Viewshed;
|
||||||
use crate::entity::{Player, Position, Renderable};
|
use crate::entity::{Player, Position, Renderable};
|
||||||
use crate::map::Map;
|
use crate::map::Map;
|
||||||
use crate::state::State;
|
use crate::state::State;
|
||||||
|
use crate::visibility::VisibilitySystem;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let context =
|
let context =
|
||||||
Rltk::init_simple8x8(80, 50, "MORTAL WOMBAT", "resources");
|
Rltk::init_simple8x8(80, 50, "MORTAL WOMBAT", "resources");
|
||||||
let mut gs = State {
|
let mut gs = State {
|
||||||
ecs: World::new(),
|
ecs: World::new(),
|
||||||
systems: DispatcherBuilder::new().build(),
|
systems: DispatcherBuilder::new()
|
||||||
|
.with(VisibilitySystem {}, "visibility_system", &[])
|
||||||
|
.build(),
|
||||||
};
|
};
|
||||||
gs.ecs.register::<Position>();
|
gs.ecs.register::<Position>();
|
||||||
gs.ecs.register::<Renderable>();
|
gs.ecs.register::<Renderable>();
|
||||||
gs.ecs.register::<Player>();
|
gs.ecs.register::<Player>();
|
||||||
|
gs.ecs.register::<Viewshed>();
|
||||||
|
|
||||||
let map = Map::new_room_corridors();
|
let map = Map::new_room_corridors();
|
||||||
gs.ecs.insert(map.clone());
|
gs.ecs.insert(map.clone());
|
||||||
|
@ -39,6 +46,10 @@ fn main() {
|
||||||
bg: RGB::named(rltk::BLACK),
|
bg: RGB::named(rltk::BLACK),
|
||||||
})
|
})
|
||||||
.with(Player {})
|
.with(Player {})
|
||||||
|
.with(Viewshed {
|
||||||
|
visible_tiles: vec![],
|
||||||
|
range: 8,
|
||||||
|
})
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
rltk::main_loop(context, gs);
|
rltk::main_loop(context, gs);
|
||||||
|
|
106
src/map.rs
106
src/map.rs
|
@ -1,8 +1,13 @@
|
||||||
use std::cmp::{max, min};
|
use std::cmp::{max, min};
|
||||||
|
|
||||||
use rltk::{Console, RandomNumberGenerator, Rltk, RGB};
|
use rltk::{
|
||||||
|
Algorithm2D, BaseMap, Console, Point, RandomNumberGenerator, Rltk,
|
||||||
|
RGB,
|
||||||
|
};
|
||||||
|
use specs::prelude::*;
|
||||||
|
|
||||||
use crate::entity::TileType;
|
use crate::component::Viewshed;
|
||||||
|
use crate::entity::{Player, TileType};
|
||||||
use crate::rect::Rect;
|
use crate::rect::Rect;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -13,6 +18,32 @@ pub struct Map {
|
||||||
pub height: i32,
|
pub height: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Algorithm2D for Map {
|
||||||
|
fn point2d_to_index(&self, pt: Point) -> i32 {
|
||||||
|
(pt.y * self.width) + pt.x
|
||||||
|
}
|
||||||
|
fn index_to_point2d(&self, idx: i32) -> Point {
|
||||||
|
Point {
|
||||||
|
x: idx % self.width,
|
||||||
|
y: idx / self.width,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BaseMap for Map {
|
||||||
|
fn is_opaque(&self, idx: i32) -> bool {
|
||||||
|
self.tiles[idx as usize] == TileType::Wall
|
||||||
|
}
|
||||||
|
fn get_available_exits(&self, _idx: i32) -> Vec<(i32, f32)> {
|
||||||
|
Vec::new()
|
||||||
|
}
|
||||||
|
fn get_pathing_distance(&self, idx1: i32, idx2: i32) -> f32 {
|
||||||
|
let p1 = Point::new(idx1 % self.width, idx1 / self.width);
|
||||||
|
let p2 = Point::new(idx2 % self.width, idx2 / self.width);
|
||||||
|
rltk::DistanceAlg::Pythagoras.distance2d(p1, p2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Map {
|
impl Map {
|
||||||
pub fn xy_idx(&self, x: i32, y: i32) -> usize {
|
pub fn xy_idx(&self, x: i32, y: i32) -> usize {
|
||||||
(y as usize * 80) + x as usize
|
(y as usize * 80) + x as usize
|
||||||
|
@ -131,35 +162,46 @@ pub fn new_test() -> Vec<TileType> {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pub fn draw(map: &[TileType], ctx: &mut Rltk) {
|
pub fn draw(ecs: &World, ctx: &mut Rltk) {
|
||||||
let mut y = 0;
|
let mut viewsheds = ecs.write_storage::<Viewshed>();
|
||||||
let mut x = 0;
|
let mut players = ecs.write_storage::<Player>();
|
||||||
map.iter().for_each(|tile| {
|
let map = ecs.fetch::<Map>();
|
||||||
match tile {
|
|
||||||
TileType::Floor => {
|
|
||||||
ctx.set(
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
RGB::from_f32(0.5, 0.5, 0.5),
|
|
||||||
RGB::from_f32(0., 0., 0.),
|
|
||||||
rltk::to_cp437('.'),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
TileType::Wall => {
|
|
||||||
ctx.set(
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
RGB::from_f32(0.0, 1.0, 0.0),
|
|
||||||
RGB::from_f32(0., 0., 0.),
|
|
||||||
rltk::to_cp437('#'),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
x += 1;
|
(&mut players, &mut viewsheds).join().into_iter().for_each(
|
||||||
if x > 79 {
|
|(_player, viewshed)| {
|
||||||
x = 0;
|
let mut y = 0;
|
||||||
y += 1;
|
let mut x = 0;
|
||||||
}
|
map.tiles.iter().for_each(|tile| {
|
||||||
});
|
let pt = Point::new(x, y);
|
||||||
|
if viewshed.visible_tiles.contains(&pt) {
|
||||||
|
match tile {
|
||||||
|
TileType::Floor => {
|
||||||
|
ctx.set(
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
RGB::from_f32(0.5, 0.5, 0.5),
|
||||||
|
RGB::from_f32(0., 0., 0.),
|
||||||
|
rltk::to_cp437('.'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
TileType::Wall => {
|
||||||
|
ctx.set(
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
RGB::from_f32(0.0, 1.0, 0.0),
|
||||||
|
RGB::from_f32(0., 0., 0.),
|
||||||
|
rltk::to_cp437('#'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
x += 1;
|
||||||
|
if x > 79 {
|
||||||
|
x = 0;
|
||||||
|
y += 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use rltk::{Console, GameState, Rltk};
|
use rltk::{Console, GameState, Rltk};
|
||||||
use specs::prelude::*;
|
use specs::prelude::*;
|
||||||
|
|
||||||
use crate::entity::{Position, Renderable, TileType};
|
use crate::entity::{Position, Renderable};
|
||||||
use crate::map;
|
use crate::map;
|
||||||
use crate::player;
|
use crate::player;
|
||||||
|
|
||||||
|
@ -17,8 +17,7 @@ impl GameState for State {
|
||||||
player::input(self, ctx);
|
player::input(self, ctx);
|
||||||
self.systems.dispatch(&self.ecs);
|
self.systems.dispatch(&self.ecs);
|
||||||
|
|
||||||
let map = self.ecs.fetch::<Vec<TileType>>();
|
map::draw(&self.ecs, ctx);
|
||||||
map::draw(&map, ctx);
|
|
||||||
|
|
||||||
let positions = self.ecs.read_storage::<Position>();
|
let positions = self.ecs.read_storage::<Position>();
|
||||||
let renderables = self.ecs.read_storage::<Renderable>();
|
let renderables = self.ecs.read_storage::<Renderable>();
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
use super::{Map, Position, Viewshed};
|
||||||
|
use rltk::{field_of_view, Point};
|
||||||
|
use specs::prelude::*;
|
||||||
|
|
||||||
|
pub struct VisibilitySystem {}
|
||||||
|
|
||||||
|
impl<'a> System<'a> for VisibilitySystem {
|
||||||
|
type SystemData = (
|
||||||
|
ReadExpect<'a, Map>,
|
||||||
|
WriteStorage<'a, Viewshed>,
|
||||||
|
WriteStorage<'a, Position>,
|
||||||
|
);
|
||||||
|
|
||||||
|
fn run(&mut self, data: Self::SystemData) {
|
||||||
|
let (map, mut viewshed, pos) = data;
|
||||||
|
(&mut viewshed, &pos).join().into_iter().for_each(
|
||||||
|
|(viewshed, pos)| {
|
||||||
|
viewshed.visible_tiles.clear();
|
||||||
|
viewshed.visible_tiles = field_of_view(
|
||||||
|
Point::new(pos.x, pos.y),
|
||||||
|
viewshed.range,
|
||||||
|
&*map,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue