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 specs::prelude::*;
|
||||
|
||||
mod component;
|
||||
mod entity;
|
||||
mod map;
|
||||
mod player;
|
||||
mod rect;
|
||||
mod state;
|
||||
mod visibility;
|
||||
|
||||
use crate::component::Viewshed;
|
||||
use crate::entity::{Player, Position, Renderable};
|
||||
use crate::map::Map;
|
||||
use crate::state::State;
|
||||
use crate::visibility::VisibilitySystem;
|
||||
|
||||
fn main() {
|
||||
let context =
|
||||
Rltk::init_simple8x8(80, 50, "MORTAL WOMBAT", "resources");
|
||||
let mut gs = State {
|
||||
ecs: World::new(),
|
||||
systems: DispatcherBuilder::new().build(),
|
||||
systems: DispatcherBuilder::new()
|
||||
.with(VisibilitySystem {}, "visibility_system", &[])
|
||||
.build(),
|
||||
};
|
||||
gs.ecs.register::<Position>();
|
||||
gs.ecs.register::<Renderable>();
|
||||
gs.ecs.register::<Player>();
|
||||
gs.ecs.register::<Viewshed>();
|
||||
|
||||
let map = Map::new_room_corridors();
|
||||
gs.ecs.insert(map.clone());
|
||||
|
@ -39,6 +46,10 @@ fn main() {
|
|||
bg: RGB::named(rltk::BLACK),
|
||||
})
|
||||
.with(Player {})
|
||||
.with(Viewshed {
|
||||
visible_tiles: vec![],
|
||||
range: 8,
|
||||
})
|
||||
.build();
|
||||
|
||||
rltk::main_loop(context, gs);
|
||||
|
|
106
src/map.rs
106
src/map.rs
|
@ -1,8 +1,13 @@
|
|||
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;
|
||||
|
||||
#[derive(Clone)]
|
||||
|
@ -13,6 +18,32 @@ pub struct Map {
|
|||
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 {
|
||||
pub fn xy_idx(&self, x: i32, y: i32) -> 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) {
|
||||
let mut y = 0;
|
||||
let mut x = 0;
|
||||
map.iter().for_each(|tile| {
|
||||
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('#'),
|
||||
);
|
||||
}
|
||||
}
|
||||
pub fn draw(ecs: &World, ctx: &mut Rltk) {
|
||||
let mut viewsheds = ecs.write_storage::<Viewshed>();
|
||||
let mut players = ecs.write_storage::<Player>();
|
||||
let map = ecs.fetch::<Map>();
|
||||
|
||||
x += 1;
|
||||
if x > 79 {
|
||||
x = 0;
|
||||
y += 1;
|
||||
}
|
||||
});
|
||||
(&mut players, &mut viewsheds).join().into_iter().for_each(
|
||||
|(_player, viewshed)| {
|
||||
let mut y = 0;
|
||||
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 specs::prelude::*;
|
||||
|
||||
use crate::entity::{Position, Renderable, TileType};
|
||||
use crate::entity::{Position, Renderable};
|
||||
use crate::map;
|
||||
use crate::player;
|
||||
|
||||
|
@ -17,8 +17,7 @@ impl GameState for State {
|
|||
player::input(self, ctx);
|
||||
self.systems.dispatch(&self.ecs);
|
||||
|
||||
let map = self.ecs.fetch::<Vec<TileType>>();
|
||||
map::draw(&map, ctx);
|
||||
map::draw(&self.ecs, ctx);
|
||||
|
||||
let positions = self.ecs.read_storage::<Position>();
|
||||
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