Add basic player physics

This commit is contained in:
crumblingstatue 2023-04-03 17:39:49 +02:00
parent 5a6fe33e1e
commit beabf269e5
3 changed files with 37 additions and 13 deletions

View file

@ -9,11 +9,12 @@ use sfml::{
use crate::{ use crate::{
debug::DebugState, debug::DebugState,
game::GameState, game::{for_each_tile_on_screen, GameState},
graphics::{self, NATIVE_RESOLUTION}, graphics::{self, NATIVE_RESOLUTION},
input::KbInput, input::KbInput,
math::{wp_to_tp, WorldPos}, math::{wp_to_tp, WorldPos, TILE_SIZE},
res::Res, res::Res,
world::Tile,
}; };
/// Application level state (includes game and ui state, etc.) /// Application level state (includes game and ui state, etc.)
@ -81,12 +82,31 @@ impl App {
if self.kb_input.down(Key::Right) { if self.kb_input.down(Key::Right) {
self.game.player.col_en.move_x(spd, |_, _| false); self.game.player.col_en.move_x(spd, |_, _| false);
} }
if self.kb_input.down(Key::Up) { if self.kb_input.pressed(Key::Up) {
self.game.player.col_en.move_y(-spd, |_, _| false); self.game.player.vspeed = -14.0;
} }
if self.kb_input.down(Key::Down) { self.game
self.game.player.col_en.move_y(spd, |_, _| false); .player
.col_en
.move_y(self.game.player.vspeed, |player_en, off| {
let mut col = false;
for_each_tile_on_screen(self.game.camera_offset, |tp, _sp| {
let tid = self.game.world.tile_at_mut(tp).id;
if tid == Tile::AIR {
return;
} }
let tsize = TILE_SIZE as i32;
let x = tp.x as i32 * TILE_SIZE as i32;
let y = tp.y as i32 * TILE_SIZE as i32;
let en = s2dc::Entity::from_rect_corners(x, y, x + tsize, y + tsize);
if player_en.would_collide(&en, off) {
col = true;
self.game.player.vspeed = 0.;
}
});
col
});
self.game.player.vspeed += 1.0;
let (x, y, _w, _h) = self.game.player.col_en.en.xywh(); 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.x = (x - NATIVE_RESOLUTION.w as i32 / 2) as u32;
self.game.camera_offset.y = (y - NATIVE_RESOLUTION.h as i32 / 2) as u32; self.game.camera_offset.y = (y - NATIVE_RESOLUTION.h as i32 / 2) as u32;

View file

@ -4,7 +4,7 @@ use sfml::graphics::{Rect, RectangleShape, RenderTarget, RenderWindow, Sprite, T
use crate::{ use crate::{
graphics::{ScreenPos, ScreenPosScalar, NATIVE_RESOLUTION}, graphics::{ScreenPos, ScreenPosScalar, NATIVE_RESOLUTION},
math::{wp_to_tp, WorldPos, WorldPosScalar}, math::{wp_to_tp, WorldPos},
res::Res, res::Res,
world::{Tile, TilePos, World}, world::{Tile, TilePos, World},
}; };
@ -41,13 +41,13 @@ impl GameState {
} }
} }
fn for_each_tile_on_screen(camera_offset: WorldPos, mut f: impl FnMut(TilePos, ScreenPos)) { pub fn for_each_tile_on_screen(camera_offset: WorldPos, mut f: impl FnMut(TilePos, ScreenPos)) {
for y in (-32..NATIVE_RESOLUTION.h + 32).step_by(32) { for y in (-32..NATIVE_RESOLUTION.h + 32).step_by(32) {
for x in (-32..NATIVE_RESOLUTION.w + 32).step_by(32) { for x in (-32..NATIVE_RESOLUTION.w + 32).step_by(32) {
f( f(
TilePos { TilePos {
x: wp_to_tp(camera_offset.x.saturating_add(x as WorldPosScalar)), x: wp_to_tp(camera_offset.x.saturating_add(x.try_into().unwrap_or(0))),
y: wp_to_tp(camera_offset.y.saturating_add(y as WorldPosScalar)), y: wp_to_tp(camera_offset.y.saturating_add(y.try_into().unwrap_or(0))),
}, },
ScreenPos { ScreenPos {
x: ((x as i64) - ((camera_offset.x as i64) % 32)) as ScreenPosScalar, x: ((x as i64) - ((camera_offset.x as i64) % 32)) as ScreenPosScalar,
@ -60,10 +60,12 @@ fn for_each_tile_on_screen(camera_offset: WorldPos, mut f: impl FnMut(TilePos, S
impl Default for GameState { impl Default for GameState {
fn default() -> Self { fn default() -> Self {
let mut spawn_point = WorldPos::SURFACE_CENTER;
spawn_point.y -= 300;
Self { Self {
camera_offset: WorldPos::SURFACE_CENTER, camera_offset: spawn_point,
world: Default::default(), world: Default::default(),
player: Player::new_at(WorldPos::SURFACE_CENTER), player: Player::new_at(spawn_point),
} }
} }
} }

View file

@ -7,12 +7,14 @@ use crate::{
pub struct Player { pub struct Player {
pub col_en: MobileEntity, pub col_en: MobileEntity,
pub vspeed: f32,
} }
impl Player { impl Player {
pub fn new_at(pos: WorldPos) -> Self { pub fn new_at(pos: WorldPos) -> Self {
Self { Self {
col_en: MobileEntity::from_pos_and_bb(vec2(pos.x as i32, pos.y as i32), vec2(15, 24)), col_en: MobileEntity::from_pos_and_bb(vec2(pos.x as i32, pos.y as i32), vec2(15, 24)),
vspeed: 0.0,
} }
} }
pub fn center_tp(&self) -> TilePos { pub fn center_tp(&self) -> TilePos {