From 5a6fe33e1e5a5ae3edfa8bb638c8042f9260e7d2 Mon Sep 17 00:00:00 2001 From: crumblingstatue Date: Mon, 3 Apr 2023 15:37:14 +0200 Subject: [PATCH] Add player entity --- .gitignore | 1 + ideas.md | 8 +++- src/app.rs | 109 +++++++++++++++++++++++++++++++++------------ src/debug.rs | 20 +++++++++ src/game.rs | 18 +++++++- src/game/player.rs | 24 ++++++++++ src/main.rs | 1 + 7 files changed, 150 insertions(+), 31 deletions(-) create mode 100644 src/debug.rs create mode 100644 src/game/player.rs diff --git a/.gitignore b/.gitignore index ea8c4bf..de358ff 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +.vscode/ diff --git a/ideas.md b/ideas.md index 9e046c3..3482e01 100644 --- a/ideas.md +++ b/ideas.md @@ -1,4 +1,10 @@ Various random ideas that aren't (yet) part of the design - Character is 1.5 blocks tall -- Can crawl to fit inside 1 block tall gaps \ No newline at end of file +- Can crawl to fit inside 1 block tall gaps + + +- Multiple tile layers. + - Back layer + - Wall layer + - Ore/misc insert layer \ No newline at end of file diff --git a/src/app.rs b/src/app.rs index d19a5ac..dc91dc9 100644 --- a/src/app.rs +++ b/src/app.rs @@ -8,8 +8,9 @@ use sfml::{ }; use crate::{ + debug::DebugState, game::GameState, - graphics, + graphics::{self, NATIVE_RESOLUTION}, input::KbInput, math::{wp_to_tp, WorldPos}, res::Res, @@ -23,6 +24,7 @@ pub struct App { pub res: Res, pub sf_egui: SfEgui, pub kb_input: KbInput, + pub debug: DebugState, } impl App { @@ -36,6 +38,7 @@ impl App { res: Res::load()?, sf_egui, kb_input: KbInput::default(), + debug: DebugState::default(), }) } @@ -61,6 +64,36 @@ impl App { } fn do_update(&mut self) { + self.debug.update(&self.kb_input); + if self.debug.freecam { + self.do_freecam(); + } else { + let spd = if self.kb_input.down(Key::LShift) { + 16.0 + } else if self.kb_input.down(Key::LControl) { + 256.0 + } else { + 4.0 + }; + if self.kb_input.down(Key::Left) { + self.game.player.col_en.move_x(-spd, |_, _| false); + } + if self.kb_input.down(Key::Right) { + self.game.player.col_en.move_x(spd, |_, _| false); + } + if self.kb_input.down(Key::Up) { + self.game.player.col_en.move_y(-spd, |_, _| false); + } + if self.kb_input.down(Key::Down) { + self.game.player.col_en.move_y(spd, |_, _| false); + } + let (x, y, _w, _h) = self.game.player.col_en.en.xywh(); + self.game.camera_offset.x = (x - NATIVE_RESOLUTION.w as i32 / 2) as u32; + self.game.camera_offset.y = (y - NATIVE_RESOLUTION.h as i32 / 2) as u32; + } + } + + fn do_freecam(&mut self) { let spd = if self.kb_input.down(Key::LShift) { 100 } else if self.kb_input.down(Key::LControl) { @@ -80,41 +113,17 @@ impl App { if self.kb_input.down(Key::Down) { self.game.camera_offset.y = self.game.camera_offset.y.saturating_add(spd); } - let tp = self.game.camera_offset.tile_pos(); - imm_dbg!(tp); - imm_dbg!(tp.to_chunk_and_local()); } fn do_rendering(&mut self) { self.rw.clear(Color::rgb(55, 221, 231)); self.game.draw_world(&mut self.rw, &self.res); + self.game.draw_entities(&mut self.rw); self.sf_egui .do_frame(|ctx| { - egui::Window::new("Debug").show(ctx, |ui| { - ui.label("Cam x"); - ui.add(egui::DragValue::new(&mut self.game.camera_offset.x)); - ui.label("Cam y"); - ui.add(egui::DragValue::new(&mut self.game.camera_offset.y)); - let tile_off = self.game.camera_offset.tile_pos(); - ui.label(format!( - "Depth: {}", - LengthDisp(tile_off.y as i64 - wp_to_tp(WorldPos::SURFACE) as i64) - )); - ui.label(format!( - "Offset from center: {}", - LengthDisp(tile_off.x as i64 - wp_to_tp(WorldPos::CENTER) as i64) - )); - ui.separator(); - egui::ScrollArea::vertical().show(ui, |ui| { - gamedebug_core::for_each_imm(|info| match info { - gamedebug_core::Info::Msg(msg) => { - ui.label(msg); - } - gamedebug_core::Info::Rect(_, _, _, _, _) => todo!(), - }); - }); - gamedebug_core::clear_immediates(); - }); + if self.debug.panel { + debug_panel_ui(&mut self.debug, &mut self.game, ctx); + } }) .unwrap(); self.sf_egui.draw(&mut self.rw, None); @@ -122,6 +131,48 @@ impl App { } } +fn debug_panel_ui(debug: &mut DebugState, game: &mut GameState, ctx: &egui::Context) { + egui::Window::new("Debug (F12)").show(ctx, |ui| { + ui.label("Cam x"); + ui.add(egui::DragValue::new(&mut game.camera_offset.x)); + ui.label("Cam y"); + ui.add(egui::DragValue::new(&mut game.camera_offset.y)); + if debug.freecam { + let tp = game.camera_offset.tile_pos(); + imm_dbg!(tp); + ui.label(format!( + "Cam Depth: {}", + LengthDisp(tp.y as i64 - wp_to_tp(WorldPos::SURFACE) as i64) + )); + ui.label(format!( + "Cam offset from center: {}", + LengthDisp(tp.x as i64 - wp_to_tp(WorldPos::CENTER) as i64) + )); + } else { + let tp = game.player.center_tp(); + imm_dbg!(tp); + ui.label(format!( + "Player Depth: {}", + LengthDisp(tp.y as i64 - wp_to_tp(WorldPos::SURFACE) as i64) + )); + ui.label(format!( + "Player offset from center: {}", + LengthDisp(tp.x as i64 - wp_to_tp(WorldPos::CENTER) as i64) + )); + } + ui.separator(); + egui::ScrollArea::vertical().show(ui, |ui| { + gamedebug_core::for_each_imm(|info| match info { + gamedebug_core::Info::Msg(msg) => { + ui.label(msg); + } + gamedebug_core::Info::Rect(_, _, _, _, _) => todo!(), + }); + }); + gamedebug_core::clear_immediates(); + }); +} + struct LengthDisp(i64); impl fmt::Display for LengthDisp { diff --git a/src/debug.rs b/src/debug.rs new file mode 100644 index 0000000..ebe9446 --- /dev/null +++ b/src/debug.rs @@ -0,0 +1,20 @@ +use sfml::window::Key; + +use crate::input::KbInput; + +#[derive(Default)] +pub struct DebugState { + pub panel: bool, + pub freecam: bool, +} + +impl DebugState { + pub fn update(&mut self, input: &KbInput) { + if input.pressed(Key::F12) { + self.panel ^= true; + } + if input.pressed(Key::F10) { + self.freecam ^= true; + } + } +} diff --git a/src/game.rs b/src/game.rs index 70595b1..e3772d8 100644 --- a/src/game.rs +++ b/src/game.rs @@ -1,4 +1,6 @@ -use sfml::graphics::{Rect, RenderTarget, RenderWindow, Sprite, Transformable}; +mod player; + +use sfml::graphics::{Rect, RectangleShape, RenderTarget, RenderWindow, Sprite, Transformable}; use crate::{ graphics::{ScreenPos, ScreenPosScalar, NATIVE_RESOLUTION}, @@ -7,9 +9,12 @@ use crate::{ world::{Tile, TilePos, World}, }; +use self::player::Player; + pub struct GameState { pub camera_offset: WorldPos, pub world: World, + pub player: Player, } impl GameState { pub(crate) fn draw_world(&mut self, rw: &mut RenderWindow, res: &Res) { @@ -24,6 +29,16 @@ impl GameState { rw.draw(&s); }); } + pub fn draw_entities(&mut self, rw: &mut RenderWindow) { + let (x, y, w, h) = self.player.col_en.en.xywh(); + let mut rs = RectangleShape::new(); + rs.set_position(( + (x - self.camera_offset.x as i32) as f32, + (y - self.camera_offset.y as i32) as f32, + )); + rs.set_size((w as f32, h as f32)); + rw.draw(&rs); + } } fn for_each_tile_on_screen(camera_offset: WorldPos, mut f: impl FnMut(TilePos, ScreenPos)) { @@ -48,6 +63,7 @@ impl Default for GameState { Self { camera_offset: WorldPos::SURFACE_CENTER, world: Default::default(), + player: Player::new_at(WorldPos::SURFACE_CENTER), } } } diff --git a/src/game/player.rs b/src/game/player.rs new file mode 100644 index 0000000..eef7e92 --- /dev/null +++ b/src/game/player.rs @@ -0,0 +1,24 @@ +use s2dc::{vec2, MobileEntity}; + +use crate::{ + math::{WorldPos, TILE_SIZE}, + world::{TilePos, TilePosScalar}, +}; + +pub struct Player { + pub col_en: MobileEntity, +} + +impl Player { + pub fn new_at(pos: WorldPos) -> Self { + Self { + col_en: MobileEntity::from_pos_and_bb(vec2(pos.x as i32, pos.y as i32), vec2(15, 24)), + } + } + pub fn center_tp(&self) -> TilePos { + TilePos { + x: (self.col_en.en.pos.x / TILE_SIZE as i32) as TilePosScalar, + y: (self.col_en.en.pos.y / TILE_SIZE as i32) as TilePosScalar, + } + } +} diff --git a/src/main.rs b/src/main.rs index 4c41222..e005061 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ mod app; +mod debug; mod game; mod graphics; mod input;