summaryrefslogtreecommitdiff
path: root/src/room.rs
diff options
context:
space:
mode:
authortroido <troido@protonmail.com>2020-01-27 21:15:07 +0100
committertroido <troido@protonmail.com>2020-01-27 21:15:07 +0100
commit599d7dc27df5e5ba37ef622d520399d7ca331425 (patch)
tree14f540fb9d186d11dedbea40e731ff2e2db2cf44 /src/room.rs
parent62c810b6f8ef7c3feca62637b8361a3386fa43d8 (diff)
started using specs for a room
Diffstat (limited to 'src/room.rs')
-rw-r--r--src/room.rs199
1 files changed, 199 insertions, 0 deletions
diff --git a/src/room.rs b/src/room.rs
new file mode 100644
index 0000000..4c1b291
--- /dev/null
+++ b/src/room.rs
@@ -0,0 +1,199 @@
+
+use std::collections::HashMap;
+// use std::collections::HashSet;
+// use std::ops::Deref;
+
+use specs::{
+ VecStorage,
+ Component,
+ System,
+ World,
+ WorldExt,
+ Builder,
+ Join,
+ ReadStorage,
+ DispatcherBuilder,
+ Dispatcher,
+ Write
+};
+
+struct EntityId(usize);
+
+#[derive(Component, Debug, Hash, PartialEq, Eq, Clone, Copy)]
+#[storage(VecStorage)]
+struct Position {
+ x: i32,
+ y: i32
+}
+
+#[derive(Component, Debug)]
+#[storage(VecStorage)]
+struct Visible {
+ sprite: String,
+ height: f32
+}
+
+#[derive(Default)]
+struct Size (i32, i32);
+
+
+struct Draw;
+
+impl <'a> System<'a> for Draw {
+
+ type SystemData = (ReadStorage<'a, Position>, ReadStorage<'a, Visible>, Write<'a, TopView>);
+
+ fn run(&mut self, (pos, vis, mut view): Self::SystemData) {
+ view.cells.clear();
+ for (pos, vis) in (&pos, &vis).join(){
+ if pos.x >= 0 && pos.y >= 0 && pos.x < view.width && pos.y < view.height {
+ view.cells.entry(*pos).or_insert(Vec::new()).push(vis.sprite.clone());
+ }
+ }
+ }
+}
+
+#[derive(Default)]
+struct TopView {
+ width: i32,
+ height: i32,
+ cells: HashMap<Position, Vec<String>>
+}
+
+
+pub struct Room<'a, 'b> {
+ world: World,
+ dispatcher: Dispatcher<'a, 'b>
+}
+
+impl <'a, 'b>Room<'a, 'b> {
+
+ pub fn new(size: (i32, i32)) -> Room<'a, 'b> {
+ let (width, height) = size;
+ let mut world = World::new();
+ world.register::<Position>();
+ world.register::<Visible>();
+ world.insert(Size(width, height));
+ world.insert(TopView{width: width, height: height, cells: HashMap::new()});
+
+ let dispatcher = DispatcherBuilder::new()
+ .with(Draw, "draw", &[])
+ .build();
+
+ gen_world(&mut world);
+
+ Room {
+ world,
+ dispatcher
+ }
+ }
+
+ pub fn view(&self) -> (Vec<usize>, Vec<Vec<String>>) {
+ let tv = &*self.world.fetch::<TopView>();
+ let width = tv.width;
+ let height = tv.height;
+// let TopView{width: width, height: height, cells: cells} = ;
+ let size = width * height;
+ let mut values :Vec<usize> = Vec::with_capacity(size as usize);
+ let mut mapping: Vec<Vec<String>> = Vec::with_capacity(size as usize);
+ for y in 0..height {
+ for x in 0..width {
+// values.push(mapping.len());
+ let sprites = match tv.cells.get(&Position{x: x, y: y}) {
+ Some(sprites) => {sprites.to_vec()}
+ None => {vec![]}
+ };
+ values.push(
+ match mapping.iter().position(|x| x == &sprites) {
+ Some(index) => {
+ index
+ }
+ None => {
+ mapping.push(sprites);
+ mapping.len() - 1
+ }
+ }
+ )
+ }
+ }
+ (values, mapping)
+ }
+
+ pub fn update(&mut self) {
+ self.dispatcher.dispatch(&mut self.world);
+ self.world.maintain();
+ }
+
+ pub fn get_size(&self) -> (i32, i32) {
+ let Size(width, height) = *self.world.fetch::<Size>();
+ (width, height)
+ }
+}
+
+fn gen_world(world: &mut World){
+
+ let Size(width, height) = *world.fetch::<Size>();
+ for x in 0..width {
+ world.create_entity().with(Position{x: x, y: 0}).with(Visible{sprite: "wall".to_string(), height: 1.0}).build();
+ world.create_entity().with(Position{x: x, y: height - 1}).with(Visible{sprite: "wall".to_string(), height: 1.0}).build();
+ }
+ for y in 1..height-1 {
+ world.create_entity().with(Position{x: 0, y: y}).with(Visible{sprite: "wall".to_string(), height: 1.0}).build();
+ world.create_entity().with(Position{x: width - 1, y: y}).with(Visible{sprite: "wall".to_string(), height: 1.0}).build();
+ }
+}
+
+// pub fn make_room<'a, 'b>(size: (i32, i32)) -> (World, Dispatcher<'a, 'b>){
+// let (width, height) = size;
+// let mut world = World::new();
+// world.register::<Position>();
+// world.register::<Visible>();
+// world.insert(Size(width, height));
+// world.insert(TopView{width: width, height: height, cells: HashMap::new()});
+//
+//
+//
+// let mut dispatcher = DispatcherBuilder::new()
+// .with(Draw, "draw", &[])
+// .build();
+//
+//
+// gen_world(&mut world);
+//
+// (world, dispatcher)
+// }
+
+// pub fn view_room(world :&World) -> (Vec<usize>, Vec<Vec<String>>) {
+// let TopView{width: width, height: height, cells: cells} = *world.fetch::<TopView>();
+// let size = width * height;
+// let mut values :Vec<usize> = Vec::with_capacity(size as usize);
+// let mut mapping = Vec::with_capacity(size as usize);
+// for y in 0..height {
+// for x in 0..width {
+// values.push(mapping.len());
+// mapping.push(match cells.get(Position{x: x, y: y}) {
+// Some(sprites) => {sprites}
+// None => {vec![]}
+// });
+// }
+// }
+// return (values, mapping)
+//
+// }
+
+// struct Room {
+// entities: Entities,
+// width: u32,
+// height: u32,
+// ground: HashMap<(u32, u32), GroundTile>
+// }
+//
+// struct Entities {
+// components: HashMap<EntityId, Box<Component>>,
+// systems: HashMap<EntityId, Box<System>>
+// }
+//
+//
+// struct GroundTile {
+// entities: HashSet<EntityId>
+// }