Prevent mid-air jump
This commit is contained in:
parent
e7f2188091
commit
f117b2750a
2 changed files with 102 additions and 59 deletions
|
@ -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
|
||||||
|
|
||||||
|
|
159
src/game.rs
159
src/game.rs
|
@ -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,67 +226,95 @@ 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 {
|
||||||
if flags.is_empty() {
|
CollisionEvent::Started(e1, e2, flags) => {
|
||||||
if let (
|
if flags.is_empty() {
|
||||||
Ok((c1_color, c1_transform, _c1_material, c1_player)),
|
if let (
|
||||||
Ok((c2_color, c2_transform, _c2_material, c2_player)),
|
Ok((c1_color, c1_transform, _c1_material, c1_player)),
|
||||||
) = (character_query.get(*e1), character_query.get(*e2))
|
Ok((c2_color, c2_transform, _c2_material, c2_player)),
|
||||||
{
|
) = (character_query.get(*e1), character_query.get(*e2))
|
||||||
commands.entity(*e1).despawn_recursive();
|
|
||||||
commands.entity(*e2).despawn_recursive();
|
|
||||||
|
|
||||||
let new_color = (Vec4::from(c1_color.0) + Vec4::from(c2_color.0))
|
|
||||||
.clamp(Vec4::ZERO, Vec4::ONE);
|
|
||||||
|
|
||||||
// If color approximately white
|
|
||||||
if app_state.current() == &AppState::Game
|
|
||||||
&& 4. - new_color.length_squared() < 0.1
|
|
||||||
{
|
{
|
||||||
app_state.replace(AppState::Win).ok();
|
commands.entity(*e1).despawn_recursive();
|
||||||
|
commands.entity(*e2).despawn_recursive();
|
||||||
|
|
||||||
|
let new_color = (Vec4::from(c1_color.0) + Vec4::from(c2_color.0))
|
||||||
|
.clamp(Vec4::ZERO, Vec4::ONE);
|
||||||
|
|
||||||
|
// If color approximately white
|
||||||
|
if app_state.current() == &AppState::Game
|
||||||
|
&& 4. - new_color.length_squared() < 0.1
|
||||||
|
{
|
||||||
|
app_state.replace(AppState::Win).ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
// position character based on current player location
|
||||||
|
spawn_character(
|
||||||
|
&mut commands,
|
||||||
|
&character_meshes,
|
||||||
|
&mut materials,
|
||||||
|
&audio,
|
||||||
|
if c1_player.is_some() {
|
||||||
|
*c1_transform
|
||||||
|
} else if c2_player.is_some() {
|
||||||
|
*c2_transform
|
||||||
|
} else {
|
||||||
|
Transform::identity().with_translation(
|
||||||
|
(c1_transform.translation + c2_transform.translation) / 2.,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
new_color.into(),
|
||||||
|
c1_player.is_some() || c2_player.is_some(),
|
||||||
|
);
|
||||||
|
|
||||||
|
audio.send(AudioMsg::Fusion).ok();
|
||||||
}
|
}
|
||||||
|
} else if *flags == CollisionEventFlags::SENSOR {
|
||||||
|
if let (Ok((mut c_color, _c_transform, mut c_material, c_player)), Ok(filter)) = (
|
||||||
|
character_query.get_mut(*e1),
|
||||||
|
pass_through_filter_query.get(*e2),
|
||||||
|
) {
|
||||||
|
c_color.0 = filter.apply(c_color.0);
|
||||||
|
*c_material = materials.add(ColorMaterial::from(c_color.0));
|
||||||
|
|
||||||
// position character based on current player location
|
if c_player.is_some() {
|
||||||
spawn_character(
|
audio
|
||||||
&mut commands,
|
.send(AudioMsg::Color([
|
||||||
&character_meshes,
|
c_color.0.r(),
|
||||||
&mut materials,
|
c_color.0.g(),
|
||||||
&audio,
|
c_color.0.b(),
|
||||||
if c1_player.is_some() {
|
]))
|
||||||
*c1_transform
|
.ok();
|
||||||
} else if c2_player.is_some() {
|
}
|
||||||
*c2_transform
|
} else if let (Ok(mut collision_count), Err(_)) = (
|
||||||
} else {
|
collision_counter_query.get_mut(*e1),
|
||||||
Transform::identity().with_translation(
|
character_query.get_mut(*e2),
|
||||||
(c1_transform.translation + c2_transform.translation) / 2.,
|
) {
|
||||||
)
|
collision_count.0 += 1;
|
||||||
},
|
} else if let (Ok(mut collision_count), Err(_)) = (
|
||||||
new_color.into(),
|
collision_counter_query.get_mut(*e2),
|
||||||
c1_player.is_some() || c2_player.is_some(),
|
character_query.get_mut(*e1),
|
||||||
);
|
) {
|
||||||
|
collision_count.0 += 1;
|
||||||
audio.send(AudioMsg::Fusion).ok();
|
}
|
||||||
}
|
}
|
||||||
} else if *flags == CollisionEventFlags::SENSOR {
|
}
|
||||||
if let (Ok((mut c_color, _c_transform, mut c_material, c_player)), Ok(filter)) = (
|
CollisionEvent::Stopped(e1, e2, flags) => {
|
||||||
character_query.get_mut(*e1),
|
if *flags == CollisionEventFlags::SENSOR {
|
||||||
pass_through_filter_query.get(*e2),
|
if let (Ok(mut collision_count), Err(_)) = (
|
||||||
) {
|
collision_counter_query.get_mut(*e1),
|
||||||
c_color.0 = filter.apply(c_color.0);
|
character_query.get_mut(*e2),
|
||||||
*c_material = materials.add(ColorMaterial::from(c_color.0));
|
) {
|
||||||
|
collision_count.0 = collision_count.0.saturating_sub(1);
|
||||||
if c_player.is_some() {
|
} else if let (Ok(mut collision_count), Err(_)) = (
|
||||||
audio
|
collision_counter_query.get_mut(*e2),
|
||||||
.send(AudioMsg::Color([
|
character_query.get_mut(*e1),
|
||||||
c_color.0.r(),
|
) {
|
||||||
c_color.0.g(),
|
collision_count.0 = collision_count.0.saturating_sub(1);
|
||||||
c_color.0.b(),
|
|
||||||
]))
|
|
||||||
.ok();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue