diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/assemblages.rs | 61 | ||||
| -rw-r--r-- | src/components.rs | 26 | ||||
| -rw-r--r-- | src/main.rs | 27 | ||||
| -rw-r--r-- | src/resources.rs | 14 | ||||
| -rw-r--r-- | src/room.rs | 172 | ||||
| -rw-r--r-- | src/systems.rs | 63 |
6 files changed, 198 insertions, 165 deletions
diff --git a/src/assemblages.rs b/src/assemblages.rs new file mode 100644 index 0000000..4705ae4 --- /dev/null +++ b/src/assemblages.rs @@ -0,0 +1,61 @@ + + +use rand::Rng; +use specs::{ + Builder, + EntityBuilder +}; + +use super::components::{Visible, Controller}; + + + + +pub trait Assemblage { + fn build<'a>(&self, builder: EntityBuilder<'a>) -> EntityBuilder<'a>; +} + + + +pub struct Wall; + +impl Assemblage for Wall { + fn build<'a>(&self, builder: EntityBuilder<'a>) -> EntityBuilder<'a>{ + builder.with(Visible{sprite: "wall".to_string(), height: 2.0}) + } +} + +pub struct Grass { + sprite: String +} + +impl Grass { + pub fn new() -> Grass { + Grass { + sprite: ["grass1", "grass2", "grass3", "grass1", "grass2", "grass3", "ground"][rand::thread_rng().gen_range(0,7)].to_string() + } + } +} + +impl Assemblage for Grass { + fn build<'a>(&self, builder: EntityBuilder<'a>) -> EntityBuilder<'a>{ + builder.with(Visible{sprite: self.sprite.to_string(), height: 0.1}) + } +} + + +pub struct Player { + name: String +} + +impl Player { + pub fn new(name: &str) -> Player { + Player { name: name.to_string()} + } +} + +impl Assemblage for Player { + fn build<'a>(&self, builder: EntityBuilder<'a>) -> EntityBuilder<'a>{ + builder.with(Visible{sprite: "player".to_string(), height: 1.0}).with(Controller(None)) + } +} diff --git a/src/components.rs b/src/components.rs new file mode 100644 index 0000000..51469cc --- /dev/null +++ b/src/components.rs @@ -0,0 +1,26 @@ + +use specs::{ + VecStorage, + Component +}; + +use super::controls::Control; + + +#[derive(Component, Debug, Hash, PartialEq, Eq, Clone, Copy)] +#[storage(VecStorage)] +pub struct Position { + pub x: i32, + pub y: i32 +} + +#[derive(Component, Debug, Clone)] +#[storage(VecStorage)] +pub struct Visible { + pub sprite: String, + pub height: f32 +} + +#[derive(Component, Debug)] +#[storage(VecStorage)] +pub struct Controller(pub Option<Control>); diff --git a/src/main.rs b/src/main.rs index c3a02e9..9b313be 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,11 +9,16 @@ pub mod gameserver; pub mod room; pub mod util; pub mod controls; +pub mod assemblages; +pub mod components; +pub mod resources; +pub mod systems; use self::gameserver::{GameServer, Action}; use self::server::unixserver::UnixServer; use self::server::tcpserver::TcpServer; use self::server::Server; +use self::assemblages::{Player, Wall, Grass}; use serde_json; @@ -34,11 +39,13 @@ fn main() { let mut room = room::Room::new((32, 32)); + gen_room(&mut room); + loop { let actions = gameserver.update(); for action in actions { match action { - Action::Join(name) => {room.add_player(&name);} + Action::Join(name) => {room.add_player(&name, &Player::new(&name));} Action::Leave(name) => {room.remove_player(&name);} Action::Input(name, control) => {room.control(name, control);} } @@ -51,6 +58,24 @@ fn main() { } } +fn gen_room(room: &mut room::Room){ + + let (width, height) = room.get_size(); + for x in 0..width { + room.add_obj(&Wall, (x, 0)); + room.add_obj(&Wall, (x, height - 1)); + } + for y in 1..height-1 { + room.add_obj(&Wall, (0, y)); + room.add_obj(&Wall, (width - 1, y)); + } + for x in 1..width-1 { + for y in 1..height-1 { + room.add_obj(&Grass::new(), (x, y)); + } + } +} + fn create_update_message((width, height): (i32, i32), field: Vec<usize>, mapping: Vec<Vec<String>>) -> String { let updatemsg= serde_json::json!([ diff --git a/src/resources.rs b/src/resources.rs new file mode 100644 index 0000000..7c14507 --- /dev/null +++ b/src/resources.rs @@ -0,0 +1,14 @@ + +use std::collections::HashMap; + +use super::components::{Position, Visible}; + +#[derive(Default)] +pub struct Size (pub i32, pub i32); + +#[derive(Default)] +pub struct TopView { + pub width: i32, + pub height: i32, + pub cells: HashMap<Position, Vec<Visible>> +} diff --git a/src/room.rs b/src/room.rs index 2d2fa48..8190d63 100644 --- a/src/room.rs +++ b/src/room.rs @@ -1,108 +1,21 @@ use std::collections::HashMap; -use rand::Rng; use specs::{ - VecStorage, - Component, - System, World, WorldExt, Builder, - Join, - ReadStorage, - WriteStorage, DispatcherBuilder, Dispatcher, - Write, - EntityBuilder, Entity }; use super::controls::Control; +use super::components::{Position, Visible, Controller}; +use super::assemblages::Assemblage; +use super::resources::{Size, TopView}; +use super::systems::{Draw, Move}; -// Components - -#[derive(Component, Debug, Hash, PartialEq, Eq, Clone, Copy)] -#[storage(VecStorage)] -struct Position { - x: i32, - y: i32 -} - -#[derive(Component, Debug, Clone)] -#[storage(VecStorage)] -struct Visible { - sprite: String, - height: f32 -} - -#[derive(Component, Debug)] -#[storage(VecStorage)] -struct Controller(Option<Control>); - - -// Resources - -#[derive(Default)] -struct Size (i32, i32); - -#[derive(Default)] -struct TopView { - width: i32, - height: i32, - cells: HashMap<Position, Vec<Visible>> -} - -// Systems - -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.clone()); - view.cells.get_mut(pos).unwrap().sort_by(|a, b| b.height.partial_cmp(&a.height).unwrap()); - } - } - } -} - -// struct Control; -// impl <'a> System <'a> for Control { -// type SystemData = WriteStorage<'a, Controller>; -// fn run (&mut self, mut controller: Self::SystemData) { -// for controller in &mut controller.join() -// } -// } - -struct Move; -impl <'a> System<'a> for Move { - type SystemData = (WriteStorage<'a, Controller>, WriteStorage<'a, Position>); - fn run(&mut self, (mut controller, mut pos): Self::SystemData) { - for (controller, pos) in (&mut controller, &mut pos).join(){ - if let Some(control) = &controller.0 { - match control { - Control::Move(direction) => { - let (dx, dy) = direction.to_position(); - pos.x += dx; - pos.y += dy; - } - _ => {} - } - controller.0 = None - } - } - } -} - - -// Higher level stuff pub struct Room<'a, 'b> { world: World, @@ -127,14 +40,12 @@ impl <'a, 'b>Room<'a, 'b> { .with(Move, "move", &["draw"]) .build(); - let mut room = Room { + Room { world, dispatcher, spawn: (width / 2, height / 2), players: HashMap::new() - }; - gen_room(&mut room); - room + } } pub fn view(&self) -> (Vec<usize>, Vec<Vec<String>>) { @@ -180,8 +91,8 @@ impl <'a, 'b>Room<'a, 'b> { template.build(self.world.create_entity()).with(Position{x, y}).build() } - pub fn add_player(&mut self, name: &str) { - let ent = self.add_obj(&Player::new(name), self.spawn); + pub fn add_player(&mut self, name: &str, template: &dyn Assemblage) { + let ent = self.add_obj(template, self.spawn); self.players.insert(name.to_string(), ent); } @@ -202,72 +113,5 @@ impl <'a, 'b>Room<'a, 'b> { } } -fn gen_room(room: &mut Room){ - - let (width, height) = room.get_size(); - for x in 0..width { - room.add_obj(&Wall, (x, 0)); - room.add_obj(&Wall, (x, height - 1)); - } - for y in 1..height-1 { - room.add_obj(&Wall, (0, y)); - room.add_obj(&Wall, (width - 1, y)); - } - for x in 1..width-1 { - for y in 1..height-1 { - room.add_obj(&Grass::new(), (x, y)); - } - } -} - - -pub trait Assemblage { - fn build<'a>(&self, builder: EntityBuilder<'a>) -> EntityBuilder<'a>; -} - - - -// Entity types - -struct Wall; -impl Assemblage for Wall { - fn build<'a>(&self, builder: EntityBuilder<'a>) -> EntityBuilder<'a>{ - builder.with(Visible{sprite: "wall".to_string(), height: 2.0}) - } -} - -struct Grass { - sprite: String -} -impl Grass { - fn new() -> Grass { - Grass { - sprite: ["grass1", "grass2", "grass3", "grass1", "grass2", "grass3", "ground"][rand::thread_rng().gen_range(0,7)].to_string() - } - } -} - -impl Assemblage for Grass { - fn build<'a>(&self, builder: EntityBuilder<'a>) -> EntityBuilder<'a>{ - builder.with(Visible{sprite: self.sprite.to_string(), height: 0.1}) - } -} - - -struct Player { - name: String -} - -impl Player { - fn new(name: &str) -> Player { - Player { name: name.to_string()} - } -} - -impl Assemblage for Player { - fn build<'a>(&self, builder: EntityBuilder<'a>) -> EntityBuilder<'a>{ - builder.with(Visible{sprite: "player".to_string(), height: 1.0}).with(Controller(None)) - } -} diff --git a/src/systems.rs b/src/systems.rs new file mode 100644 index 0000000..322ad23 --- /dev/null +++ b/src/systems.rs @@ -0,0 +1,63 @@ + +use specs::{ + ReadStorage, + WriteStorage, + Write, + System, + Join +}; + +use super::components::{ + Position, + Visible, + Controller +}; + +use super::controls::Control; + +use super::resources::TopView; + +pub 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.clone()); + view.cells.get_mut(pos).unwrap().sort_by(|a, b| b.height.partial_cmp(&a.height).unwrap()); + } + } + } +} + +// struct Control; +// impl <'a> System <'a> for Control { +// type SystemData = WriteStorage<'a, Controller>; +// fn run (&mut self, mut controller: Self::SystemData) { +// for controller in &mut controller.join() +// } +// } + +pub struct Move; +impl <'a> System<'a> for Move { + type SystemData = (WriteStorage<'a, Controller>, WriteStorage<'a, Position>); + fn run(&mut self, (mut controller, mut pos): Self::SystemData) { + for (controller, pos) in (&mut controller, &mut pos).join(){ + if let Some(control) = &controller.0 { + match control { + Control::Move(direction) => { + let (dx, dy) = direction.to_position(); + pos.x += dx; + pos.y += dy; + } + _ => {} + } + controller.0 = None + } + } + } +} |
