diff --git a/Cargo.lock b/Cargo.lock index 126b32c..4a6e782 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -923,6 +923,26 @@ dependencies = [ "winit", ] +[[package]] +name = "bevyjam" +version = "0.1.0" +dependencies = [ + "bevy", + "bevy-inspector-egui", + "bevy_common_assets", + "bevy_mod_picking", + "bevy_rapier2d", + "cpal 0.14.0", + "crossbeam-channel", + "hexodsp", + "rand", + "rand_distr", + "rapier2d", + "serde", + "serde_json", + "ticktock", +] + [[package]] name = "bindgen" version = "0.59.2" @@ -1313,7 +1333,6 @@ dependencies = [ "parking_lot 0.12.1", "stdweb", "thiserror", - "wasm-bindgen", "web-sys", "windows", ] @@ -2227,26 +2246,6 @@ dependencies = [ "cfg-if 1.0.0", ] -[[package]] -name = "lux-synthese" -version = "0.1.0" -dependencies = [ - "bevy", - "bevy-inspector-egui", - "bevy_common_assets", - "bevy_mod_picking", - "bevy_rapier2d", - "cpal 0.14.0", - "crossbeam-channel", - "hexodsp", - "rand", - "rand_distr", - "rapier2d", - "serde", - "serde_json", - "ticktock", -] - [[package]] name = "mach" version = "0.3.2" diff --git a/Cargo.toml b/Cargo.toml index fd3c589..3eac3b7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "lux-synthese" +name = "bevyjam" version = "0.1.0" authors = ["tuxmain "] license = "AGPL-3.0-only" @@ -24,7 +24,6 @@ serde_json = "1.0.85" ticktock = "0.8.0" [target."cfg(target_arch = \"wasm32\")".dependencies] -cpal = { version = "0.14.0", features = ["wasm-bindgen"] } [profile.dev.package."*"] opt-level = 3 diff --git a/README.md b/README.md index d46aca3..b53f02d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Lux synthesĕ +# Bevyjam ## Controls @@ -9,14 +9,17 @@ ## TODO +* name * more filters * despawn black characters * despawn character when too far * more levels * (?) multiplayer * more audio +* "jumpable" component to avoid jumping on sensors * bug: in level2, move the blue character to win, then reset. The characters are lighter than expected. (also level 4) * redshift warning +* itchio test ## Build @@ -63,6 +66,6 @@ Edit the level `N: u32` with the command `bevyjam e`. GNU AGPL v3, CopyLeft 2022 Pascal Engélibert, Nixon Cheng -_Lux synthesĕ_ is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, version 3 of the License. -_Lux synthesĕ_ is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. -You should have received a copy of the GNU Affero General Public License along with _Lux synthesĕ_. If not, see https://www.gnu.org/licenses/. +This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, version 3 of the License. +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. +You should have received a copy of the GNU Affero General Public License along with this program. If not, see https://www.gnu.org/licenses/. diff --git a/build-itchio.sh b/build-itchio.sh deleted file mode 100644 index 62759b7..0000000 --- a/build-itchio.sh +++ /dev/null @@ -1,12 +0,0 @@ -sh build-wasm.sh || exit 1 - -mkdir -p target/itchio/wasm/target -mkdir -p target/itchio/wasm/assets - -cp assets/* target/itchio/wasm/assets/ -cp index.html target/itchio/wasm/ -cp target/lux-synthese.js target/itchio/wasm/target/ -cp target/lux-synthese_bg.wasm target/itchio/wasm/target/ - -cd target/itchio/wasm -zip -r ../wasm.zip . diff --git a/build-wasm.sh b/build-wasm.sh index 793798d..0a2d039 100644 --- a/build-wasm.sh +++ b/build-wasm.sh @@ -1,3 +1,3 @@ cargo build --release --target wasm32-unknown-unknown || exit 1 echo "==> wasm-bindgen..." -wasm-bindgen --out-name lux-synthese --out-dir target --target web target/wasm32-unknown-unknown/release/lux-synthese.wasm || exit 1 +wasm-bindgen --out-name bevyjam --out-dir target --target web target/wasm32-unknown-unknown/release/bevyjam.wasm || exit 1 diff --git a/cover.png b/cover.png deleted file mode 100644 index 282923f..0000000 Binary files a/cover.png and /dev/null differ diff --git a/cover.xcf b/cover.xcf deleted file mode 100644 index 9a7f4b5..0000000 Binary files a/cover.xcf and /dev/null differ diff --git a/index.html b/index.html index f36746d..3b956aa 100644 --- a/index.html +++ b/index.html @@ -2,35 +2,12 @@ - Lux synthesĕ + Bevyjam -
-

Lux synthesĕ

-

- Note: audio does not work in the WASM build. -

-

Controls

-
    -
  • Move: Arrows
  • -
  • Switch: Tab
  • -
  • Level up: Enter
  • -
  • Reset: R
  • -
-

Source

-

- The source code of this free software is available in our Git repository. -

-

