//! This example illustrates how to load and play an audio file, and control where the sounds seems to come from. use bevy::{ audio::{AudioPlugin, SpatialScale}, color::palettes::css::*, prelude::*, time::Stopwatch, }; /// Spatial audio uses the distance to attenuate the sound volume. In 2D with the default camera, /// 1 pixel is 1 unit of distance, so we use a scale so that 100 pixels is 1 unit of distance for /// audio. const AUDIO_SCALE: f32 = 1. / 100.0; fn main() { App::new() .add_plugins(DefaultPlugins.set(AudioPlugin { default_spatial_scale: SpatialScale::new_2d(AUDIO_SCALE), ..default() })) .add_systems(Startup, setup) .add_systems(Update, update_emitters) .add_systems(Update, update_listener) .run(); } fn setup( mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, asset_server: Res, ) { // Space between the two ears let gap = 400.0; // sound emitter commands.spawn(( Mesh2d(meshes.add(Circle::new(15.0))), MeshMaterial2d(materials.add(Color::from(BLUE))), Transform::from_translation(Vec3::new(0.0, 50.0, 0.0)), Emitter::default(), AudioPlayer::(asset_server.load("sounds/Windless Slopes.ogg")), PlaybackSettings::LOOP.with_spatial(true), )); let listener = SpatialListener::new(gap); commands .spawn(( Transform::default(), Visibility::default(), listener.clone(), )) .with_children(|parent| { // left ear parent.spawn(( Sprite::from_color(RED, Vec2::splat(20.0)), Transform::from_xyz(-gap / 2.0, 0.0, 0.0), )); // right ear parent.spawn(( Sprite::from_color(LIME, Vec2::splat(20.0)), Transform::from_xyz(gap / 2.0, 0.0, 0.0), )); }); // example instructions commands.spawn(( Text::new("Up/Down/Left/Right: Move Listener\nSpace: Toggle Emitter Movement"), Node { position_type: PositionType::Absolute, bottom: Val::Px(12.0), left: Val::Px(12.0), ..default() }, )); // camera commands.spawn(Camera2d); } #[derive(Component, Default)] struct Emitter { stopwatch: Stopwatch, } fn update_emitters( time: Res