From 227c0021fe37dbb9e1a60a26a5ea2a3bc24eb570 Mon Sep 17 00:00:00 2001 From: unintendedfraud Date: Sat, 7 Oct 2023 12:53:21 +0200 Subject: [PATCH] dungeoncrawler --- dungeoncrawler/Cargo.toml | 9 ++++++ dungeoncrawler/src/main.rs | 44 ++++++++++++++++++++++++++++++ dungeoncrawler/src/map.rs | 53 ++++++++++++++++++++++++++++++++++++ dungeoncrawler/src/player.rs | 39 ++++++++++++++++++++++++++ 4 files changed, 145 insertions(+) create mode 100644 dungeoncrawler/Cargo.toml create mode 100644 dungeoncrawler/src/main.rs create mode 100644 dungeoncrawler/src/map.rs create mode 100644 dungeoncrawler/src/player.rs diff --git a/dungeoncrawler/Cargo.toml b/dungeoncrawler/Cargo.toml new file mode 100644 index 0000000..9a64c58 --- /dev/null +++ b/dungeoncrawler/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "dungeoncrawler" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +bracket-lib = "~0.8.1" diff --git a/dungeoncrawler/src/main.rs b/dungeoncrawler/src/main.rs new file mode 100644 index 0000000..ab9c4df --- /dev/null +++ b/dungeoncrawler/src/main.rs @@ -0,0 +1,44 @@ +mod map; +mod player; + +mod prelude { + pub use bracket_lib::prelude::*; + pub const SCREEN_WIDTH: i32 = 80; + pub const SCREEN_HEIGHT: i32 = 50; + pub use crate::map::*; + pub use crate::player::*; +} + +use prelude::*; + +struct State { + map: Map, + player: Player, +} + +impl State { + fn new() -> Self { + Self { + map: Map::new(), + player: Player::new(Point { x: 0, y: 0 }), + } + } +} + +impl GameState for State { + fn tick(&mut self, ctx: &mut BTerm) { + ctx.cls(); + self.player.update(ctx, &self.map); + self.map.render(ctx); + self.player.render(ctx); + } +} + +fn main() -> BError { + let ctx = BTermBuilder::simple80x50() + .with_title("Dungeon Crawler") + .with_fps_cap(30.0) + .build()?; + + main_loop(ctx, State::new()) +} diff --git a/dungeoncrawler/src/map.rs b/dungeoncrawler/src/map.rs new file mode 100644 index 0000000..76d933e --- /dev/null +++ b/dungeoncrawler/src/map.rs @@ -0,0 +1,53 @@ +use crate::prelude::*; + +const NUM_TILES: usize = (SCREEN_WIDTH * SCREEN_HEIGHT) as usize; + +#[derive(Copy, Clone, PartialEq)] +pub enum TileType { + Wall, + Floor, +} + +pub struct Map { + pub tiles: Vec, +} + +impl Map { + pub fn new() -> Self { + Self { + tiles: vec![TileType::Floor; NUM_TILES], + } + } + + pub fn render(&self, ctx: &mut BTerm) { + for y in 0..SCREEN_HEIGHT { + for x in 0..SCREEN_WIDTH { + let idx = map_idx(x, y); + match self.tiles[idx] { + TileType::Floor => ctx.set(x, y, YELLOW, BLACK, to_cp437('.')), + TileType::Wall => ctx.set(x, y, GREEN, BLACK, to_cp437('#')), + } + } + } + } + + pub fn in_bounds(&self, point: Point) -> bool { + point.x >= 0 && point.x < SCREEN_WIDTH && point.y >= 0 && point.y < SCREEN_HEIGHT + } + + pub fn can_enter_tile(&self, point: Point) -> bool { + self.in_bounds(point) && self.tiles[map_idx(point.x, point.y)] == TileType::Floor + } + + pub fn try_idx(&self, point: Point) -> Option { + if !self.in_bounds(point) { + None + } else { + Some(map_idx(point.x, point.y)) + } + } +} + +pub fn map_idx(x: i32, y: i32) -> usize { + ((y * SCREEN_WIDTH) + x) as usize +} diff --git a/dungeoncrawler/src/player.rs b/dungeoncrawler/src/player.rs new file mode 100644 index 0000000..4107708 --- /dev/null +++ b/dungeoncrawler/src/player.rs @@ -0,0 +1,39 @@ +use crate::prelude::*; + +pub struct Player { + position: Point, +} + +impl Player { + pub fn new(position: Point) -> Self { + Player { position } + } + + pub fn render(&self, ctx: &mut BTerm) { + ctx.set( + self.position.x, + self.position.y, + WHITE, + BLACK, + to_cp437('@'), + ) + } + + pub fn update(&mut self, ctx: &mut BTerm, map: &Map) { + if let Some(key) = ctx.key { + let delta = match key { + VirtualKeyCode::Up => Point::new(0, -1), + VirtualKeyCode::Down => Point::new(0, 1), + VirtualKeyCode::Left => Point::new(-1, 0), + VirtualKeyCode::Right => Point::new(1, 0), + _ => Point::zero(), + }; + + let new_position = self.position + delta; + + if map.can_enter_tile(new_position) { + self.position = new_position; + } + } + } +}