This repository has been archived on 2021-10-11. You can view files and clone it, but cannot push or open issues or pull requests.

75 lines
2.4 KiB
Rust

use std::ops::Mul;
use raylib::math::{Rectangle, Vector2};
use crate::scenes::ingame_scene::world::WORLD_LEVEL_X_OFFSET;
use super::{CharacterState, MainCharacter};
pub const GRAVITY_PPS: f32 = 2.0;
pub fn modify_player_based_on_forces(
player: &mut MainCharacter,
colliders: &Vec<Rectangle>,
level_height_offset: f32,
) -> Result<(), ()> {
// Modify the player's velocity by the forces
player.movement_force += player.base_velocity;
player.velocity = player.movement_force;
// Predict the player's position next frame
let predicted_player_position = player.position + player.velocity;
// Calculate a bounding rect around the player both now, and one frame in the future
let player_rect = Rectangle::new(
predicted_player_position.x - (player.size.x / 2.0),
predicted_player_position.y - (player.size.x / 2.0),
player.size.x,
player.size.y,
);
// Calculate a generic "floor" to always collide with
let floor_rect = Rectangle::new(f32::MIN, 0.0, f32::MAX, 1.0);
// Check collision conditions
let check_player_colliding_with_floor = || floor_rect.check_collision_recs(&player_rect);
let check_player_colliding_with_floor_next_frame =
|| player_rect.y + player_rect.height > floor_rect.y;
let check_player_colliding_with_colliders = || {
colliders.iter().any(|rect| {
let mut translated_rect = rect.clone();
translated_rect.y += level_height_offset;
translated_rect.x += WORLD_LEVEL_X_OFFSET;
translated_rect.check_collision_recs(&player_rect)
})
};
// If the player is colliding, only apply the x force
if (check_player_colliding_with_floor()
|| check_player_colliding_with_floor_next_frame()
|| check_player_colliding_with_colliders())
&& player.velocity.y != 0.0
{
player.velocity.y = 0.0;
// Handle ending a jump
if player.current_state == CharacterState::Jumping
|| player.current_state == CharacterState::Dashing
{
player.update_player(
Some(CharacterState::Running),
colliders,
level_height_offset,
);
return Ok(());
}
}
// Check sideways collisions
// Finally apply the velocity to the player
player.position += player.velocity;
Ok(())
}