From e2d96cc7e0b14f9fb59782f58ae2590cafc07b74 Mon Sep 17 00:00:00 2001 From: Louis Pearson Date: Thu, 23 May 2019 08:03:21 -0600 Subject: [PATCH] Add CollisionShape, move friction calculations to phys Former-commit-id: 3723a8f74bc2854aaa98357e2d0b51a1668d9030 --- common/src/sys/inputs.rs | 61 +++++++++++++++++----------------------- common/src/sys/phys.rs | 15 ++++++++++ 2 files changed, 41 insertions(+), 35 deletions(-) diff --git a/common/src/sys/inputs.rs b/common/src/sys/inputs.rs index 7e1f1216ee..198b485cda 100644 --- a/common/src/sys/inputs.rs +++ b/common/src/sys/inputs.rs @@ -17,6 +17,14 @@ use crate::{ // Basic ECS AI agent system pub struct Sys; +const HUMANOID_ACCEL: f32 = 100.0; +const HUMANOID_SPEED: f32 = 500.0; +const HUMANOID_AIR_ACCEL: f32 = 10.0; +const HUMANOID_AIR_SPEED: f32 = 100.0; +const HUMANOID_JUMP_ACCEL: f32 = 16.0; +const GLIDE_ACCEL: f32 = 25.0; +const GLIDE_SPEED: f32 = 200.0; + impl<'a> System<'a> for Sys { type SystemData = ( Entities<'a>, @@ -73,51 +81,34 @@ impl<'a> System<'a> for Sys { continue; } - // Handle held-down control let on_ground = terrain .get((pos.0 - Vec3::unit_z() * 0.1).map(|e| e.floor() as i32)) .map(|vox| !vox.is_empty()) .unwrap_or(false) && vel.0.z <= 0.0; - let (gliding, friction) = if on_ground { - // TODO: Don't hard-code this. - // Apply physics to the player: acceleration and non-linear deceleration. - vel.0 += Vec2::broadcast(dt.0) * control.move_dir * 200.0; + let gliding = glides.get(entity).is_some() && vel.0.z < 0.0; - if jumps.get(entity).is_some() { - vel.0.z += 16.0; + if on_ground { + // Move player according to move_dir + if vel.0.magnitude() < HUMANOID_SPEED { + vel.0 += Vec2::broadcast(dt.0) * control.move_dir * HUMANOID_ACCEL; + } + + // Jump + if jumps.get(entity).is_some() && vel.0.z <= 0.0 { + vel.0.z = HUMANOID_JUMP_ACCEL; jumps.remove(entity); } + } else if gliding && vel.0.magnitude() < GLIDE_SPEED { + let anti_grav = 9.81 * 3.95 + vel.0.z.powf(2.0) * 0.2; + vel.0.z += dt.0 * anti_grav * Vec2::::from(vel.0 * 0.15).magnitude().min(1.0); + vel.0 += Vec2::broadcast(dt.0) * control.move_dir * GLIDE_ACCEL; + } else if vel.0.magnitude() < HUMANOID_AIR_SPEED { + vel.0 += Vec2::broadcast(dt.0) * control.move_dir * HUMANOID_AIR_ACCEL; + } - (false, 0.15) - } else { - // TODO: Don't hard-code this. - // Apply physics to the player: acceleration and non-linear deceleration. - vel.0 += Vec2::broadcast(dt.0) * control.move_dir * 10.0; - - if glides.get(entity).is_some() && vel.0.z < 0.0 { - // TODO: Don't hard-code this. - let anti_grav = 9.81 * 3.95 + vel.0.z.powf(2.0) * 0.2; - vel.0.z += - dt.0 * anti_grav * Vec2::::from(vel.0 * 0.15).magnitude().min(1.0); - - (true, 0.008) - } else { - (false, 0.015) - } - }; - - // Friction - vel.0 -= Vec2::broadcast(dt.0) - * 50.0 - * vel.0.map(|e| { - (e.abs() * friction * (vel.0.magnitude() * 0.1 + 0.5)) - .min(e.abs() * dt.0 * 50.0) - .copysign(e) - }) - * Vec3::new(1.0, 1.0, 0.0); - + // Set direction based on velocity if vel.0.magnitude_squared() != 0.0 { ori.0 = vel.0.normalized() * Vec3::new(1.0, 1.0, 0.0); } diff --git a/common/src/sys/phys.rs b/common/src/sys/phys.rs index 94a8f565b2..bafbe3e7c5 100644 --- a/common/src/sys/phys.rs +++ b/common/src/sys/phys.rs @@ -31,6 +31,21 @@ impl<'a> System<'a> for Sys { continue; } + // Handle held-down control + let on_ground = terrain + .get((pos.0 - Vec3::unit_z() * 0.1).map(|e| e.floor() as i32)) + .map(|vox| !vox.is_empty()) + .unwrap_or(false) + && vel.0.z <= 0.0; + + // Friction + // Will never make the character go backwards since it is interpolating towards 0 + let friction = if on_ground { 0.15 } else { 0.015 }; + let mul = 50.0; + let z = vel.0.z; + vel.0 = Vec3::lerp(vel.0, Vec3::new(0.0, 0.0, 0.0), friction * dt.0 * mul); + vel.0.z = z; + // Gravity vel.0.z = (vel.0.z - GRAVITY * dt.0).max(-50.0);