diff options
Diffstat (limited to 'src/game.rs')
-rw-r--r-- | src/game.rs | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/src/game.rs b/src/game.rs new file mode 100644 index 0000000..0358638 --- /dev/null +++ b/src/game.rs @@ -0,0 +1,98 @@ +use std::io::{Read, Write}; + +use termion::{ + cursor::HideCursor, event::Key, input::TermRead, raw::IntoRawMode, screen::AlternateScreen, +}; + +use crate::{ + entity::{Controllable, Player}, + error::Result, + physics::Vector, + structure::Building, + Render, Velocity, +}; + +#[derive(Debug)] +pub(crate) enum Command { + Quit, + UpdatePlayer, +} + +#[derive(Debug, Default)] +pub struct Game { + pub player: Player, + pub structures: Vec<Building>, +} + +impl Game { + pub fn run_loop<R: Read, W: IntoRawMode>(&mut self, reader: R, writer: W) -> Result<()> { + let mut screen = AlternateScreen::from(HideCursor::from(writer).into_raw_mode().unwrap()); + self.write_screen(&mut screen)?; + + for key in reader.keys() { + match self.handle_input(key?) { + Some(Command::Quit) => break, + Some(Command::UpdatePlayer) => &mut self.update()?, + None => continue, + }; + self.write_screen(&mut screen)?; + } + + write!(screen, "{}", termion::cursor::Show).map_err(From::from) + } + + fn write_screen(&self, writer: &mut impl Write) -> Result<()> { + write!(writer, "{}", termion::clear::All)?; + + self.player.render(writer)?; + + for entity in &self.structures { + entity.render(writer)?; + } + + writer.flush().map_err(From::from) + } + + fn handle_input(&mut self, key: Key) -> Option<Command> { + match key { + Key::Char('q') => Some(Command::Quit), + _ => self.player.handle_input(key), + } + } + + fn update(&mut self) -> Result<()> { + self.player.tick_time()?; + self.player.set_velocity(Vector::default()) + } +} + +#[cfg(test)] +mod tests { + use std::io::stdout; + + use crate::{structure::Building, Game, Position}; + + #[test] + fn run_game() { + let stdin = "q".as_bytes(); + let stdout = stdout(); + + let mut game = Game::default(); + + if let Err(err) = game.run_loop(stdin, stdout) { + eprintln!("{}", err) + } + } + + #[test] + fn move_player() { + let stdin = "sssdddq".as_bytes(); + let stdout = stdout(); + + let mut game = Game::default(); + + if let Err(err) = game.run_loop(stdin, stdout) { + eprintln!("{}", err) + } + } +} |