use bevy::{prelude::*, sprite::Mesh2dHandle}; use rand::Rng; use rand_distr::{Distribution, UnitCircle}; #[cfg(not(target_arch = "wasm32"))] pub const POOL_COUNT: usize = 100; #[cfg(target_arch = "wasm32")] pub const POOL_COUNT: usize = 50; pub const MIN_VELOCITY: f32 = 10.0; pub const MAX_VELOCITY: f32 = 100.0; pub const _VELOCITY_SCALE: f32 = 0.1; pub const PARTICLE_EFFECT_RADIUS: f32 = 70.0; pub struct ParticleEffectPlugin; impl Plugin for ParticleEffectPlugin { fn build(&self, app: &mut App) { app.init_resource::() .insert_resource(ParticleEffectResource::new(Vec3::new( 10000.0, 10000.0, 0.0, ))) .add_startup_system(particle_effect_startup) .add_system(particle_effect_system); } } pub struct ParticleMesh { square: Mesh2dHandle, } impl FromWorld for ParticleMesh { fn from_world(world: &mut World) -> Self { let mut meshes = world.get_resource_mut::>().unwrap(); Self { square: meshes .add(Mesh::from(shape::Quad { size: Vec2 { x: 4.0, y: 4.0 }, flip: false, })) .into(), } } } #[derive(bevy_inspector_egui::Inspectable)] pub struct ParticleEffectResource { pub translation: Vec3, pub prev_translation: Vec3, pub radius_squared: f32, pub color: Color, } impl ParticleEffectResource { fn new(init_translation: Vec3) -> Self { Self { translation: init_translation, prev_translation: init_translation, radius_squared: PARTICLE_EFFECT_RADIUS * PARTICLE_EFFECT_RADIUS, color: Color::WHITE, } } } #[derive(Default, Component)] pub struct ParticleComponent { pub velocity: Vec3, } impl ParticleComponent { pub fn new() -> Self { let mut particle_component: Self = Self::default(); particle_component.randomize_velocity(MIN_VELOCITY, MAX_VELOCITY); particle_component } pub fn randomize_velocity(&mut self, min_velocity: f32, max_velocity: f32) { let random_direction: [f32; 2] = UnitCircle.sample(&mut rand::thread_rng()); let random_magnitude: f32 = rand::thread_rng().gen_range(min_velocity..max_velocity); self.velocity = Vec3::new(random_direction[0], random_direction[1], 0.0) * random_magnitude; } } fn particle_effect_startup( mut commands: Commands, particle_mesh: Res, mut materials: ResMut>, ) { for _p in 0..POOL_COUNT { let color_mesh = ColorMesh2dBundle { mesh: particle_mesh.square.clone(), material: materials.add(ColorMaterial::from(Color::WHITE)), ..default() }; commands .spawn_bundle(color_mesh) .insert(ParticleComponent::new()); } } fn particle_effect_system( mut materials: ResMut>, mut query: Query<( &mut Transform, &mut ParticleComponent, &Handle, )>, mut particle_effect: ResMut, time: Res