Added jumping, grounded and falling states. Modified force and gravity
This commit is contained in:
parent
f55faadbe4
commit
8e739de9bc
@ -1,12 +1,12 @@
|
||||
use bevy::prelude::*;
|
||||
use bevy_rapier3d::prelude::*;
|
||||
|
||||
use crate::logic::core::player::player_movement::{PlayerMovementInput, move_player};
|
||||
use crate::logic::core::player::player_movement::{PlayerMovementInput, move_player, PlayerLinearYState};
|
||||
|
||||
use super::markers::player::Player;
|
||||
|
||||
/// System that captures input and fires events
|
||||
pub fn capture_input(keyboard_input: Res<Input<KeyCode>>, query: Query<(&mut Velocity, &mut ExternalImpulse), With<Player>>, time: Res<Time>) {
|
||||
pub fn capture_input(keyboard_input: Res<Input<KeyCode>>, query: Query<(&mut Velocity, &mut ExternalImpulse, &mut PlayerLinearYState), With<Player>>, time: Res<Time>) {
|
||||
// Don't allocate on each frame. Instead Check if any of the inputs are being pressed and then allocate.
|
||||
if keyboard_input.any_pressed([KeyCode::A, KeyCode::S, KeyCode::D, KeyCode::W, KeyCode::C, KeyCode::Space]) {
|
||||
let player_movement_input = PlayerMovementInput {
|
||||
|
@ -1,3 +1,6 @@
|
||||
|
||||
pub const MAX_LINEAR_PLAYER_VELOCITY: f32 = 10.0;
|
||||
pub const PLAYER_ACCELERATION: f32 = 10.0;
|
||||
pub const PLAYER_ACCELERATION: f32 = 10.0;
|
||||
pub const PLAYER_JUMP_FORCE: f32 = 1500.0;
|
||||
/// Time in ms that player must be grounded in order to jump again
|
||||
pub const PLAYER_JUMP_COOLDOWN_MS: u64 = 300;
|
@ -1,3 +1,4 @@
|
||||
pub mod player_movement;
|
||||
pub mod spawn_player;
|
||||
pub mod camera_player_sync;
|
||||
pub mod camera_player_sync;
|
||||
pub mod player_vertical_sync;
|
@ -1,7 +1,38 @@
|
||||
use bevy::prelude::*;
|
||||
use bevy_rapier3d::prelude::*;
|
||||
|
||||
use crate::{comps::core::markers::player::Player, constants::player_values::{MAX_LINEAR_PLAYER_VELOCITY, PLAYER_ACCELERATION}};
|
||||
use crate::{comps::core::markers::player::Player, constants::player_values::{MAX_LINEAR_PLAYER_VELOCITY, PLAYER_ACCELERATION, PLAYER_JUMP_COOLDOWN_MS, PLAYER_JUMP_FORCE}};
|
||||
|
||||
#[derive(Component)]
|
||||
pub enum PlayerLinearYState {
|
||||
Grounded(u64),
|
||||
Jumping,
|
||||
Falling
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
impl PlayerLinearYState {
|
||||
pub fn is_grounded(&self, longer_than: u64) -> bool {
|
||||
match self {
|
||||
Self::Grounded(time_grounded) => {
|
||||
time_grounded > &longer_than
|
||||
},
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
pub fn is_jumping(&self) -> bool {
|
||||
match self {
|
||||
Self::Jumping => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
pub fn is_falling(&self) -> bool {
|
||||
match self {
|
||||
Self::Falling => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Holds all the possible ways a player can be attempting to move at any time.
|
||||
#[derive(Default)]
|
||||
@ -25,8 +56,8 @@ pub struct PlayerMovementInput {
|
||||
}
|
||||
|
||||
/// Applies game logic to determine how player should move.
|
||||
pub fn move_player(player_movement_input: PlayerMovementInput, mut query: Query<(&mut Velocity, &mut ExternalImpulse), With<Player>>, time: Res<Time>,) {
|
||||
for (mut player_velocity, mut player_external_force) in &mut query {
|
||||
pub fn move_player(player_movement_input: PlayerMovementInput, mut query: Query<(&mut Velocity, &mut ExternalImpulse, &mut PlayerLinearYState), With<Player>>, time: Res<Time>,) {
|
||||
for (mut player_velocity, mut player_external_force, mut player_linear_y_state) in &mut query {
|
||||
let crouch_multiplier = if player_movement_input.down {
|
||||
0.25
|
||||
} else {
|
||||
@ -50,8 +81,9 @@ pub fn move_player(player_movement_input: PlayerMovementInput, mut query: Query<
|
||||
player_velocity.linvel.x = apply_movement_acceleration(player_velocity.linvel.x, false, time.delta_seconds(), 1.0);
|
||||
}
|
||||
|
||||
if player_movement_input.up {
|
||||
player_external_force.impulse = Vec3::new(0.0, 200.0, 0.0);
|
||||
if player_movement_input.up && player_linear_y_state.is_grounded(PLAYER_JUMP_COOLDOWN_MS) {
|
||||
player_external_force.impulse = Vec3::new(0.0, PLAYER_JUMP_FORCE, 0.0);
|
||||
*player_linear_y_state = PlayerLinearYState::Jumping;
|
||||
}
|
||||
// When player velocity exceeds max linear velocity then set to max_linear_vel value
|
||||
if player_velocity.linvel.x.abs() > MAX_LINEAR_PLAYER_VELOCITY * crouch_multiplier * sprint_multiplier {
|
||||
|
24
src/logic/core/player/player_vertical_sync.rs
Normal file
24
src/logic/core/player/player_vertical_sync.rs
Normal file
@ -0,0 +1,24 @@
|
||||
use bevy::prelude::*;
|
||||
use bevy_rapier3d::prelude::*;
|
||||
|
||||
use crate::comps::core::markers::player::Player;
|
||||
|
||||
use super::player_movement::PlayerLinearYState;
|
||||
|
||||
|
||||
|
||||
/// System that captures input and fires events
|
||||
pub fn sync_player_y_state(mut query: Query<(&Velocity, &mut PlayerLinearYState), With<Player>>, time: Res<Time>) {
|
||||
for (player_velocity, mut player_linear_y_state) in &mut query {
|
||||
if player_velocity.linvel.y < -1.0 {
|
||||
*player_linear_y_state = PlayerLinearYState::Falling;
|
||||
} else if player_velocity.linvel.y >= -1.0 && player_velocity.linvel.y <= 1.0 {
|
||||
let previous_grounded_time = match *player_linear_y_state {
|
||||
PlayerLinearYState::Grounded(grounded_for) => grounded_for,
|
||||
_ => 0
|
||||
};
|
||||
*player_linear_y_state = PlayerLinearYState::Grounded(previous_grounded_time + time.delta().as_millis() as u64);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -3,10 +3,12 @@ use bevy_rapier3d::prelude::*;
|
||||
|
||||
use crate::comps::core::{markers::player::Player, camera::MainCamera};
|
||||
|
||||
use super::player_movement::PlayerLinearYState;
|
||||
|
||||
pub fn spawn_player(mut commands: Commands) {
|
||||
commands.spawn(Player)
|
||||
.insert(RigidBody::Dynamic)
|
||||
.insert(GravityScale(1.0))
|
||||
.insert(GravityScale(2.5))
|
||||
.insert(Collider::capsule_y(2.0, 2.0))
|
||||
.insert(Restitution::coefficient(0.3))
|
||||
.insert(Friction { coefficient: 0.0, ..Default::default() })
|
||||
@ -14,11 +16,12 @@ pub fn spawn_player(mut commands: Commands) {
|
||||
.insert(Velocity::zero())
|
||||
.insert(Damping { linear_damping: 1.0, angular_damping: 1.0 })
|
||||
.insert(LockedAxes::ROTATION_LOCKED_X | LockedAxes::ROTATION_LOCKED_Z)
|
||||
.insert(ColliderMassProperties::Mass(100.0))
|
||||
.insert(ColliderMassProperties::Density(2.0))
|
||||
.insert(ExternalImpulse {
|
||||
impulse: Vec3::ZERO,
|
||||
torque_impulse: Vec3::ZERO,
|
||||
});
|
||||
})
|
||||
.insert(PlayerLinearYState::Falling);
|
||||
|
||||
|
||||
commands.spawn(MainCamera)
|
||||
|
@ -23,8 +23,8 @@ fn main() {
|
||||
fn setup_plugins(application: &mut App) {
|
||||
application
|
||||
.add_plugins(DefaultPlugins)
|
||||
.add_plugins(RapierPhysicsPlugin::<NoUserData>::default()) // Rapier Physics
|
||||
;//.add_plugins(RapierDebugRenderPlugin::default()); // Uncomment this to see physics objects as wireframes
|
||||
.add_plugins(RapierPhysicsPlugin::<NoUserData>::default()); // Rapier Physics
|
||||
//.add_plugins(RapierDebugRenderPlugin::default()); // Uncomment this to see physics objects as wireframes
|
||||
}
|
||||
|
||||
fn load(application: &mut App) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use bevy::prelude::*;
|
||||
|
||||
use crate::{logic::core::player::{spawn_player::spawn_player, camera_player_sync::sync_camera_to_player}, comps::core::controller::capture_input};
|
||||
use crate::{logic::core::player::{spawn_player::spawn_player, camera_player_sync::sync_camera_to_player, player_vertical_sync::sync_player_y_state}, comps::core::controller::capture_input};
|
||||
|
||||
use super::{ground::spawn_ground, lighting::setup_lighting, obstacles::spawn_obstacles};
|
||||
|
||||
@ -15,6 +15,7 @@ pub fn load_scene(application: &mut App) {
|
||||
// Update
|
||||
application.add_systems(Update, capture_input);
|
||||
application.add_systems(Update, sync_camera_to_player);
|
||||
application.add_systems(Update, sync_player_y_state);
|
||||
|
||||
application.add_systems(Startup, setup_lighting);
|
||||
}
|
Loading…
Reference in New Issue
Block a user