- GNU AGPL v3: CopyLeft 2022 Pascal Engélibert, Nixon Cheng
- Lux synthesĕ is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, version 3 of the License.
- Lux synthesĕ is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with Lux synthesĕ. If not, see https://www.gnu.org/licenses/. -

-
diff --git a/src/game.rs b/src/game.rs index 0816bfa..b5c803e 100644 --- a/src/game.rs +++ b/src/game.rs @@ -57,13 +57,7 @@ impl Plugin for GamePlugin { .with_system(character_particle_effect_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_platform_collision_event_system) - // collision event system might remove items, therefore, we should detect platforms first before removing them - .add_system_to_stage( - CoreStage::PostUpdate, - collision_event_system.after(char_platform_collision_event_system), - ); + .add_system_to_stage(CoreStage::PostUpdate, collision_event_system); } } @@ -108,28 +102,7 @@ pub struct CharacterColor(pub Color); pub struct Player; #[derive(Component)] -pub struct Platform; - -#[derive(Component)] -pub struct PlatformCount(usize); - -impl PlatformCount { - fn increment(&mut self) { - self.0 += 1; - } - - fn decrement(&mut self) { - self.0 = self.0.saturating_sub(1); - } - - fn reset(&mut self) { - self.0 = 0; - } - - fn is_landed(&self) -> bool { - self.0 != 0 - } -} +pub struct CollisionCount(usize); #[derive(Component)] pub struct Melty(pub Color); @@ -217,7 +190,7 @@ pub fn spawn_character( .insert(Sensor) .insert(Collider::cuboid(30., 0.5)) .insert(ActiveEvents::COLLISION_EVENTS) - .insert(PlatformCount(0)); + .insert(CollisionCount(0)); }); character_list.0.insert(entity_commands.id()); @@ -258,8 +231,7 @@ pub fn spawn_platform( ..default() }) .insert(Collider::cuboid(size.x / 2., size.y / 2.)) - .insert(Level) - .insert(Platform); + .insert(Level); } pub fn spawn_melty_platform( @@ -286,7 +258,6 @@ pub fn spawn_melty_platform( .insert(Collider::cuboid(48., 8.)) .insert(Melty(color)) .insert(Level) - .insert(Platform) .with_children(|c| { c.spawn_bundle(SpriteBundle { texture: asset_server.get_handle("melty.png"), @@ -296,109 +267,9 @@ pub fn spawn_melty_platform( }); } -fn char_char_collision_event_system( - mut commands: Commands, - - mut collision_events: EventReader, - character_query: Query<( - &CharacterColor, - &Transform, - Option<&Player>, - )>, - - mut character_list: ResMut, - mut app_state: ResMut>, - character_meshes: Res, - audio: Res>, - mut materials: ResMut>, -) { - for collision_event in collision_events.iter() { - if let CollisionEvent::Started(e1, e2, _flags) = collision_event { - if let ( - Ok((c1_color, c1_transform, c1_player)), - Ok((c2_color, c2_transform, c2_player)), - ) = (character_query.get(*e1), character_query.get(*e2)) - { - character_list.0.remove(e1); - character_list.0.remove(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 && new_color.min_element() >= 0.9 { - app_state.replace(AppState::Win).ok(); - } - - // position character based on current player location - spawn_character( - &mut commands, - &character_meshes, - &mut materials, - &audio, - &mut character_list, - 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) * 0.5, - ) - }, - new_color.into(), - c1_player.is_some() || c2_player.is_some(), - ); - - audio.send(AudioMsg::Fusion).ok(); - } - } - } -} - -fn char_platform_collision_event_system( - mut collision_events: EventReader, - mut platform_count_query: Query<&mut PlatformCount>, - 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 platform_count), Ok(_)) = - (platform_count_query.get_mut(*e1), platform_query.get(*e2)) - { - platform_count.increment(); - } else if let (Ok(mut platform_count), Ok(_)) = - (platform_count_query.get_mut(*e2), platform_query.get(*e1)) - { - platform_count.increment(); - } - } - } - - CollisionEvent::Stopped(e1, e2, flags) => { - if *flags == CollisionEventFlags::SENSOR { - if let (Ok(mut platform_count), Ok(_)) = - (platform_count_query.get_mut(*e1), platform_query.get(*e2)) - { - platform_count.decrement(); - } else if let (Ok(mut platform_count), Ok(_)) = - (platform_count_query.get_mut(*e2), platform_query.get(*e1)) - { - platform_count.decrement(); - } - } - } - } - } -} - fn collision_event_system( mut commands: Commands, + character_meshes: Res, mut materials: ResMut>, mut collision_events: EventReader, mut character_query: Query<( @@ -409,61 +280,131 @@ fn collision_event_system( )>, pass_through_filter_query: Query<&PassThroughFilter>, melty_query: Query<&Melty>, + mut collision_counter_query: Query<&mut CollisionCount>, + mut app_state: ResMut>, audio: Res>, + mut character_list: ResMut, ) { 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)) - { - if (Vec4::from(melty.0) - Vec4::from(c_color.0)).max_element() <= 0. { - commands.entity(*e2).despawn_recursive(); - } - } else if let (Ok((c_color, _c_transform, _c_material, _c_player)), Ok(melty)) = - (character_query.get_mut(*e2), melty_query.get(*e1)) - { - if (Vec4::from(melty.0) - Vec4::from(c_color.0)).max_element() <= 0. { + match collision_event { + CollisionEvent::Started(e1, e2, flags) => { + if flags.is_empty() { + if let ( + Ok((c1_color, c1_transform, _c1_material, c1_player)), + Ok((c2_color, c2_transform, _c2_material, c2_player)), + ) = (character_query.get(*e1), character_query.get(*e2)) + { + character_list.0.remove(e1); + character_list.0.remove(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 && new_color.min_element() >= 0.9 + { + app_state.replace(AppState::Win).ok(); + } + + // position character based on current player location + spawn_character( + &mut commands, + &character_meshes, + &mut materials, + &audio, + &mut character_list, + 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 let (Ok((c_color, _c_transform, _c_material, _c_player)), Ok(melty)) = + (character_query.get_mut(*e1), melty_query.get(*e2)) + { + if (Vec4::from(melty.0) - Vec4::from(c_color.0)).max_element() <= 0. { + commands.entity(*e2).despawn_recursive(); + } + } else if let (Ok((c_color, _c_transform, _c_material, _c_player)), Ok(melty)) = + (character_query.get_mut(*e2), melty_query.get(*e1)) + { + if (Vec4::from(melty.0) - Vec4::from(c_color.0)).max_element() <= 0. { + commands.entity(*e1).despawn_recursive(); + } + } + } 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)); + + if c_player.is_some() { + audio + .send(AudioMsg::Color([ + c_color.0.r(), + c_color.0.g(), + c_color.0.b(), + ])) + .ok(); + audio.send(AudioMsg::Switch).ok(); + } + } else if let ( + Ok((mut c_color, _c_transform, mut c_material, c_player)), + Ok(filter), + ) = ( + character_query.get_mut(*e2), + pass_through_filter_query.get(*e1), + ) { + c_color.0 = filter.apply(c_color.0); + *c_material = materials.add(ColorMaterial::from(c_color.0)); + + if c_player.is_some() { + audio + .send(AudioMsg::Color([ + c_color.0.r(), + c_color.0.g(), + c_color.0.b(), + ])) + .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; } } - } 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)); - - if c_player.is_some() { - audio - .send(AudioMsg::Color([ - c_color.0.r(), - c_color.0.g(), - c_color.0.b(), - ])) - .ok(); - audio.send(AudioMsg::Switch).ok(); - } - } else if let ( - Ok((mut c_color, _c_transform, mut c_material, c_player)), - Ok(filter), - ) = ( - character_query.get_mut(*e2), - pass_through_filter_query.get(*e1), - ) { - c_color.0 = filter.apply(c_color.0); - *c_material = materials.add(ColorMaterial::from(c_color.0)); - - if c_player.is_some() { - audio - .send(AudioMsg::Color([ - c_color.0.r(), - c_color.0.g(), - c_color.0.b(), - ])) - .ok(); - audio.send(AudioMsg::Switch).ok(); + } + 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); } } } @@ -509,7 +450,7 @@ fn change_character_system( fn player_movement_system( keyboard_input: Res>, mut characters: Query<(&mut Velocity, &Children), With>, - mut platform_count_query: Query<&mut PlatformCount>, + collision_counter_query: Query<&CollisionCount>, audio: Res>, ) { let right_pressed: bool = @@ -520,12 +461,11 @@ fn player_movement_system( for (mut velocity, children) in characters.iter_mut() { velocity.linvel.x = 200. * (right_pressed as i8 - left_pressed as i8) as f32; - let mut platform_count: Mut = - platform_count_query.get_mut(children[0]).unwrap(); - if keyboard_input.just_pressed(KeyCode::Space) && platform_count.is_landed() { + if keyboard_input.just_pressed(KeyCode::Space) + && collision_counter_query.get(children[0]).unwrap().0 != 0 + { audio.send(AudioMsg::Jump).ok(); velocity.linvel.y = 700.; - platform_count.reset(); } } } diff --git a/src/menu.rs b/src/menu.rs index 0fd8a8f..f35f024 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -39,7 +39,7 @@ fn setup(mut commands: Commands, asset_server: Res) { commands .spawn_bundle(Text2dBundle { text: Text::from_section( - "Lux synthesĕ", + "BEVYJAM", TextStyle { font: font.clone(), font_size: 96.0, diff --git a/src/particle_effect.rs b/src/particle_effect.rs index 146ac73..26e275a 100644 --- a/src/particle_effect.rs +++ b/src/particle_effect.rs @@ -143,6 +143,5 @@ fn particle_effect_system( / particle_effect.radius_squared, ); } - transform.translation.z = 0.005; } }