Prevent mid-air jump

This commit is contained in:
Pascal Engélibert 2022-08-25 14:47:20 +02:00
parent e7f2188091
commit f117b2750a
Signed by: tuxmain
GPG key ID: 3504BC6D362F7DCA
2 changed files with 102 additions and 59 deletions

View file

@ -14,9 +14,9 @@
* despawn black characters * despawn black characters
* despawn character when too far * despawn character when too far
* level design * level design
* (?) can jump only from a surface (no mid-air jump)
* (?) multiplayer * (?) multiplayer
* more audio * more audio
* "jumpable" component to avoid jumping on sensors
## Build ## Build

View file

@ -93,6 +93,9 @@ pub struct CharacterColor(pub Color);
#[derive(Component)] #[derive(Component)]
pub struct Player; pub struct Player;
#[derive(Component)]
pub struct CollisionCount(usize);
// Systems // Systems
fn setup( fn setup(
@ -161,7 +164,16 @@ pub fn spawn_character(
linear_damping: 0.5, linear_damping: 0.5,
angular_damping: 0.5, angular_damping: 0.5,
}) })
.insert(ActiveEvents::COLLISION_EVENTS); .insert(ActiveEvents::COLLISION_EVENTS)
.with_children(|c| {
c.spawn_bundle(TransformBundle::from_transform(Transform::from_xyz(
0., -33., 0.,
)))
.insert(Sensor)
.insert(Collider::cuboid(30., 0.5))
.insert(ActiveEvents::COLLISION_EVENTS)
.insert(CollisionCount(0));
});
if is_player { if is_player {
entity_commands.insert(Player); entity_commands.insert(Player);
@ -214,11 +226,13 @@ fn collision_event_system(
Option<&Player>, Option<&Player>,
)>, )>,
pass_through_filter_query: Query<&PassThroughFilter>, pass_through_filter_query: Query<&PassThroughFilter>,
mut collision_counter_query: Query<&mut CollisionCount>,
mut app_state: ResMut<State<AppState>>, mut app_state: ResMut<State<AppState>>,
audio: Res<crossbeam_channel::Sender<AudioMsg>>, audio: Res<crossbeam_channel::Sender<AudioMsg>>,
) { ) {
for collision_event in collision_events.iter() { for collision_event in collision_events.iter() {
if let CollisionEvent::Started(e1, e2, flags) = collision_event { match collision_event {
CollisionEvent::Started(e1, e2, flags) => {
if flags.is_empty() { if flags.is_empty() {
if let ( if let (
Ok((c1_color, c1_transform, _c1_material, c1_player)), Ok((c1_color, c1_transform, _c1_material, c1_player)),
@ -276,6 +290,32 @@ fn collision_event_system(
])) ]))
.ok(); .ok();
} }
} else if let (Ok(mut collision_count), Err(_)) = (
collision_counter_query.get_mut(*e1),
character_query.get_mut(*e2),
) {
collision_count.0 += 1;
} else if let (Ok(mut collision_count), Err(_)) = (
collision_counter_query.get_mut(*e2),
character_query.get_mut(*e1),
) {
collision_count.0 += 1;
}
}
}
CollisionEvent::Stopped(e1, e2, flags) => {
if *flags == CollisionEventFlags::SENSOR {
if let (Ok(mut collision_count), Err(_)) = (
collision_counter_query.get_mut(*e1),
character_query.get_mut(*e2),
) {
collision_count.0 = collision_count.0.saturating_sub(1);
} else if let (Ok(mut collision_count), Err(_)) = (
collision_counter_query.get_mut(*e2),
character_query.get_mut(*e1),
) {
collision_count.0 = collision_count.0.saturating_sub(1);
}
} }
} }
} }
@ -328,7 +368,8 @@ fn change_character_system(
fn player_movement_system( fn player_movement_system(
keyboard_input: Res<Input<KeyCode>>, keyboard_input: Res<Input<KeyCode>>,
mut characters: Query<&mut Velocity, With<Player>>, mut characters: Query<(&mut Velocity, &Children), With<Player>>,
collision_counter_query: Query<&CollisionCount>,
audio: Res<crossbeam_channel::Sender<AudioMsg>>, audio: Res<crossbeam_channel::Sender<AudioMsg>>,
) { ) {
let right_pressed: bool = let right_pressed: bool =
@ -336,12 +377,14 @@ fn player_movement_system(
let left_pressed: bool = let left_pressed: bool =
keyboard_input.pressed(KeyCode::Left) || keyboard_input.pressed(KeyCode::A); keyboard_input.pressed(KeyCode::Left) || keyboard_input.pressed(KeyCode::A);
for mut velocity in characters.iter_mut() { for (mut velocity, children) in characters.iter_mut() {
velocity.linvel.x = 200. * (right_pressed as i8 - left_pressed as i8) as f32; velocity.linvel.x = 200. * (right_pressed as i8 - left_pressed as i8) as f32;
if keyboard_input.just_pressed(KeyCode::Space) { if keyboard_input.just_pressed(KeyCode::Space)
&& collision_counter_query.get(children[0]).unwrap().0 != 0
{
audio.send(AudioMsg::Jump).ok(); audio.send(AudioMsg::Jump).ok();
velocity.linvel.y = 500.; velocity.linvel.y = 700.;
} }
} }
} }