From d15c15271830e2d2949355842e3849e6e8681f5d Mon Sep 17 00:00:00 2001 From: Joshua Walker Date: Mon, 25 Nov 2024 21:08:43 -0700 Subject: [PATCH] fix: player no longer bounces when crossing tile boundaries fixes #18 --- game/src/movement/plugin.rs | 2 +- game/src/plugins/level_load_plugin.rs | 55 ++++++++++++++++----------- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/game/src/movement/plugin.rs b/game/src/movement/plugin.rs index 816a4b2..458c535 100644 --- a/game/src/movement/plugin.rs +++ b/game/src/movement/plugin.rs @@ -101,7 +101,7 @@ impl CharacterControllerBundle { pub fn new(collider: Collider) -> Self { // Create shape caster as a slightly smaller version of collider let mut caster_shape = collider.clone(); - caster_shape.set_scale(Vector::ONE * 0.99, 10); + caster_shape.set_scale(Vector::ONE * 0.75, 10); Self { character_controller: CharacterController, diff --git a/game/src/plugins/level_load_plugin.rs b/game/src/plugins/level_load_plugin.rs index f509278..599fecc 100644 --- a/game/src/plugins/level_load_plugin.rs +++ b/game/src/plugins/level_load_plugin.rs @@ -6,24 +6,28 @@ use crate::components::{ use crate::movement::plugin::*; use avian2d::math::{Scalar, Vector}; use avian2d::prelude::*; -use bevy::prelude::*; +use bevy::{ecs::entity, math::vec2, prelude::*}; use bevy_ecs_ldtk::prelude::*; const LDTK_PROJECT_NAME: &str = "TestLevel.ldtk"; -const PLAYER_COLLIDER_RADIUS: Scalar = 12.5; -const PLAYER_COLLIDER_LOWER_ENDPOINT: Vector = Vector::new(0.0, -15.0); -const PLAYER_COLLIDER_UPPER_ENDPOINT: Vector = Vector::new(0.0, -8.0); +const PLAYER_HITBOX_SHIFT_X: f32 = 0.0; +const PLAYER_HITBOX_SHIFT_Y: f32 = -12.0; +const PLAYER_HITBOX_ROTATION: f32 = 0.0; +const PLAYER_HITBOX_WIDTH: f32 = 8.0; +const PLAYER_HITBOX_LENGTH: f32 = 24.0; const PLAYER_ACCELERATION: Scalar = 125.0; const PLAYER_STARTING_HEALTH: u32 = 100; const PLAYER_DAMPING: Scalar = 1.0; const PLAYER_JUMP_IMPULSE: Scalar = 130.0; -const PLAYER_MAX_SLOPE_ANGLE: Scalar = 30.0 as Scalar; -const PLAYER_COLLIDER_DENSITY: ColliderDensity = ColliderDensity(5.0); +const PLAYER_MAX_SLOPE_ANGLE: Scalar = 10.0 as Scalar; +const PLAYER_COLLIDER_DENSITY: ColliderDensity = ColliderDensity(50000.0); const PLAYER_GRAVITY_SCALE: GravityScale = GravityScale(10.0); -const COLLIDABLES_SHIFT: f32 = 12.0; -const COLLIDABLES_COLLIDER_SIZE_X: f32 = 23.9; -const COLLIDABLES_COLLIDER_SIZE_Y: f32 = 23.9; -const COLLIDABLES_COLLIDER_DENSITY: ColliderDensity = ColliderDensity(1000.0); +const PLAYER_COLLISION_MARGIN: CollisionMargin = CollisionMargin(5.0); +const COLLIDABLES_SHIFT_CENTER: f32 = 12.0; +const COLLIDABLES_SHIFT_VERTEX: f32 = 24.0; +const COLLIDABLES_COLLIDER_SIZE_X: f32 = 24.0; +const COLLIDABLES_COLLIDER_SIZE_Y: f32 = 24.0; +const COLLIDABLES_COLLIDER_DENSITY: ColliderDensity = ColliderDensity(100000.0); ///LevelLoadPlugin handle the loading of an LDTtk project into the game ///The plugin handles parsing in the world and entities @@ -56,26 +60,30 @@ fn world_setup(mut command: Commands, asset_server: Res) { ///player_setup queries for any entities that were added the previous update ///with the "Player" tag then adds appropriate components -fn player_setup(mut commands: Commands, query: Query>) { +fn player_setup(mut commands: Commands, query: Query<(Entity, &Transform), Added>) { let new_players = query.iter(); - for entity in new_players { + for (entity, player_position) in new_players { + let shapes = vec![( + Position::new(Vec2::new(PLAYER_HITBOX_SHIFT_X, PLAYER_HITBOX_SHIFT_Y)), + Rotation::degrees(PLAYER_HITBOX_ROTATION), + Collider::rectangle(PLAYER_HITBOX_WIDTH, PLAYER_HITBOX_LENGTH), + )]; + let player_health = HealthBundle { health: Health::new(PLAYER_STARTING_HEALTH), }; - let new_control = CharacterControllerBundle::new(Collider::capsule_endpoints( - PLAYER_COLLIDER_RADIUS, - PLAYER_COLLIDER_LOWER_ENDPOINT, - PLAYER_COLLIDER_UPPER_ENDPOINT, - )) - .with_movement( + let new_control = CharacterControllerBundle::new(Collider::compound(shapes)).with_movement( PLAYER_ACCELERATION, PLAYER_DAMPING, PLAYER_JUMP_IMPULSE, PLAYER_MAX_SLOPE_ANGLE.to_radians(), ); + commands + .entity(entity) + .insert(PLAYER_COLLISION_MARGIN); commands.entity(entity).insert(player_health); commands.entity(entity).insert(new_control); commands @@ -97,14 +105,15 @@ fn player_setup(mut commands: Commands, query: Query>) { ///with the "Collidable" tag then adds appropriate components fn collidables_setup( mut commands: Commands, - query: Query<(Entity, &Transform), Added>, + new_tile_query: Query<(Entity, &Transform), Added>, ) { - let new_collidables = query.iter(); + let new_collidables = new_tile_query.iter(); - for (_collidable, position) in new_collidables { + for (_new_tile, position) in new_collidables { let mut new_position = *position; - new_position.translation.x += COLLIDABLES_SHIFT; - new_position.translation.y += COLLIDABLES_SHIFT; + + new_position.translation.x += COLLIDABLES_SHIFT_CENTER; + new_position.translation.y += COLLIDABLES_SHIFT_CENTER; commands.spawn(( SpriteBundle {