diff --git a/game/dist/project-constants.json b/game/dist/project-constants.json index 6f9303c7..cd2d0e59 100644 --- a/game/dist/project-constants.json +++ b/game/dist/project-constants.json @@ -16,5 +16,10 @@ "details.sm_failure": "Game went FUBAR", "details.main_menu": "In the main menu" } + }, + "player": { + "max_velocity": 3, + "acceleration": 2, + "deceleration": 1 } } diff --git a/game/game_logic/src/project_constants.rs b/game/game_logic/src/project_constants.rs index bd821f43..0797baf2 100644 --- a/game/game_logic/src/project_constants.rs +++ b/game/game_logic/src/project_constants.rs @@ -28,6 +28,20 @@ pub struct DiscordConstants { pub strings: HashMap, } +/// Constants relating to the Player +#[derive(Debug, Deserialize)] +pub struct PlayerConstants { + + /// Maximum velocity, tiles per second + pub max_velocity: u32, + + /// Acceleration, tiles per second per second + pub acceleration: u32, + + /// Deceleration, tiles per second per second + pub deceleration: u32, +} + /// This structure is filled with the contents of `dist/project-constants.json` at runtime #[derive(Debug, Deserialize)] pub struct ProjectConstants { @@ -40,6 +54,9 @@ pub struct ProjectConstants { /// The Discord constants pub discord: DiscordConstants, + /// The Player constants + pub player: PlayerConstants, + /// The target framerate of the game pub target_fps: u32, diff --git a/game/game_logic/src/scenes/mod.rs b/game/game_logic/src/scenes/mod.rs index 4ca705af..a58be6e1 100644 --- a/game/game_logic/src/scenes/mod.rs +++ b/game/game_logic/src/scenes/mod.rs @@ -69,7 +69,7 @@ impl SceneRenderDelegate { .render_frame(raylib, rl_thread, &discord, global_resources, constants) .await; self.scene_playable - .update_physics(raylib) + .update_physics(raylib, constants) .await; } MenuStateSignal::QuitGame => unimplemented!(), diff --git a/game/game_logic/src/scenes/player_interaction.rs b/game/game_logic/src/scenes/player_interaction.rs index cd1d269d..30128dc4 100644 --- a/game/game_logic/src/scenes/player_interaction.rs +++ b/game/game_logic/src/scenes/player_interaction.rs @@ -102,24 +102,45 @@ impl PlayableScene { pub async fn update_physics( &mut self, raylib: & raylib::RaylibHandle, + constants: &ProjectConstants, ) { + + // Get time since last physics update let time = SystemTime::now(); - if time - .duration_since(self.last_update) - .expect("Time Appears to Have Moved Backwards!") - .as_millis() < 16 - { - return - } - + let elapsed = time.duration_since(self.last_update).expect("Time Appears to Have Moved Backwards!"); self.last_update = time; + let delta_time = elapsed.as_millis() as f32 / 1000.0; // Physics will be scaled by this value let player = &mut self.player; + + // Get input direction components let h_axis = raylib.is_key_down(KeyboardKey::KEY_D) as i8 - raylib.is_key_down(KeyboardKey::KEY_A) as i8; let v_axis = raylib.is_key_down(KeyboardKey::KEY_W) as i8 - raylib.is_key_down(KeyboardKey::KEY_S) as i8; - let direction = na::Vector2::new(h_axis as f32, v_axis as f32); - player.velocity += &direction; - player.position += &player.velocity; + if h_axis != 0 || v_axis != 0 { + // Normalize input and accelerate in desired direction + let direction = na::Vector2::new(h_axis as f32, v_axis as f32).normalize(); + player.velocity += &direction.xy() + * constants.player.acceleration as f32 + * constants.tile_size as f32 + * delta_time; + } + + if player.velocity.magnitude() != 0.0 { + player.velocity -= player.velocity.normalize() + * constants.player.deceleration as f32 + * constants.tile_size as f32 + * delta_time; + if player.velocity.magnitude() < 0.01 { + player.velocity.set_magnitude(0.0); + } + } + + if ((constants.player.max_velocity * constants.tile_size) as f32) + < player.velocity.magnitude() { + player.velocity.set_magnitude((constants.player.max_velocity * constants.tile_size) as f32); + } + + player.position += &player.velocity * delta_time; } }