From 6e7ab861c983c13428c23d94ab49b90ddeec9320 Mon Sep 17 00:00:00 2001 From: unintendedfraud Date: Sat, 27 Jan 2024 22:47:22 +0100 Subject: [PATCH] blabla --- .../Cargo.toml | 2 +- rusty-roguelike/readme.md | 36 +++++++++++++ .../src/main.rs | 18 +++---- .../src/map.rs | 54 ++++++++++--------- .../src/player.rs | 39 +++++++------- 5 files changed, 95 insertions(+), 54 deletions(-) rename {dungeoncrawler => rusty-roguelike}/Cargo.toml (87%) create mode 100644 rusty-roguelike/readme.md rename {dungeoncrawler => rusty-roguelike}/src/main.rs (67%) rename {dungeoncrawler => rusty-roguelike}/src/map.rs (54%) rename {dungeoncrawler => rusty-roguelike}/src/player.rs (64%) diff --git a/dungeoncrawler/Cargo.toml b/rusty-roguelike/Cargo.toml similarity index 87% rename from dungeoncrawler/Cargo.toml rename to rusty-roguelike/Cargo.toml index 9a64c58..ff5e8f9 100644 --- a/dungeoncrawler/Cargo.toml +++ b/rusty-roguelike/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "dungeoncrawler" +name = "rusty-roguelike" version = "0.1.0" edition = "2021" diff --git a/rusty-roguelike/readme.md b/rusty-roguelike/readme.md new file mode 100644 index 0000000..d1a8b6b --- /dev/null +++ b/rusty-roguelike/readme.md @@ -0,0 +1,36 @@ +# Rusty Roguelike +Roguelike following the book "Hands-on Rust". + +## Short description +A dungeon crawler with procedurally generated levels, monsters of increasing difficulty and turn-based movement. + +## Story +The hero's hometown is suffering from a plague of monsters. Welling up from the deep, they seem unstoppable. Legend +tells of the Amulet of Yala that can be used to stem the tide. After a long night at the tavern, the hero promises to +save the day - and set forth into the dungeon. + +## Basic game loops +1. Enter dungeon level +2. Explore, revealing the map +3. Encounter ennemies from whom the players decide to fight or flee from +4. Find power-ups and use them to strenghten the player +5. Locate the exit to the level, back to 1 + +## MVP +1. Create a basic dungeon map +2. Place the player and let them walk around +3. Spawn monsters, draw them, and let the player kill them by walking into them +4. Add health and a combat system that uses it +5. Add healing potions +6. Display a "Game Over" screen when the player dies +7. Add the Amulet of Yala to the level and let the player wins by reaching it + +## Stretch goals +1. Add field of view +2. Add more interesting dungeon designs +3. Add some dungeon themes +4. Add multiple layers to the dungeon, with the amulet on the last one +5. Add varied weapons to the game +6. Move to a data driven design for spawning ennemies +7. Consider some visuals effects to make combats more visceral +8. Consider keeping scores diff --git a/dungeoncrawler/src/main.rs b/rusty-roguelike/src/main.rs similarity index 67% rename from dungeoncrawler/src/main.rs rename to rusty-roguelike/src/main.rs index ab9c4df..7e0c3af 100644 --- a/dungeoncrawler/src/main.rs +++ b/rusty-roguelike/src/main.rs @@ -3,10 +3,11 @@ 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::*; + + pub const SCREEN_WIDTH: i32 = 80; + pub const SCREEN_HEIGHT: i32 = 50; } use prelude::*; @@ -18,10 +19,10 @@ struct State { impl State { fn new() -> Self { - Self { + return Self { map: Map::new(), - player: Player::new(Point { x: 0, y: 0 }), - } + player: Player::new(Point { x: SCREEN_WIDTH / 2, y: SCREEN_HEIGHT / 2 }), + }; } } @@ -35,10 +36,7 @@ impl GameState for State { } fn main() -> BError { - let ctx = BTermBuilder::simple80x50() - .with_title("Dungeon Crawler") - .with_fps_cap(30.0) - .build()?; + let context = BTermBuilder::simple80x50().with_title("Dungeon Crawler").with_fps_cap(30.0).build()?; - main_loop(ctx, State::new()) + return main_loop(context, State::new()); } diff --git a/dungeoncrawler/src/map.rs b/rusty-roguelike/src/map.rs similarity index 54% rename from dungeoncrawler/src/map.rs rename to rusty-roguelike/src/map.rs index 76d933e..aaeaac4 100644 --- a/dungeoncrawler/src/map.rs +++ b/rusty-roguelike/src/map.rs @@ -1,53 +1,57 @@ -use crate::prelude::*; +pub use crate::prelude::*; const NUM_TILES: usize = (SCREEN_WIDTH * SCREEN_HEIGHT) as usize; #[derive(Copy, Clone, PartialEq)] pub enum TileType { - Wall, Floor, + Wall, } pub struct Map { pub tiles: Vec, } +pub fn map_idx(x: i32, y: i32) -> usize { + return ((y * SCREEN_WIDTH) + x) as usize; +} + impl Map { pub fn new() -> Self { - Self { + return Self { tiles: vec![TileType::Floor; NUM_TILES], } } + pub fn in_bounds(&self, point: Point) -> bool { + return point.x >= 0 && point.x < SCREEN_WIDTH && point.y >= 0 && point.y < SCREEN_HEIGHT; + } + + pub fn can_enter_tile(&self, point: Point) -> bool { + return 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) { + return Some(map_idx(point.x, point.y)); + } else { + return None; + } + } + 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('#')), + 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/rusty-roguelike/src/player.rs similarity index 64% rename from dungeoncrawler/src/player.rs rename to rusty-roguelike/src/player.rs index 4107708..1b93c8d 100644 --- a/dungeoncrawler/src/player.rs +++ b/rusty-roguelike/src/player.rs @@ -1,39 +1,42 @@ use crate::prelude::*; pub struct Player { - position: Point, + pub hp: i32, + pub 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 new(point: Point) -> Self { + return Self { + hp: 100, + position: point, + }; } 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::Right => Point::new(1, 0), 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; + let new_pos = self.position + delta; + if map.can_enter_tile(new_pos) { + self.position = new_pos; } } } + + pub fn render(&self, ctx: &mut BTerm) { + return ctx.set( + self.position.x, + self.position.y, + WHITE, + BLACK, + to_cp437('@') + ); + } }