diff options
author | Guillaume Pasquet <dev@etenil.net> | 2020-03-11 07:35:23 +0000 |
---|---|---|
committer | Guillaume Pasquet <dev@etenil.net> | 2020-03-11 07:35:23 +0000 |
commit | 0d545ea6e634ed990dd8f731a24a4e0838ffedbf (patch) | |
tree | 4444ce15a0cb55020a8d1de4e9088de172ca9e8e | |
parent | 0191b3a881027bcb6d6210e010841664dae4204b (diff) |
stuff
-rw-r--r-- | TODO.md | 21 | ||||
-rw-r--r-- | src/state.rs | 90 |
2 files changed, 22 insertions, 89 deletions
@@ -1,4 +1,23 @@ +# TODO
+
- Add unit tests
- Disassociate level to view, move view around if terminal too small
- Add equipment system
-- Remove rendering logic from State
\ No newline at end of file +- Remove rendering logic from State
+
+
+## Separate rendering logic
+
+```
+------- ---------
+| main| -----> | State |
+------- | ---------
+ |
+ | ------------
+ +-> | ViewPort |
+ ------------
+```
+
+- Main game logic mutates State in reaction to player input
+- Render is triggered by giving it a read-only reference to current state
+- Heavy use of traits in ViewPort allows multiple type of viewports (Piston etc.)
diff --git a/src/state.rs b/src/state.rs index 8561486..542f822 100644 --- a/src/state.rs +++ b/src/state.rs @@ -1,9 +1,5 @@ -use crossterm::cursor::MoveTo; -use crossterm::{execute, queue, Output}; -use std::io::{stdout, Write}; - -use crate::entities::{Character, Entity, Player}; -use crate::tiling::{tile_to_str, Tile, TileGrid, TileType}; +use crate::entities::{Character, Entity}; +use crate::tiling::{Tile, TileGrid, TileType}; use crate::world::{apply_movement, Dungeon, Generatable, Level, Movement}; const PLAYER_SIGHT: usize = 3; @@ -36,86 +32,6 @@ impl State { self.grid = Some(self.current_level().to_tilegrid().unwrap()); } - pub fn render_level(&self) { - let mut sout = stdout(); - execute!(sout, MoveTo(0, 0)).unwrap(); - for (linenum, line) in self.grid.as_ref().unwrap().raw_data().iter().enumerate() { - let linestr = line.iter().map(tile_to_str).collect::<Vec<&str>>(); - let mut linestr2 = String::from(""); - for chr in linestr { - linestr2.push_str(chr); - } - queue!(sout, Output(linestr2), MoveTo(0, linenum as u16)).unwrap(); - sout.flush().unwrap(); - } - } - - fn render_entity(&self, entity: &dyn Entity) { - if !entity.is_visible() || !entity.is_dirty() { - return; - } - let dirt = entity.previous_location(); - let background = self.grid.as_ref().unwrap().block_at(dirt.0, dirt.1); - let mut sout = stdout(); - queue!( - sout, - MoveTo(dirt.0 as u16, dirt.1 as u16), - Output(tile_to_str(background)), - MoveTo(entity.location().0 as u16, entity.location().1 as u16), - Output(tile_to_str(entity.tile())) - ) - .unwrap(); - sout.flush().unwrap(); - } - - pub fn render_entities(&self) { - for e in self.current_level().entities.iter() { - self.render_entity(&**e); - } - } - - pub fn render_player(&mut self) { - self.render_entity(&self.player); - - self.grid - .as_mut() - .unwrap() - .clear_fog_of_war(self.player.location(), PLAYER_SIGHT); - } - - fn ui_state_position(&self) -> MoveTo { - MoveTo(0, (self.dungeon.ysize()) as u16) - } - - fn ui_notification_position(&self) -> MoveTo { - MoveTo(0, (self.dungeon.ysize() + 1) as u16) - } - - pub fn render_ui(&self) { - let mut sout = stdout(); - queue!(sout, self.ui_state_position(), Output(self.player.stats())).unwrap(); - sout.flush().unwrap(); - } - - pub fn notify(&self, message: String) { - let mut sout = stdout(); - queue!( - sout, - self.ui_notification_position(), - Output(" ".repeat(self.dungeon.xsize())), - self.ui_notification_position(), - Output(message) - ) - .unwrap(); - sout.flush().unwrap(); - } - - pub fn ui_help(&self) { - self.notify(String::from( - "quit: q, movement{up(k), down(j), left(h), right(l)}", - )) - } - pub fn current_level(&self) -> &Level { &self.dungeon.levels[self.level] } @@ -157,7 +73,6 @@ impl State { match grid.block_at(loc.0, loc.1).get_type() { TileType::StairsDown => { self.switch_level(self.level + 1); - self.render_level(); Ok(()) } _ => Err(String::from("Not on stairs!")), @@ -178,7 +93,6 @@ impl State { match grid.block_at(loc.0, loc.1).get_type() { TileType::StairsUp => { self.switch_level(self.level - 1); - self.render_level(); Ok(()) } _ => Err(String::from("Not on stairs!")), |