Merge pull request #36 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

11
.vscode/tasks.json vendored
View File

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

View File

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

View File

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

View File

@ -1,6 +1,7 @@
use std::ops::Mul; use std::ops::Mul;
use raylib::math::{Rectangle, Vector2}; use raylib::math::{Rectangle, Vector2};
use tracing::trace;
use crate::scenes::ingame_scene::world::WORLD_LEVEL_X_OFFSET; use crate::scenes::ingame_scene::world::WORLD_LEVEL_X_OFFSET;
@ -14,6 +15,8 @@ pub fn modify_player_based_on_forces(
colliders: &Vec<Rectangle>, colliders: &Vec<Rectangle>,
level_height_offset: f32, level_height_offset: f32,
) -> Result<(), ()> { ) -> Result<(), ()> {
trace!("Player state: {:?}", player.current_state);
// Modify the player's velocity by the forces // Modify the player's velocity by the forces
player.movement_force += player.base_velocity; player.movement_force += player.base_velocity;
player.velocity = player.movement_force; player.velocity = player.movement_force;
@ -22,26 +25,27 @@ pub fn modify_player_based_on_forces(
let predicted_player_position = player.position + player.velocity; let predicted_player_position = player.position + player.velocity;
// Calculate a bounding rect around the player both now, and one frame in the future // 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.x - (player.size.x / 2.0),
predicted_player_position.y - (player.size.x / 2.0), predicted_player_position.y - (player.size.x / 2.0),
player.size.x, player.size.x,
player.size.y, 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 // 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 = || { let check_player_colliding_with_colliders = || {
colliders.iter().any(|rect| { colliders.iter().any(|rect| {
let mut translated_rect = rect.clone(); let mut translated_rect = rect.clone();
translated_rect.y += level_height_offset; translated_rect.y += level_height_offset;
translated_rect.x += WORLD_LEVEL_X_OFFSET; translated_rect.x += WORLD_LEVEL_X_OFFSET;
translated_rect.check_collision_recs(&player_rect) translated_rect.check_collision_recs(&player_rect)
|| translated_rect.check_collision_recs(&predicted_player_rect)
}) })
}; };
let check_player_colliding_with_colliders_forwards = || { let check_player_colliding_with_colliders_forwards = || {
@ -49,9 +53,9 @@ pub fn modify_player_based_on_forces(
let mut translated_rect = rect.clone(); let mut translated_rect = rect.clone();
translated_rect.y += level_height_offset; translated_rect.y += level_height_offset;
translated_rect.x += WORLD_LEVEL_X_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, x: player_rect.x + 1.0,
y: player_rect.y - 1.0 , y: player_rect.y - 1.0,
width: player_rect.width, width: player_rect.width,
height: player_rect.height, 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 the player is colliding, only apply the x force
if (check_player_colliding_with_floor() if player.velocity.y != 0.0
|| check_player_colliding_with_floor_next_frame() && (check_player_colliding_with_colliders()
|| check_player_colliding_with_colliders()) || check_player_colliding_with_colliders_forwards())
&& player.velocity.y != 0.0
{ {
player.velocity.y = 0.0; player.velocity.y = 0.0;
@ -76,15 +79,30 @@ pub fn modify_player_based_on_forces(
level_height_offset, level_height_offset,
); );
} }
} }else if player.current_state == CharacterState::Running {
player.override_state(CharacterState::Jumping);
// Check sideways collisions
if player.velocity.y == 0.0 && check_player_colliding_with_colliders_forwards(){
return Err(());
} }
// Finally apply the velocity to the player // Finally apply the velocity to the player
player.position += player.velocity; 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(()) Ok(())
} }

View File

@ -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] #[must_use]
pub fn update_player( pub fn update_player(
&mut self, &mut self,
@ -61,18 +69,15 @@ impl MainCharacter {
level_height_offset: f32, level_height_offset: f32,
) -> Result<(), ()> { ) -> Result<(), ()> {
if let Some(state) = state { 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 // 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::Running => Vector2::new(10.0, 0.0),
CharacterState::Jumping => Vector2::new(10.0, -30.0), CharacterState::Jumping => Vector2::new(10.0, -30.0),
CharacterState::Dashing => Vector2::new(30.0, -20.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 // Update the player based on the new velocity

View File

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

View File

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

View File

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

View File

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