From beabf269e5df4807c234ae03db6c7000aec2919b Mon Sep 17 00:00:00 2001 From: crumblingstatue Date: Mon, 3 Apr 2023 17:39:49 +0200 Subject: [PATCH] Add basic player physics --- src/app.rs | 34 +++++++++++++++++++++++++++------- src/game.rs | 14 ++++++++------ src/game/player.rs | 2 ++ 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/app.rs b/src/app.rs index dc91dc9..fc480fc 100644 --- a/src/app.rs +++ b/src/app.rs @@ -9,11 +9,12 @@ use sfml::{ use crate::{ debug::DebugState, - game::GameState, + game::{for_each_tile_on_screen, GameState}, graphics::{self, NATIVE_RESOLUTION}, input::KbInput, - math::{wp_to_tp, WorldPos}, + math::{wp_to_tp, WorldPos, TILE_SIZE}, res::Res, + world::Tile, }; /// Application level state (includes game and ui state, etc.) @@ -81,12 +82,31 @@ impl App { 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); + if self.kb_input.pressed(Key::Up) { + self.game.player.vspeed = -14.0; } + self.game + .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(); 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; diff --git a/src/game.rs b/src/game.rs index e3772d8..1012958 100644 --- a/src/game.rs +++ b/src/game.rs @@ -4,7 +4,7 @@ use sfml::graphics::{Rect, RectangleShape, RenderTarget, RenderWindow, Sprite, T use crate::{ graphics::{ScreenPos, ScreenPosScalar, NATIVE_RESOLUTION}, - math::{wp_to_tp, WorldPos, WorldPosScalar}, + math::{wp_to_tp, WorldPos}, res::Res, 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 x in (-32..NATIVE_RESOLUTION.w + 32).step_by(32) { f( TilePos { - x: wp_to_tp(camera_offset.x.saturating_add(x as WorldPosScalar)), - y: wp_to_tp(camera_offset.y.saturating_add(y 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.try_into().unwrap_or(0))), }, ScreenPos { 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 { fn default() -> Self { + let mut spawn_point = WorldPos::SURFACE_CENTER; + spawn_point.y -= 300; Self { - camera_offset: WorldPos::SURFACE_CENTER, + camera_offset: spawn_point, world: Default::default(), - player: Player::new_at(WorldPos::SURFACE_CENTER), + player: Player::new_at(spawn_point), } } } diff --git a/src/game/player.rs b/src/game/player.rs index eef7e92..af5b0ae 100644 --- a/src/game/player.rs +++ b/src/game/player.rs @@ -7,12 +7,14 @@ use crate::{ pub struct Player { pub col_en: MobileEntity, + pub vspeed: f32, } 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)), + vspeed: 0.0, } } pub fn center_tp(&self) -> TilePos {