diff --git a/src/camera.rs b/src/camera.rs new file mode 100644 index 0000000..199deb5 --- /dev/null +++ b/src/camera.rs @@ -0,0 +1,25 @@ +use crate::prelude::*; + +pub struct Camera { + pub left_x: i32, + pub right_x: i32, + pub top_y: i32, + pub bottom_y: i32, +} + +impl Camera { + pub fn new(player_position: Point) -> Self { + Self { + left_x: player_position.x - DISPLAY_WIDTH / 2, + right_x: player_position.x + DISPLAY_WIDTH / 2, + top_y: player_position.y - DISPLAY_HEIGHT / 2, + bottom_y: player_position.y + DISPLAY_HEIGHT / 2, + } + } + pub fn on_player_move(&mut self, player_position: Point) { + self.left_x = player_position.x - DISPLAY_WIDTH / 2; + self.right_x = player_position.x + DISPLAY_WIDTH / 2; + self.top_y = player_position.y - DISPLAY_HEIGHT / 2; + self.bottom_y = player_position.y + DISPLAY_HEIGHT / 2; + } +} diff --git a/src/main.rs b/src/main.rs index e114c91..922d5f1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,4 @@ +mod camera; mod map; mod map_builder; mod player; @@ -6,16 +7,20 @@ mod prelude { pub use bracket_lib::prelude::*; pub const SCREEN_WIDTH: i32 = 80; pub const SCREEN_HEIGHT: i32 = 50; - pub use crate::map::*; + pub const DISPLAY_WIDTH: i32 = SCREEN_WIDTH / 2; + pub const DISPLAY_HEIGHT: i32 = SCREEN_HEIGHT / 2; + pub use crate::camera::*; + pub use crate::map::*; pub use crate::player::*; + pub use crate::map_builder::*; } -use map_builder::MapBuilder; use prelude::*; struct State { map: Map, player: Player, + camera: Camera, } impl State { @@ -25,24 +30,34 @@ impl State { Self { map: map_builder.map, player: Player::new(map_builder.player_start), + camera: Camera::new(map_builder.player_start), } } } impl GameState for State { fn tick(&mut self, ctx: &mut BTerm) { + ctx.set_active_console(0); ctx.cls(); - self.player.update(ctx, &self.map); - self.map.render(ctx); - self.player.render(ctx); + ctx.set_active_console(1); + ctx.cls(); + self.player.update(ctx, &self.map, &mut self.camera); + self.map.render(ctx, &self.camera); + self.player.render(ctx, &self.camera); } } fn main() -> BError { println!("Hello, world!"); - let context = BTermBuilder::simple80x50() + let context = BTermBuilder::new() .with_title("Dungeon Crawler") .with_fps_cap(30.0) + .with_dimensions(DISPLAY_WIDTH, DISPLAY_HEIGHT) + .with_tile_dimensions(32, 32) + .with_resource_path("resources/") + .with_font("dungeonfont.png", 32, 32) + .with_simple_console(DISPLAY_WIDTH, DISPLAY_HEIGHT, "dungeonfont.png") + .with_simple_console_no_bg(DISPLAY_WIDTH, DISPLAY_HEIGHT, "dungeonfont.png") .build()?; main_loop(context, State::new()) diff --git a/src/map.rs b/src/map.rs index a41de84..67360bd 100644 --- a/src/map.rs +++ b/src/map.rs @@ -22,15 +22,32 @@ impl Map { 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('.')); + pub fn render(&self, ctx: &mut BTerm, camera: &Camera) { + ctx.set_active_console(0); + for y in camera.top_y..camera.bottom_y { + for x in camera.left_x..camera.right_x { + if self.in_bounds(Point::new(x, y)) { + let idx = map_idx(x, y); + match self.tiles[idx] { + TileType::Floor => { + ctx.set( + x - camera.left_x, + y - camera.top_y, + WHITE, + BLACK, + to_cp437('.') + ); + } + TileType::Wall => { + ctx.set( + x - camera.left_x, + y - camera.top_y, + WHITE, + BLACK, + to_cp437('#') + ); + } } - TileType::Wall => ctx.set(x, y, YELLOW, GREEN, to_cp437('#')), } } } diff --git a/src/player.rs b/src/player.rs index 49dd219..8d4bd66 100644 --- a/src/player.rs +++ b/src/player.rs @@ -8,16 +8,17 @@ impl Player { pub fn new(position: Point) -> Self { Self { position } } - pub fn render(&self, ctx: &mut BTerm) { + pub fn render(&self, ctx: &mut BTerm, camera: &Camera) { + ctx.set_active_console(1); ctx.set( - self.position.x, - self.position.y, + self.position.x - camera.left_x, + self.position.y - camera.top_y, WHITE, BLACK, to_cp437('@'), - ) + ); } - pub fn update(&mut self, ctx: &mut BTerm, map: &Map) { + pub fn update(&mut self, ctx: &mut BTerm, map: &Map, camera: &mut Camera) { if let Some(key) = ctx.key { let delta = match key { VirtualKeyCode::W => Point::new(0, -1), @@ -30,6 +31,7 @@ impl Player { let new_position = self.position + delta; if map.can_enter_tile(new_position) { self.position = new_position; + camera.on_player_move(new_position); } } }