Merge pull request from Ewpratten/interaction_bugfixes

Interaction bugfixes
This commit is contained in:
Evan Pratten 2021-10-02 19:30:15 -07:00 committed by GitHub
commit 251df8b0ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 100 additions and 51 deletions
.vscode
game

11
.vscode/tasks.json vendored

@ -48,12 +48,19 @@
},
{
"type": "cargo",
"subcommand": "build",
"command": "run",
"args": [
"--features",
"collider_debug"
],
"problemMatcher": [
"$rustc"
],
"group": "build",
"label": "Rust: cargo build - ludum-dare-49"
"label": "Rust: Run Game - DEBUG COLLIDERS",
"env": {
"RUST_LOG": "debug"
}
}
]
}

@ -40,3 +40,7 @@ puffin_viewer = "0.6"
[build-dependencies]
vergen = "5"
anyhow = "1.0"
[features]
default = []
collider_debug = []

@ -1,4 +1,10 @@
[
{
"x": -500,
"y": 1000,
"width": 16000,
"height": 10
},
{
"x": 322,
"y": 926,
@ -7,13 +13,13 @@
},
{
"x": 852,
"y": 882,
"y": 823,
"width": 81,
"height": 178
},
{
"x": 852,
"y": 882,
"y": 823,
"width": 258,
"height": 33
},

@ -1,6 +1,7 @@
use std::ops::Mul;
use raylib::math::{Rectangle, Vector2};
use tracing::trace;
use crate::scenes::ingame_scene::world::WORLD_LEVEL_X_OFFSET;
@ -14,6 +15,8 @@ pub fn modify_player_based_on_forces(
colliders: &Vec<Rectangle>,
level_height_offset: f32,
) -> Result<(), ()> {
trace!("Player state: {:?}", player.current_state);
// Modify the player's velocity by the forces
player.movement_force += player.base_velocity;
player.velocity = player.movement_force;
@ -22,26 +25,27 @@ pub fn modify_player_based_on_forces(
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(
let mut 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,
);
let predicted_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)
|| translated_rect.check_collision_recs(&predicted_player_rect)
})
};
let check_player_colliding_with_colliders_forwards = || {
@ -49,9 +53,9 @@ pub fn modify_player_based_on_forces(
let mut translated_rect = rect.clone();
translated_rect.y += level_height_offset;
translated_rect.x += WORLD_LEVEL_X_OFFSET;
translated_rect.check_collision_recs(&Rectangle{
translated_rect.check_collision_recs(&Rectangle {
x: player_rect.x + 1.0,
y: player_rect.y - 1.0 ,
y: player_rect.y - 1.0,
width: player_rect.width,
height: player_rect.height,
})
@ -59,10 +63,9 @@ pub fn modify_player_based_on_forces(
};
// 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
if player.velocity.y != 0.0
&& (check_player_colliding_with_colliders()
|| check_player_colliding_with_colliders_forwards())
{
player.velocity.y = 0.0;
@ -76,15 +79,30 @@ pub fn modify_player_based_on_forces(
level_height_offset,
);
}
}
// Check sideways collisions
if player.velocity.y == 0.0 && check_player_colliding_with_colliders_forwards(){
return Err(());
}else if player.current_state == CharacterState::Running {
player.override_state(CharacterState::Jumping);
}
// Finally apply the velocity to the player
player.position += player.velocity;
// Re-calculate the player rect
player_rect = Rectangle::new(
player.position.x - (player.size.x / 2.0),
player.position.y - (player.size.x / 2.0),
player.size.x,
player.size.y,
);
if 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)
}) {
return Err(());
}
Ok(())
}

@ -53,6 +53,14 @@ impl MainCharacter {
}
}
pub fn override_state(&mut self, state: CharacterState) {
// Update the internal state
if state != self.current_state {
self.current_state = state.clone();
self.state_set_timestamp = Utc::now();
}
}
#[must_use]
pub fn update_player(
&mut self,
@ -61,18 +69,15 @@ impl MainCharacter {
level_height_offset: f32,
) -> Result<(), ()> {
if let Some(state) = state {
// Update the internal state
if state != self.current_state {
self.current_state = state.clone();
self.state_set_timestamp = Utc::now();
}
// Handle extra external forces based on the character state
self.movement_force = match state {
self.movement_force = match &state {
CharacterState::Running => Vector2::new(10.0, 0.0),
CharacterState::Jumping => Vector2::new(10.0, -30.0),
CharacterState::Dashing => Vector2::new(30.0, -20.0),
};
// Update the internal state
self.override_state(state);
}
// Update the player based on the new velocity

@ -41,24 +41,25 @@ pub fn render_character_in_camera_space(
);
// Possibly render a debug vector
// if config.debug_view {
raylib.draw_line_v(
player.position.sub(player.size.div(2.0)),
player
.position
.sub(player.size.div(2.0))
.add(player.velocity.mul(10.0).add(Vector2::new(0.0, 100.0))),
Color::RED,
);
raylib.draw_rectangle_lines_ex(
Rectangle::new(
player.position.x - (player.size.x / 2.0),
player.position.y - (player.size.x / 2.0),
player.size.x,
player.size.y,
),
2,
Color::RED,
);
// }
#[cfg(all(debug_assertions, feature = "collider_debug"))]
{
raylib.draw_line_v(
player.position.sub(player.size.div(2.0)),
player
.position
.sub(player.size.div(2.0))
.add(player.velocity.mul(10.0).add(Vector2::new(0.0, 100.0))),
Color::RED,
);
raylib.draw_rectangle_lines_ex(
Rectangle::new(
player.position.x - (player.size.x / 2.0),
player.position.y - (player.size.x / 2.0),
player.size.x,
player.size.y,
),
2,
Color::RED,
);
}
}

@ -61,6 +61,7 @@ impl Action<Scenes, ScreenError, GameContext> for DeathScreen {
fn on_finish(&mut self, _interrupted: bool) -> Result<(), ScreenError> {
debug!("Finished DeathScreen");
self.is_retry_pressed = false;
Ok(())
}
}

@ -63,6 +63,10 @@ impl Action<Scenes, ScreenError, GameContext> for InGameScreen {
fn on_first_run(&mut self, context: &GameContext) -> Result<(), ScreenError> {
debug!("Running InGameScreen for the first time");
// Handle cleanup after death
self.player_dead = false;
self.player.reset();
// Set the player to running
let cur_level = self.levels.get(self.current_level_idx).unwrap();
let _ = self.player.update_player(

@ -22,7 +22,9 @@ impl WorldSpaceRender for InGameScreen {
let cur_level = self.levels.get(self.current_level_idx).unwrap();
// Render the world background
cur_level.background_tex.render(raylib, Vector2::new(0.0, -1080.0), &self.camera);
cur_level
.background_tex
.render(raylib, Vector2::new(0.0, -1080.0), &self.camera);
// Render the platform layer
raylib.draw_texture_v(
@ -31,7 +33,8 @@ impl WorldSpaceRender for InGameScreen {
Color::WHITE,
);
if config.debug_view {
#[cfg(all(debug_assertions, feature = "collider_debug"))]
{
for collider in &cur_level.colliders {
let mut translated_collider = collider.clone();
translated_collider.y += -cur_level.platform_tex.height as f32;