character can now only jump on platforms

This commit is contained in:
Nixon 2022-08-27 20:51:18 +08:00
parent 4fc53c04aa
commit 3c721c3225

View file

@ -57,6 +57,8 @@ impl Plugin for GamePlugin {
.with_system(character_particle_effect_system) .with_system(character_particle_effect_system)
.with_system(move_win_text_system), .with_system(move_win_text_system),
) )
.add_system_to_stage(CoreStage::PostUpdate, char_char_collision_event_system)
.add_system_to_stage(CoreStage::PostUpdate, char_airbound_event_system)
.add_system_to_stage(CoreStage::PostUpdate, collision_event_system); .add_system_to_stage(CoreStage::PostUpdate, collision_event_system);
} }
} }
@ -102,7 +104,10 @@ pub struct CharacterColor(pub Color);
pub struct Player; pub struct Player;
#[derive(Component)] #[derive(Component)]
pub struct CollisionCount(usize); pub struct Platform;
#[derive(Component)]
pub struct Airbound(bool);
#[derive(Component)] #[derive(Component)]
pub struct Melty(pub Color); pub struct Melty(pub Color);
@ -198,7 +203,7 @@ pub fn spawn_character(
.insert(Sensor) .insert(Sensor)
.insert(Collider::cuboid(30., 0.5)) .insert(Collider::cuboid(30., 0.5))
.insert(ActiveEvents::COLLISION_EVENTS) .insert(ActiveEvents::COLLISION_EVENTS)
.insert(CollisionCount(0)); .insert(Airbound(true));
}); });
character_list.0.insert(entity_commands.id()); character_list.0.insert(entity_commands.id());
@ -239,7 +244,8 @@ pub fn spawn_platform(
..default() ..default()
}) })
.insert(Collider::cuboid(size.x / 2., size.y / 2.)) .insert(Collider::cuboid(size.x / 2., size.y / 2.))
.insert(Level); .insert(Level)
.insert(Platform);
} }
pub fn spawn_melty_platform( pub fn spawn_melty_platform(
@ -275,33 +281,29 @@ pub fn spawn_melty_platform(
}); });
} }
fn collision_event_system( fn char_char_collision_event_system(
mut commands: Commands, mut commands: Commands,
character_meshes: Res<CharacterMeshes>,
mut materials: ResMut<Assets<ColorMaterial>>,
mut collision_events: EventReader<CollisionEvent>, mut collision_events: EventReader<CollisionEvent>,
mut character_query: Query<( character_query: Query<(
&mut CharacterColor, &mut CharacterColor,
&Transform, &Transform,
&mut Handle<ColorMaterial>, &mut Handle<ColorMaterial>,
Option<&Player>, Option<&Player>,
)>, )>,
pass_through_filter_query: Query<&PassThroughFilter>,
melty_query: Query<&Melty>,
mut collision_counter_query: Query<&mut CollisionCount>,
mut app_state: ResMut<State<AppState>>,
audio: Res<crossbeam_channel::Sender<AudioMsg>>,
mut character_list: ResMut<CharacterList>, mut character_list: ResMut<CharacterList>,
mut app_state: ResMut<State<AppState>>,
character_meshes: Res<CharacterMeshes>,
audio: Res<crossbeam_channel::Sender<AudioMsg>>,
mut materials: ResMut<Assets<ColorMaterial>>,
) { ) {
for collision_event in collision_events.iter() { for collision_event in collision_events.iter() {
match collision_event { if let CollisionEvent::Started(e1, e2, _flags) = collision_event {
CollisionEvent::Started(e1, e2, flags) => {
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)),
Ok((c2_color, c2_transform, _c2_material, c2_player)), Ok((c2_color, c2_transform, _c2_material, c2_player)),
) = (character_query.get(*e1), character_query.get(*e2)) ) = (character_query.get(*e1), character_query.get(*e2)) {
{
character_list.0.remove(e1); character_list.0.remove(e1);
character_list.0.remove(e2); character_list.0.remove(e2);
commands.entity(*e1).despawn_recursive(); commands.entity(*e1).despawn_recursive();
@ -311,8 +313,7 @@ fn collision_event_system(
.clamp(Vec4::ZERO, Vec4::ONE); .clamp(Vec4::ZERO, Vec4::ONE);
// If color approximately white // If color approximately white
if app_state.current() == &AppState::Game && new_color.min_element() >= 0.9 if app_state.current() == &AppState::Game && new_color.min_element() >= 0.9 {
{
app_state.replace(AppState::Win).ok(); app_state.replace(AppState::Win).ok();
} }
@ -329,7 +330,7 @@ fn collision_event_system(
*c2_transform *c2_transform
} else { } else {
Transform::identity().with_translation( Transform::identity().with_translation(
(c1_transform.translation + c2_transform.translation) / 2., (c1_transform.translation + c2_transform.translation) * 0.5,
) )
}, },
new_color.into(), new_color.into(),
@ -337,7 +338,72 @@ fn collision_event_system(
); );
audio.send(AudioMsg::Fusion).ok(); audio.send(AudioMsg::Fusion).ok();
} else if let (Ok((c_color, _c_transform, _c_material, _c_player)), Ok(melty)) = }
}
}
}
fn char_airbound_event_system(
mut collision_events: EventReader<CollisionEvent>,
mut airbound_query: Query<&mut Airbound>,
platform_query: Query<&Platform>,
) {
// detect platform + player collisions only
for collision_event in collision_events.iter() {
match collision_event {
CollisionEvent::Started(e1, e2, flags) => {
if *flags == CollisionEventFlags::SENSOR {
if let (Ok(mut airbound), Ok(_)) = (
airbound_query.get_mut(*e1),
platform_query.get(*e2),
) {
airbound.0 = false;
} else if let (Ok(mut airbound), Ok(_)) = (
airbound_query.get_mut(*e2),
platform_query.get(*e1),
) {
airbound.0 = false;
}
}
}
CollisionEvent::Stopped(e1, e2, flags) => {
if *flags == CollisionEventFlags::SENSOR {
if let (Ok(mut airbound), Ok(_)) = (
airbound_query.get_mut(*e1),
platform_query.get(*e2),
) {
airbound.0 = true;
} else if let (Ok(mut airbound), Ok(_)) = (
airbound_query.get_mut(*e2),
platform_query.get(*e1),
) {
airbound.0 = true;
}
}
}
}
}
}
fn collision_event_system(
mut commands: Commands,
mut materials: ResMut<Assets<ColorMaterial>>,
mut collision_events: EventReader<CollisionEvent>,
mut character_query: Query<(
&mut CharacterColor,
&Transform,
&mut Handle<ColorMaterial>,
Option<&Player>,
)>,
pass_through_filter_query: Query<&PassThroughFilter>,
melty_query: Query<&Melty>,
audio: Res<crossbeam_channel::Sender<AudioMsg>>,
) {
for collision_event in collision_events.iter() {
if let CollisionEvent::Started(e1, e2, flags) = collision_event {
if flags.is_empty() {
if let (Ok((c_color, _c_transform, _c_material, _c_player)), Ok(melty)) =
(character_query.get_mut(*e1), melty_query.get(*e2)) (character_query.get_mut(*e1), melty_query.get(*e2))
{ {
if (Vec4::from(melty.0) - Vec4::from(c_color.0)).max_element() <= 0. { if (Vec4::from(melty.0) - Vec4::from(c_color.0)).max_element() <= 0. {
@ -388,32 +454,6 @@ fn collision_event_system(
.ok(); .ok();
audio.send(AudioMsg::Switch).ok(); audio.send(AudioMsg::Switch).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);
}
} }
} }
} }
@ -458,7 +498,7 @@ 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, &Children), With<Player>>, mut characters: Query<(&mut Velocity, &Children), With<Player>>,
collision_counter_query: Query<&CollisionCount>, airbound_query: Query<&Airbound>,
audio: Res<crossbeam_channel::Sender<AudioMsg>>, audio: Res<crossbeam_channel::Sender<AudioMsg>>,
) { ) {
let right_pressed: bool = let right_pressed: bool =
@ -469,9 +509,8 @@ fn player_movement_system(
for (mut velocity, children) 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) let airbound: &Airbound = airbound_query.get(children[0]).unwrap();
&& collision_counter_query.get(children[0]).unwrap().0 != 0 if keyboard_input.just_pressed(KeyCode::Space) && !airbound.0 {
{
audio.send(AudioMsg::Jump).ok(); audio.send(AudioMsg::Jump).ok();
velocity.linvel.y = 700.; velocity.linvel.y = 700.;
} }