Compare commits

...

15 commits

17 changed files with 172 additions and 276 deletions

176
Cargo.lock generated
View file

@ -899,7 +899,7 @@ dependencies = [
"bevy_input", "bevy_input",
"bevy_math", "bevy_math",
"bevy_utils", "bevy_utils",
"raw-window-handle 0.4.3", "raw-window-handle",
"web-sys", "web-sys",
] ]
@ -917,7 +917,7 @@ dependencies = [
"bevy_utils", "bevy_utils",
"bevy_window", "bevy_window",
"crossbeam-channel", "crossbeam-channel",
"raw-window-handle 0.4.3", "raw-window-handle",
"wasm-bindgen", "wasm-bindgen",
"web-sys", "web-sys",
"winit", "winit",
@ -1292,31 +1292,6 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "cpal"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d466b47cf0ea4100186a7c12d7d0166813dda7cf648553554c9c39c6324841b"
dependencies = [
"alsa",
"core-foundation-sys 0.8.3",
"coreaudio-rs",
"jni",
"js-sys",
"libc",
"mach",
"ndk 0.7.0",
"ndk-context",
"nix 0.23.1",
"oboe",
"once_cell",
"parking_lot 0.12.1",
"stdweb",
"thiserror",
"web-sys",
"windows",
]
[[package]] [[package]]
name = "crc32fast" name = "crc32fast"
version = "1.3.2" version = "1.3.2"
@ -1939,26 +1914,6 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
[[package]]
name = "hexodsp"
version = "0.2.0"
source = "git+https://github.com/WeirdConstructor/HexoDSP#be4e9232cc05b96588b156d1c9f995f7eda41ec0"
dependencies = [
"hound",
"lazy_static",
"ringbuf",
"serde",
"serde_json",
"synfx-dsp",
"triple_buffer",
]
[[package]]
name = "hound"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a164bb2ceaeff4f42542bdb847c41517c78a60f5649671b2a07312b6e117549"
[[package]] [[package]]
name = "ident_case" name = "ident_case"
version = "1.0.1" version = "1.0.1"
@ -2209,9 +2164,9 @@ dependencies = [
[[package]] [[package]]
name = "lock_api" name = "lock_api"
version = "0.4.7" version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" checksum = "9f80bf5aacaf25cbfc8210d1cfb718f2bf3b11c4c54e5afe36c236853a8ec390"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"scopeguard", "scopeguard",
@ -2235,9 +2190,7 @@ dependencies = [
"bevy_common_assets", "bevy_common_assets",
"bevy_mod_picking", "bevy_mod_picking",
"bevy_rapier2d", "bevy_rapier2d",
"cpal 0.14.0",
"crossbeam-channel", "crossbeam-channel",
"hexodsp",
"rand", "rand",
"rand_distr", "rand_distr",
"rapier2d", "rapier2d",
@ -2439,20 +2392,6 @@ dependencies = [
"thiserror", "thiserror",
] ]
[[package]]
name = "ndk"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0"
dependencies = [
"bitflags",
"jni-sys",
"ndk-sys 0.4.0",
"num_enum",
"raw-window-handle 0.5.0",
"thiserror",
]
[[package]] [[package]]
name = "ndk-context" name = "ndk-context"
version = "0.1.1" version = "0.1.1"
@ -2518,15 +2457,6 @@ dependencies = [
"jni-sys", "jni-sys",
] ]
[[package]]
name = "ndk-sys"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21d83ec9c63ec5bf950200a8e508bdad6659972187b625469f58ef8c08e29046"
dependencies = [
"jni-sys",
]
[[package]] [[package]]
name = "nix" name = "nix"
version = "0.22.3" version = "0.22.3"
@ -3070,15 +3000,6 @@ dependencies = [
"cty", "cty",
] ]
[[package]]
name = "raw-window-handle"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed7e3d950b66e19e0c372f3fa3fbbcf85b1746b571f74e0c2af6042a5c93420a"
dependencies = [
"cty",
]
[[package]] [[package]]
name = "rawpointer" name = "rawpointer"
version = "0.2.1" version = "0.2.1"
@ -3132,15 +3053,6 @@ version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1382d1f0a252c4bf97dc20d979a2fdd05b024acd7c2ed0f7595d7817666a157" checksum = "f1382d1f0a252c4bf97dc20d979a2fdd05b024acd7c2ed0f7595d7817666a157"
[[package]]
name = "ringbuf"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f65af18d50f789e74aaf23bbb3f65dcd22a3cb6e029b5bced149f6bd57c5c2a2"
dependencies = [
"cache-padded",
]
[[package]] [[package]]
name = "robust" name = "robust"
version = "0.2.3" version = "0.2.3"
@ -3153,7 +3065,7 @@ version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0939e9f626e6c6f1989adb6226a039c855ca483053f0ee7c98b90e41cf731e" checksum = "ec0939e9f626e6c6f1989adb6226a039c855ca483053f0ee7c98b90e41cf731e"
dependencies = [ dependencies = [
"cpal 0.13.5", "cpal",
"lewton", "lewton",
] ]
@ -3364,14 +3276,6 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "synfx-dsp"
version = "0.5.3"
source = "git+https://github.com/WeirdConstructor/synfx-dsp#3334a91ee48c009707c0147434a3fc14a929c079"
dependencies = [
"num-traits",
]
[[package]] [[package]]
name = "taffy" name = "taffy"
version = "0.1.0" version = "0.1.0"
@ -3537,15 +3441,6 @@ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]]
name = "triple_buffer"
version = "5.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "803966e5a8397a70d3d8111afa1597ba8381346d7de4720e9f539471d371a1a3"
dependencies = [
"cache-padded",
]
[[package]] [[package]]
name = "ttf-parser" name = "ttf-parser"
version = "0.15.2" version = "0.15.2"
@ -3760,7 +3655,7 @@ dependencies = [
"log", "log",
"naga", "naga",
"parking_lot 0.12.1", "parking_lot 0.12.1",
"raw-window-handle 0.4.3", "raw-window-handle",
"smallvec", "smallvec",
"wasm-bindgen", "wasm-bindgen",
"wasm-bindgen-futures", "wasm-bindgen-futures",
@ -3786,7 +3681,7 @@ dependencies = [
"naga", "naga",
"parking_lot 0.12.1", "parking_lot 0.12.1",
"profiling", "profiling",
"raw-window-handle 0.4.3", "raw-window-handle",
"smallvec", "smallvec",
"thiserror", "thiserror",
"web-sys", "web-sys",
@ -3823,7 +3718,7 @@ dependencies = [
"parking_lot 0.12.1", "parking_lot 0.12.1",
"profiling", "profiling",
"range-alloc", "range-alloc",
"raw-window-handle 0.4.3", "raw-window-handle",
"renderdoc-sys", "renderdoc-sys",
"thiserror", "thiserror",
"wasm-bindgen", "wasm-bindgen",
@ -3896,30 +3791,17 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows"
version = "0.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57b543186b344cc61c85b5aab0d2e3adf4e0f99bc076eff9aa5927bcc0b8a647"
dependencies = [
"windows_aarch64_msvc 0.37.0",
"windows_i686_gnu 0.37.0",
"windows_i686_msvc 0.37.0",
"windows_x86_64_gnu 0.37.0",
"windows_x86_64_msvc 0.37.0",
]
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.36.1" version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
dependencies = [ dependencies = [
"windows_aarch64_msvc 0.36.1", "windows_aarch64_msvc",
"windows_i686_gnu 0.36.1", "windows_i686_gnu",
"windows_i686_msvc 0.36.1", "windows_i686_msvc",
"windows_x86_64_gnu 0.36.1", "windows_x86_64_gnu",
"windows_x86_64_msvc 0.36.1", "windows_x86_64_msvc",
] ]
[[package]] [[package]]
@ -3928,60 +3810,30 @@ version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
[[package]]
name = "windows_aarch64_msvc"
version = "0.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2623277cb2d1c216ba3b578c0f3cf9cdebeddb6e66b1b218bb33596ea7769c3a"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
version = "0.36.1" version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
[[package]]
name = "windows_i686_gnu"
version = "0.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3925fd0b0b804730d44d4b6278c50f9699703ec49bcd628020f46f4ba07d9e1"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
version = "0.36.1" version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
[[package]]
name = "windows_i686_msvc"
version = "0.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce907ac74fe331b524c1298683efbf598bb031bc84d5e274db2083696d07c57c"
[[package]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
version = "0.36.1" version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
[[package]]
name = "windows_x86_64_gnu"
version = "0.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2babfba0828f2e6b32457d5341427dcbb577ceef556273229959ac23a10af33d"
[[package]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"
version = "0.36.1" version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
[[package]]
name = "windows_x86_64_msvc"
version = "0.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4dd6dc7df2d84cf7b33822ed5b86318fb1781948e9663bacd047fc9dd52259d"
[[package]] [[package]]
name = "winit" name = "winit"
version = "0.26.1" version = "0.26.1"
@ -4005,7 +3857,7 @@ dependencies = [
"objc", "objc",
"parking_lot 0.11.2", "parking_lot 0.11.2",
"percent-encoding", "percent-encoding",
"raw-window-handle 0.4.3", "raw-window-handle",
"wasm-bindgen", "wasm-bindgen",
"web-sys", "web-sys",
"winapi", "winapi",

View file

@ -18,13 +18,13 @@ serde = { version = "1.0.144", features = ["derive"] }
[target."cfg(not(target_arch = \"wasm32\"))".dependencies] [target."cfg(not(target_arch = \"wasm32\"))".dependencies]
bevy-inspector-egui = "0.12.1" bevy-inspector-egui = "0.12.1"
bevy_mod_picking = "0.9.0" bevy_mod_picking = "0.9.0"
cpal = "0.14.0" # cpal = "0.14.0"
hexodsp = { git = "https://github.com/WeirdConstructor/HexoDSP", default-features = false } # hexodsp = { git = "https://github.com/WeirdConstructor/HexoDSP", default-features = false }
serde_json = "1.0.85" serde_json = "1.0.85"
ticktock = "0.8.0" ticktock = "0.8.0"
[target."cfg(target_arch = \"wasm32\")".dependencies] [target."cfg(target_arch = \"wasm32\")".dependencies]
#cpal = { version = "0.14.0", features = ["wasm-bindgen"] } # cpal = { version = "0.14.0", features = ["wasm-bindgen"] }
[profile.dev.package."*"] [profile.dev.package."*"]
opt-level = 3 opt-level = 3

BIN
assets/sound/notes.flp Normal file

Binary file not shown.

BIN
assets/sound/notes/a5.ogg Normal file

Binary file not shown.

BIN
assets/sound/notes/cs6.ogg Normal file

Binary file not shown.

BIN
assets/sound/notes/e6.ogg Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,5 +1,6 @@
// https://github.com/WeirdConstructor/HexoDSP/blob/master/examples/cpal_demo_node_api.rs // https://github.com/WeirdConstructor/HexoDSP/blob/master/examples/cpal_demo_node_api.rs
// use bevy::{prelude::*, asset::HandleId};
use crate::game::AudioMsg; use crate::game::AudioMsg;
use cpal::traits::{DeviceTrait, HostTrait, StreamTrait}; use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
@ -163,4 +164,4 @@ fn start_backend<F: FnMut()>(node_exec: NodeExecutor, frontend_loop: F) {
cpal::SampleFormat::I16 => run::<i16, F>(&device, &config.into(), node_exec, frontend_loop), cpal::SampleFormat::I16 => run::<i16, F>(&device, &config.into(), node_exec, frontend_loop),
cpal::SampleFormat::U16 => run::<u16, F>(&device, &config.into(), node_exec, frontend_loop), cpal::SampleFormat::U16 => run::<u16, F>(&device, &config.into(), node_exec, frontend_loop),
}; };
} }

49
src/audio_system.rs Normal file
View file

@ -0,0 +1,49 @@
use bevy::prelude::*;
pub struct AudioSystemPlugin;
impl Plugin for AudioSystemPlugin {
fn build(&self, app: &mut App) {
app
.init_resource::<AudioAssets>()
.add_startup_system(load_audio);
}
}
#[derive(Default)]
pub struct AudioAssets {
pub notes: [Handle<AudioSource>; 3],
pub reverb_notes: [Handle<AudioSource>; 3],
pub warp_notes: [Handle<AudioSource>; 3],
}
pub fn play_audio(
audio_set: &[Handle<AudioSource>; 3],
audio: &Res<Audio>,
color: Vec4,
volume: f32,
) {
for i in 0 .. 3 {
audio.play_with_settings(
audio_set[i].clone(),
PlaybackSettings::ONCE.with_volume(color[i] * volume)
);
}
}
fn load_audio(
mut audio_assets: ResMut<AudioAssets>,
asset_server: Res<AssetServer>,
) {
audio_assets.notes[0] = asset_server.load::<AudioSource, &str>("sound/notes/a5.ogg");
audio_assets.notes[1] = asset_server.load::<AudioSource, &str>("sound/notes/cs6.ogg");
audio_assets.notes[2] = asset_server.load::<AudioSource, &str>("sound/notes/e6.ogg");
audio_assets.reverb_notes[0] = asset_server.load::<AudioSource, &str>("sound/reverb_notes/a5.ogg");
audio_assets.reverb_notes[1] = asset_server.load::<AudioSource, &str>("sound/reverb_notes/cs6.ogg");
audio_assets.reverb_notes[2] = asset_server.load::<AudioSource, &str>("sound/reverb_notes/e6.ogg");
audio_assets.warp_notes[0] = asset_server.load::<AudioSource, &str>("sound/warp_notes/a5.ogg");
audio_assets.warp_notes[1] = asset_server.load::<AudioSource, &str>("sound/warp_notes/cs6.ogg");
audio_assets.warp_notes[2] = asset_server.load::<AudioSource, &str>("sound/warp_notes/e6.ogg");
}

View file

@ -2,8 +2,8 @@
#![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_arguments)]
pub use crate::filters::*; pub use crate::filters::*;
use crate::{AppState, audio_system};
use crate::AppState; use crate::levels;
use bevy::{ use bevy::{
ecs::system::EntityCommands, ecs::system::EntityCommands,
@ -15,13 +15,6 @@ use bevy_rapier2d::prelude::*;
use rapier2d::geometry::CollisionEventFlags; use rapier2d::geometry::CollisionEventFlags;
use std::collections::BTreeSet; use std::collections::BTreeSet;
pub enum AudioMsg {
Color([f32; 3]),
Fusion,
Jump,
Switch,
}
pub struct FirstLevel(pub LevelId); pub struct FirstLevel(pub LevelId);
#[derive(Clone, Copy, Eq, Hash, PartialEq)] #[derive(Clone, Copy, Eq, Hash, PartialEq)]
@ -35,6 +28,7 @@ impl Plugin for GamePlugin {
.init_resource::<CharacterMeshes>() .init_resource::<CharacterMeshes>()
.insert_resource(CurrentLevel(None)) .insert_resource(CurrentLevel(None))
.init_resource::<CharacterList>() .init_resource::<CharacterList>()
.init_resource::<levels::ZoomTimer>()
.add_system_set(SystemSet::on_enter(AppState::Game).with_system(setup)) .add_system_set(SystemSet::on_enter(AppState::Game).with_system(setup))
.add_system_set(SystemSet::on_enter(AppState::Win).with_system(win_setup)) .add_system_set(SystemSet::on_enter(AppState::Win).with_system(win_setup))
.add_system_set( .add_system_set(
@ -46,14 +40,14 @@ impl Plugin for GamePlugin {
.with_system(change_character_system) .with_system(change_character_system)
.with_system(player_movement_system) .with_system(player_movement_system)
.with_system(level_keyboard_system) .with_system(level_keyboard_system)
.with_system(move_camera) .with_system(camera_system)
.with_system(character_particle_effect_system), .with_system(character_particle_effect_system),
) )
.add_system_set( .add_system_set(
SystemSet::on_update(AppState::Win) SystemSet::on_update(AppState::Win)
.with_system(player_movement_system) .with_system(player_movement_system)
.with_system(level_keyboard_system) .with_system(level_keyboard_system)
.with_system(move_camera) .with_system(camera_system)
.with_system(character_particle_effect_system) .with_system(character_particle_effect_system)
.with_system(move_win_text_system), .with_system(move_win_text_system),
) )
@ -144,34 +138,41 @@ fn setup(
mut current_level: ResMut<CurrentLevel>, mut current_level: ResMut<CurrentLevel>,
mut level_startup_event: EventWriter<LevelStartupEvent>, mut level_startup_event: EventWriter<LevelStartupEvent>,
mut camera_query: Query<&mut Transform, With<Camera>>, mut camera_query: Query<&mut Transform, With<Camera>>,
mut zoom_timer: ResMut<levels::ZoomTimer>,
) { ) {
if current_level.0.is_none() { if current_level.0.is_none() {
current_level.0 = Some(first_level.0); current_level.0 = Some(first_level.0);
} }
crate::levels::setup_level(&mut level_startup_event, &mut camera_query); crate::levels::setup_level(&mut level_startup_event, &mut camera_query, &mut zoom_timer);
} }
pub fn spawn_characters<I: IntoIterator<Item = (Transform, Color)>>( pub fn spawn_characters<I: IntoIterator<Item = (Transform, Color)>>(
commands: &mut Commands, commands: &mut Commands,
character_meshes: &Res<CharacterMeshes>, character_meshes: &Res<CharacterMeshes>,
materials: &mut ResMut<Assets<ColorMaterial>>, materials: &mut ResMut<Assets<ColorMaterial>>,
audio: &Res<crossbeam_channel::Sender<AudioMsg>>,
character_list: &mut ResMut<CharacterList>, character_list: &mut ResMut<CharacterList>,
characters: I, characters: I,
) { ) {
const Z_INCREMENT: f32 = 0.01;
let mut curr_z: f32 = Z_INCREMENT;
for (i, (transform, color)) in characters.into_iter().enumerate() { for (i, (transform, color)) in characters.into_iter().enumerate() {
spawn_character( spawn_character(
commands, commands,
character_meshes, character_meshes,
materials, materials,
audio,
character_list, character_list,
transform, {
let mut new_transform: Transform = transform;
new_transform.translation.z = curr_z;
new_transform
},
color, color,
i == 0, i == 0,
); );
curr_z += Z_INCREMENT;
} }
} }
@ -179,7 +180,6 @@ pub fn spawn_character(
commands: &mut Commands, commands: &mut Commands,
character_meshes: &Res<CharacterMeshes>, character_meshes: &Res<CharacterMeshes>,
materials: &mut ResMut<Assets<ColorMaterial>>, materials: &mut ResMut<Assets<ColorMaterial>>,
audio: &Res<crossbeam_channel::Sender<AudioMsg>>,
character_list: &mut ResMut<CharacterList>, character_list: &mut ResMut<CharacterList>,
mut transform: Transform, mut transform: Transform,
color: Color, color: Color,
@ -224,9 +224,6 @@ pub fn spawn_character(
if is_player { if is_player {
entity_commands.insert(Player); entity_commands.insert(Player);
audio
.send(AudioMsg::Color([color.r(), color.g(), color.b()]))
.ok();
} }
} }
@ -305,16 +302,16 @@ fn char_char_collision_event_system(
mut character_list: ResMut<CharacterList>, mut character_list: ResMut<CharacterList>,
mut app_state: ResMut<State<AppState>>, mut app_state: ResMut<State<AppState>>,
character_meshes: Res<CharacterMeshes>, character_meshes: Res<CharacterMeshes>,
audio: Res<crossbeam_channel::Sender<AudioMsg>>,
mut materials: ResMut<Assets<ColorMaterial>>, mut materials: ResMut<Assets<ColorMaterial>>,
audio_assets: Res<audio_system::AudioAssets>,
audio: Res<Audio>,
) { ) {
for collision_event in collision_events.iter() { for collision_event in collision_events.iter() {
if let CollisionEvent::Started(e1, e2, _flags) = collision_event { if let CollisionEvent::Started(e1, e2, _flags) = collision_event {
if let ( if let (
Ok((c1_color, c1_transform, c1_player)), Ok((c1_color, c1_transform, c1_player)),
Ok((c2_color, c2_transform, c2_player)), Ok((c2_color, c2_transform, 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();
@ -333,7 +330,6 @@ fn char_char_collision_event_system(
&mut commands, &mut commands,
&character_meshes, &character_meshes,
&mut materials, &mut materials,
&audio,
&mut character_list, &mut character_list,
if c1_player.is_some() { if c1_player.is_some() {
*c1_transform *c1_transform
@ -348,7 +344,7 @@ fn char_char_collision_event_system(
c1_player.is_some() || c2_player.is_some(), c1_player.is_some() || c2_player.is_some(),
); );
audio.send(AudioMsg::Fusion).ok(); audio_system::play_audio(&audio_assets.warp_notes, &audio, new_color.into(), 1.0);
} }
} }
} }
@ -405,64 +401,42 @@ fn collision_event_system(
)>, )>,
pass_through_filter_query: Query<&PassThroughFilter>, pass_through_filter_query: Query<&PassThroughFilter>,
melty_query: Query<&Melty>, melty_query: Query<&Melty>,
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 { if let CollisionEvent::Started(e1, e2, flags) = collision_event {
if flags.is_empty() { if flags.is_empty() {
if let (Ok((c_color, _c_transform, _c_material, _c_player)), Ok(melty)) = 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. {
commands.entity(*e2).despawn_recursive(); commands.entity(*e2).despawn_recursive();
} }
} else if let (Ok((c_color, _c_transform, _c_material, _c_player)), Ok(melty)) = } else if let (Ok((c_color, _c_transform, _c_material, _c_player)), Ok(melty)) =
(character_query.get_mut(*e2), melty_query.get(*e1)) (character_query.get_mut(*e2), melty_query.get(*e1))
{ {
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. {
commands.entity(*e1).despawn_recursive(); commands.entity(*e1).despawn_recursive();
} }
} }
} else if *flags == CollisionEventFlags::SENSOR { } else if *flags == CollisionEventFlags::SENSOR {
if let (Ok((mut c_color, _c_transform, mut c_material, c_player)), Ok(filter)) = ( if let (Ok((mut c_color, _c_transform, mut c_material, _c_player)), Ok(filter)) = (
character_query.get_mut(*e1), character_query.get_mut(*e1),
pass_through_filter_query.get(*e2), pass_through_filter_query.get(*e2),
) { ) {
c_color.0 = filter.apply(c_color.0); c_color.0 = filter.apply(c_color.0);
*c_material = materials.add(ColorMaterial::from(c_color.0)); *c_material = materials.add(ColorMaterial::from(c_color.0));
if c_player.is_some() { } else if let (
audio Ok((mut c_color, _c_transform, mut c_material, _c_player)),
.send(AudioMsg::Color([ Ok(filter),
c_color.0.r(), ) = (
c_color.0.g(), character_query.get_mut(*e2),
c_color.0.b(), pass_through_filter_query.get(*e1),
])) ) {
.ok(); c_color.0 = filter.apply(c_color.0);
audio.send(AudioMsg::Switch).ok(); *c_material = materials.add(ColorMaterial::from(c_color.0));
} }
} 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();
}
}
}
} }
} }
} }
@ -472,8 +446,9 @@ fn change_character_system(
keyboard_input: Res<Input<KeyCode>>, keyboard_input: Res<Input<KeyCode>>,
characters: Query<(Entity, &CharacterColor, Option<&Player>)>, characters: Query<(Entity, &CharacterColor, Option<&Player>)>,
audio: Res<crossbeam_channel::Sender<AudioMsg>>,
character_list: Res<CharacterList>, character_list: Res<CharacterList>,
audio_assets: Res<audio_system::AudioAssets>,
audio: Res<Audio>,
) { ) {
if !keyboard_input.just_pressed(KeyCode::Tab) { if !keyboard_input.just_pressed(KeyCode::Tab) {
return; return;
@ -493,10 +468,7 @@ fn change_character_system(
{ {
commands.entity(*new_player_entity).insert(Player); commands.entity(*new_player_entity).insert(Player);
if let Ok((_entity, color, _player)) = characters.get(*new_player_entity) { if let Ok((_entity, color, _player)) = characters.get(*new_player_entity) {
audio audio_system::play_audio(&audio_assets.reverb_notes, &audio, color.0.into(), 1.0);
.send(AudioMsg::Color([color.0.r(), color.0.g(), color.0.b()]))
.ok();
audio.send(AudioMsg::Switch).ok();
} }
} }
} }
@ -504,22 +476,22 @@ 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, &CharacterColor), With<Player>>,
mut platform_count_query: Query<&mut PlatformCount>, mut platform_count_query: Query<&mut PlatformCount>,
audio: Res<crossbeam_channel::Sender<AudioMsg>>, audio_assets: Res<audio_system::AudioAssets>,
audio: Res<Audio>,
) { ) {
let right_pressed: bool = let right_pressed: bool =
keyboard_input.pressed(KeyCode::Right) || keyboard_input.pressed(KeyCode::D); keyboard_input.pressed(KeyCode::Right) || keyboard_input.pressed(KeyCode::D);
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, children) in characters.iter_mut() { for (mut velocity, children, color) 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;
let mut platform_count: Mut<PlatformCount> = let mut platform_count: Mut<PlatformCount> = platform_count_query.get_mut(children[0]).unwrap();
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) && platform_count.is_landed() {
audio.send(AudioMsg::Jump).ok(); audio_system::play_audio(&audio_assets.notes, &audio, color.0.into(), 0.5);
velocity.linvel.y = 700.; velocity.linvel.y = 700.;
platform_count.reset(); platform_count.reset();
} }
@ -575,16 +547,22 @@ fn win_setup(
.insert(WinText); .insert(WinText);
} }
fn move_camera( fn camera_system(
mut camera_query: Query<(&Camera, &mut Transform)>, mut camera_query: Query<(&Camera, &mut OrthographicProjection, &mut Transform)>,
characters: Query<&Transform, (Without<Camera>, With<Player>)>, characters: Query<&Transform, (Without<Camera>, With<Player>)>,
time: Res<Time>, time: Res<Time>,
mut zoom_timer: ResMut<levels::ZoomTimer>,
) { ) {
fn lerp(x: f32, y: f32, t: f32,) -> f32 {
return ((y - x) * t) + x;
}
const MARGIN: f32 = 300.0; const MARGIN: f32 = 300.0;
const FOLLOW_SPEED: f32 = std::f32::consts::PI; const FOLLOW_SPEED: f32 = std::f32::consts::PI;
const ZOOM_SPEED: f32 = std::f32::consts::E;
for character_transform in characters.iter() { for character_transform in characters.iter() {
let (camera, mut camera_transform) = camera_query.single_mut(); let (camera, mut projection, mut camera_transform) = camera_query.single_mut();
let size: Vec2 = camera.logical_viewport_size().unwrap(); let size: Vec2 = camera.logical_viewport_size().unwrap();
let half_height: f32 = size.y * 0.5; let half_height: f32 = size.y * 0.5;
@ -596,6 +574,14 @@ fn move_camera(
.translation .translation
.lerp(target_translation, time.delta_seconds() * FOLLOW_SPEED); .lerp(target_translation, time.delta_seconds() * FOLLOW_SPEED);
if zoom_timer.0.finished() {
projection.scale = lerp(projection.scale, 1.0, time.delta_seconds() * ZOOM_SPEED);
} else {
projection.scale = 3.0;
camera_transform.translation = Vec3::ZERO;
zoom_timer.0.tick(time.delta());
}
// always make sure that camera is away from the object in order to render them // always make sure that camera is away from the object in order to render them
camera_transform.translation.z = 999.0; camera_transform.translation.z = 999.0;
} }
@ -621,6 +607,7 @@ fn level_keyboard_system(
mut character_list: ResMut<CharacterList>, mut character_list: ResMut<CharacterList>,
level_query: Query<Entity, With<Level>>, level_query: Query<Entity, With<Level>>,
mut app_state: ResMut<State<AppState>>, mut app_state: ResMut<State<AppState>>,
mut zoom_timer: ResMut<levels::ZoomTimer>,
) { ) {
if app_state.current() == &AppState::Win && keyboard_input.just_pressed(KeyCode::Return) { if app_state.current() == &AppState::Win && keyboard_input.just_pressed(KeyCode::Return) {
current_level.0 = Some(LevelId( current_level.0 = Some(LevelId(
@ -635,7 +622,7 @@ fn level_keyboard_system(
commands.entity(entity).despawn_recursive(); commands.entity(entity).despawn_recursive();
} }
if app_state.replace(AppState::Game).is_err() { if app_state.replace(AppState::Game).is_err() {
crate::levels::setup_level(&mut level_startup_event, &mut camera_query); crate::levels::setup_level(&mut level_startup_event, &mut camera_query, &mut zoom_timer);
} }
} }
} }

View file

@ -1,5 +1,7 @@
#![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_arguments)]
use std::time::Duration;
pub use stored::*; pub use stored::*;
use crate::game::*; use crate::game::*;
@ -7,11 +9,26 @@ use crate::game::*;
use bevy::{prelude::*, reflect::TypeUuid}; use bevy::{prelude::*, reflect::TypeUuid};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Component)]
pub struct ZoomTimer(pub Timer);
impl Default for ZoomTimer {
fn default() -> Self {
Self {
0: Timer::new(Duration::new(2, 0), false),
}
}
}
pub fn setup_level( pub fn setup_level(
level_startup_event: &mut EventWriter<LevelStartupEvent>, level_startup_event: &mut EventWriter<LevelStartupEvent>,
camera_query: &mut Query<&mut Transform, With<Camera>>, camera_query: &mut Query<&mut Transform, With<Camera>>,
zoom_timer: &mut ResMut<ZoomTimer>,
) { ) {
camera_query.single_mut().translation = Default::default(); let mut transform = camera_query.single_mut();
transform.translation = Default::default();
zoom_timer.0.reset();
level_startup_event.send(LevelStartupEvent); level_startup_event.send(LevelStartupEvent);
} }
@ -36,7 +53,6 @@ pub fn post_setup_level(
current_level: Res<CurrentLevel>, current_level: Res<CurrentLevel>,
mut level_startup_event: EventReader<LevelStartupEvent>, mut level_startup_event: EventReader<LevelStartupEvent>,
asset_server: Res<AssetServer>, asset_server: Res<AssetServer>,
audio: Res<crossbeam_channel::Sender<AudioMsg>>,
mut character_list: ResMut<CharacterList>, mut character_list: ResMut<CharacterList>,
stored_levels_assets: Res<Assets<StoredLevels>>, stored_levels_assets: Res<Assets<StoredLevels>>,
stored_levels_handle: Res<Handle<StoredLevels>>, stored_levels_handle: Res<Handle<StoredLevels>>,
@ -55,7 +71,6 @@ pub fn post_setup_level(
&mut meshes, &mut meshes,
&mut materials, &mut materials,
&asset_server, &asset_server,
&audio,
&mut character_list, &mut character_list,
stored_level, stored_level,
); );
@ -70,7 +85,6 @@ pub fn spawn_stored_level(
meshes: &mut ResMut<Assets<Mesh>>, meshes: &mut ResMut<Assets<Mesh>>,
materials: &mut ResMut<Assets<ColorMaterial>>, materials: &mut ResMut<Assets<ColorMaterial>>,
asset_server: &Res<AssetServer>, asset_server: &Res<AssetServer>,
audio: &Res<crossbeam_channel::Sender<AudioMsg>>,
character_list: &mut ResMut<CharacterList>, character_list: &mut ResMut<CharacterList>,
stored_level: &StoredLevel, stored_level: &StoredLevel,
@ -91,7 +105,6 @@ pub fn spawn_stored_level(
commands, commands,
character_meshes, character_meshes,
materials, materials,
audio,
character_list, character_list,
stored_level.characters.iter().map(|character| { stored_level.characters.iter().map(|character| {
( (

View file

@ -1,14 +1,14 @@
#![allow(clippy::too_many_arguments)] #![allow(clippy::too_many_arguments)]
#[cfg(not(target_arch = "wasm32"))]
mod audio;
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
mod editor; mod editor;
mod filters; mod filters;
mod game; mod game;
mod levels; mod levels;
mod menu; mod menu;
mod particle_effect; mod particle_effect;
mod audio_system;
use bevy::{ use bevy::{
asset::{Asset, HandleId, LoadState}, asset::{Asset, HandleId, LoadState},
@ -39,12 +39,6 @@ impl LoadingAssets {
} }
fn main() { fn main() {
let (audio_event_sender, audio_event_receiver) =
crossbeam_channel::bounded::<game::AudioMsg>(512);
#[cfg(not(target_arch = "wasm32"))]
std::thread::spawn(move || audio::setup(audio_event_receiver));
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
let (first_level, use_editor) = { let (first_level, use_editor) = {
let mut args = std::env::args().skip(1); let mut args = std::env::args().skip(1);
@ -71,14 +65,14 @@ fn main() {
title: "Lux synthesĕ".into(), title: "Lux synthesĕ".into(),
..Default::default() ..Default::default()
}) })
.insert_resource(audio_event_sender)
.insert_resource(UseEditor(use_editor)) .insert_resource(UseEditor(use_editor))
.add_state(AppState::Loading) .add_state(AppState::Loading)
.insert_resource(game::FirstLevel(first_level)) .insert_resource(game::FirstLevel(first_level))
.insert_resource(ClearColor(Color::BLACK)) .insert_resource(ClearColor(Color::BLACK))
.add_plugins(DefaultPlugins) .add_plugins(DefaultPlugins)
.add_plugin(audio_system::AudioSystemPlugin)
//.add_plugin(RapierDebugRenderPlugin::default()) //.add_plugin(RapierDebugRenderPlugin::default())
//.add_plugin(bevy_inspector_egui::WorldInspectorPlugin::new()) // .add_plugin(bevy_inspector_egui::WorldInspectorPlugin::new())
.add_plugin(JsonAssetPlugin::<levels::StoredLevels>::new(&[ .add_plugin(JsonAssetPlugin::<levels::StoredLevels>::new(&[
"levels.json", "levels.json",
])); ]));