From 51419ff0b8da7d25ac4424291ad3e5b2e7f5ae40 Mon Sep 17 00:00:00 2001 From: Joachim Lusiardi Date: Sat, 11 Nov 2023 07:00:29 +0100 Subject: [PATCH] Wall drawing works --- .idea/el_diabolo.iml | 11 +++++++ src/level.rs | 40 +++++++++++++++++------ src/main.rs | 76 ++++++++++++++++++++++++++++++++++++++++++-- src/player.rs | 2 ++ 4 files changed, 117 insertions(+), 12 deletions(-) create mode 100644 .idea/el_diabolo.iml diff --git a/.idea/el_diabolo.iml b/.idea/el_diabolo.iml new file mode 100644 index 0000000..cf84ae4 --- /dev/null +++ b/.idea/el_diabolo.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/level.rs b/src/level.rs index 0ff215d..18d4c95 100644 --- a/src/level.rs +++ b/src/level.rs @@ -1,5 +1,8 @@ +pub const LEVEL_WIDTH: usize = 50; +pub const LEVEL_HEIGHT: usize = 25; + #[derive(Copy, Clone, Debug, PartialEq)] -enum LevelElement { +pub enum LevelElement { Wall, Floor, StairDown, @@ -8,23 +11,42 @@ enum LevelElement { #[derive(Copy, Clone, Debug, PartialEq)] pub struct Level { - structure: [[LevelElement; 25]; 80], + structure: [[LevelElement; LEVEL_HEIGHT]; LEVEL_WIDTH], } impl Level { pub fn new() -> Level { - let mut s = [[LevelElement::Wall; 25]; 80]; + let mut s = [[LevelElement::Floor; LEVEL_HEIGHT]; LEVEL_WIDTH]; + for i in 0..LEVEL_WIDTH { + s[i][0] = LevelElement::Wall; + s[i][LEVEL_HEIGHT-1] = LevelElement::Wall; + } + for i in 0..LEVEL_HEIGHT { + s[0][i] = LevelElement::Wall; + s[LEVEL_WIDTH-1][i] = LevelElement::Wall; + } + s[10][10] = LevelElement::Wall; + s[11][10] = LevelElement::Wall; + s[10][11] = LevelElement::Wall; + s[11][11] = LevelElement::Wall; + s[1][20] = LevelElement::Wall; + s[20][1] = LevelElement::Wall; + s[20][LEVEL_HEIGHT-2] = LevelElement::Wall; + s[LEVEL_WIDTH-2][20] = LevelElement::Wall; s[4][4] = LevelElement::StairDown; - s[75][20] = LevelElement::StairUp; + s[45][20] = LevelElement::StairUp; Level { structure: s } } - pub fn get_element(&self, x: usize, y: usize) -> Option { - if x >= 80 || y >= 25 { + pub fn get_element(&self, x: i16, y: i16) -> Option { + if x < 0 || y < 0 { return None; } - Some(self.structure[x][y]) + if x >= LEVEL_WIDTH as i16 || y >= LEVEL_HEIGHT as i16 { + return None; + } + Some(self.structure[x as usize][y as usize]) } } @@ -33,6 +55,6 @@ fn test_get_element() { let l = Level::new(); assert_eq!(l.get_element(0, 0).unwrap(), LevelElement::Wall); assert_eq!(l.get_element(4, 4).unwrap(), LevelElement::StairDown); - assert_eq!(l.get_element(79, 24).unwrap(), LevelElement::Wall); - assert_eq!(l.get_element(80, 25), None); + assert_eq!(l.get_element(49, 24).unwrap(), LevelElement::Wall); + assert_eq!(l.get_element(50, 25), None); } diff --git a/src/main.rs b/src/main.rs index 4d70693..d2c6a45 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,16 +1,86 @@ +use crossterm::{ + event::{self, KeyCode, KeyEventKind}, + terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, + ExecutableCommand, +}; +use ratatui::{ + prelude::{CrosstermBackend, Stylize, Terminal}, + widgets::Paragraph, +}; +use std::io::{stdout, Result}; +use ratatui::prelude::*; +use ratatui::widgets::Block; + use crate::game::Game; use crate::level::Level; +use crate::level_widget::LevelWidget; use crate::player::Player; mod game; mod player; mod level; mod position; +mod level_widget; -fn main() { +fn main() -> Result<()> { let g = Game { player: Player::new("Teddy Tester", 10), - levels: [Level::new();25] + levels: [Level::new(); 25], }; - println!("{}",g.player.get_name()); + + stdout().execute(EnterAlternateScreen)?; + enable_raw_mode()?; + let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?; + terminal.clear()?; + + loop { + terminal.draw(|frame| { + let mut area = frame.size(); + frame.render_widget(Block::default().style(Style::default().bg(Color::Green)), area); + + if area.width > 80 { + area.x = (area.width - 80) / 2; + area.width = 80; + } + if area.height > 25 { + area.y = (area.height - 25) / 2; + area.height = 25; + } + + let map_area = Rect { + x: area.x, + y: area.y, + width: level::LEVEL_WIDTH as u16, + height: level::LEVEL_HEIGHT as u16, + }; + frame.render_widget(LevelWidget { content: g.levels[0] }, map_area); + + let stats_area = Rect { + x: area.x + 50, + y: area.y, + width: 30, + height: 25, + }; + frame.render_widget( + Paragraph::new(format!("{}\nHealth: {}/{}", + g.player.get_name(), + g.player.get_life(), + g.player.get_max_life())) + .white() + .on_blue(), + stats_area, + ); + })?; + if event::poll(std::time::Duration::from_millis(16))? { + if let event::Event::Key(key) = event::read()? { + if key.kind == KeyEventKind::Press && key.code == KeyCode::Char('q') { + break; + } + } + } + } + + stdout().execute(LeaveAlternateScreen)?; + disable_raw_mode()?; + Ok(()) } diff --git a/src/player.rs b/src/player.rs index a5e6388..8f1ed8f 100644 --- a/src/player.rs +++ b/src/player.rs @@ -20,6 +20,8 @@ impl Player { pub fn get_name(&self) -> String { return self.name.clone(); } + pub fn get_life(&self) -> i16 {self.life} + pub fn get_max_life(&self) -> i16 {self.max_life} pub fn change_life(&mut self, by: i16) { self.life = max(0, min(self.max_life, self.life + by)); }