Add player entity

This commit is contained in:
crumblingstatue 2023-04-03 15:37:14 +02:00
parent 6ca737f36c
commit 5a6fe33e1e
7 changed files with 150 additions and 31 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
/target /target
.vscode/

View file

@ -2,3 +2,9 @@ Various random ideas that aren't (yet) part of the design
- Character is 1.5 blocks tall - Character is 1.5 blocks tall
- Can crawl to fit inside 1 block tall gaps - Can crawl to fit inside 1 block tall gaps
- Multiple tile layers.
- Back layer
- Wall layer
- Ore/misc insert layer

View file

@ -8,8 +8,9 @@ use sfml::{
}; };
use crate::{ use crate::{
debug::DebugState,
game::GameState, game::GameState,
graphics, graphics::{self, NATIVE_RESOLUTION},
input::KbInput, input::KbInput,
math::{wp_to_tp, WorldPos}, math::{wp_to_tp, WorldPos},
res::Res, res::Res,
@ -23,6 +24,7 @@ pub struct App {
pub res: Res, pub res: Res,
pub sf_egui: SfEgui, pub sf_egui: SfEgui,
pub kb_input: KbInput, pub kb_input: KbInput,
pub debug: DebugState,
} }
impl App { impl App {
@ -36,6 +38,7 @@ impl App {
res: Res::load()?, res: Res::load()?,
sf_egui, sf_egui,
kb_input: KbInput::default(), kb_input: KbInput::default(),
debug: DebugState::default(),
}) })
} }
@ -61,6 +64,36 @@ impl App {
} }
fn do_update(&mut self) { 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) { let spd = if self.kb_input.down(Key::LShift) {
100 100
} else if self.kb_input.down(Key::LControl) { } else if self.kb_input.down(Key::LControl) {
@ -80,30 +113,53 @@ impl App {
if self.kb_input.down(Key::Down) { if self.kb_input.down(Key::Down) {
self.game.camera_offset.y = self.game.camera_offset.y.saturating_add(spd); 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) { fn do_rendering(&mut self) {
self.rw.clear(Color::rgb(55, 221, 231)); self.rw.clear(Color::rgb(55, 221, 231));
self.game.draw_world(&mut self.rw, &self.res); self.game.draw_world(&mut self.rw, &self.res);
self.game.draw_entities(&mut self.rw);
self.sf_egui self.sf_egui
.do_frame(|ctx| { .do_frame(|ctx| {
egui::Window::new("Debug").show(ctx, |ui| { if self.debug.panel {
debug_panel_ui(&mut self.debug, &mut self.game, ctx);
}
})
.unwrap();
self.sf_egui.draw(&mut self.rw, None);
self.rw.display();
}
}
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.label("Cam x");
ui.add(egui::DragValue::new(&mut self.game.camera_offset.x)); ui.add(egui::DragValue::new(&mut game.camera_offset.x));
ui.label("Cam y"); ui.label("Cam y");
ui.add(egui::DragValue::new(&mut self.game.camera_offset.y)); ui.add(egui::DragValue::new(&mut game.camera_offset.y));
let tile_off = self.game.camera_offset.tile_pos(); if debug.freecam {
let tp = game.camera_offset.tile_pos();
imm_dbg!(tp);
ui.label(format!( ui.label(format!(
"Depth: {}", "Cam Depth: {}",
LengthDisp(tile_off.y as i64 - wp_to_tp(WorldPos::SURFACE) as i64) LengthDisp(tp.y as i64 - wp_to_tp(WorldPos::SURFACE) as i64)
)); ));
ui.label(format!( ui.label(format!(
"Offset from center: {}", "Cam offset from center: {}",
LengthDisp(tile_off.x as i64 - wp_to_tp(WorldPos::CENTER) as i64) 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(); ui.separator();
egui::ScrollArea::vertical().show(ui, |ui| { egui::ScrollArea::vertical().show(ui, |ui| {
gamedebug_core::for_each_imm(|info| match info { gamedebug_core::for_each_imm(|info| match info {
@ -115,11 +171,6 @@ impl App {
}); });
gamedebug_core::clear_immediates(); gamedebug_core::clear_immediates();
}); });
})
.unwrap();
self.sf_egui.draw(&mut self.rw, None);
self.rw.display();
}
} }
struct LengthDisp(i64); struct LengthDisp(i64);

20
src/debug.rs Normal file
View file

@ -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;
}
}
}

View file

@ -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::{ use crate::{
graphics::{ScreenPos, ScreenPosScalar, NATIVE_RESOLUTION}, graphics::{ScreenPos, ScreenPosScalar, NATIVE_RESOLUTION},
@ -7,9 +9,12 @@ use crate::{
world::{Tile, TilePos, World}, world::{Tile, TilePos, World},
}; };
use self::player::Player;
pub struct GameState { pub struct GameState {
pub camera_offset: WorldPos, pub camera_offset: WorldPos,
pub world: World, pub world: World,
pub player: Player,
} }
impl GameState { impl GameState {
pub(crate) fn draw_world(&mut self, rw: &mut RenderWindow, res: &Res) { pub(crate) fn draw_world(&mut self, rw: &mut RenderWindow, res: &Res) {
@ -24,6 +29,16 @@ impl GameState {
rw.draw(&s); 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)) { fn for_each_tile_on_screen(camera_offset: WorldPos, mut f: impl FnMut(TilePos, ScreenPos)) {
@ -48,6 +63,7 @@ impl Default for GameState {
Self { Self {
camera_offset: WorldPos::SURFACE_CENTER, camera_offset: WorldPos::SURFACE_CENTER,
world: Default::default(), world: Default::default(),
player: Player::new_at(WorldPos::SURFACE_CENTER),
} }
} }
} }

24
src/game/player.rs Normal file
View file

@ -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,
}
}
}

View file

@ -1,4 +1,5 @@
mod app; mod app;
mod debug;
mod game; mod game;
mod graphics; mod graphics;
mod input; mod input;