diff --git a/src/game.rs b/src/game.rs index b50dbbb..abadec2 100644 --- a/src/game.rs +++ b/src/game.rs @@ -31,7 +31,8 @@ impl Plugin for GamePlugin { .add_system_set( SystemSet::on_update(AppState::Game) .with_system(crate::levels::post_setup_level) - .with_system(keyboard_input_system), + .with_system(keyboard_input_system) + .with_system(character_particle_effect_system), ) .add_system_set(SystemSet::on_update(AppState::Win).with_system(keyboard_input_system)) .add_system_to_stage(CoreStage::PostUpdate, collision_event_system); @@ -259,6 +260,25 @@ fn keyboard_input_system( } } +fn character_particle_effect_system( + mut characters: Query<(&CharacterId, &Transform, &CharacterColor)>, + mut particle_effect: ResMut, + mut level_query: Query<(&SelectedCharacterId)>, +) { + if let Ok(selected_character_id) = level_query.get_single_mut() { + if let Some(selected_character_id) = &selected_character_id.0 { + if let Some((_character_id, transform, color)) = characters + .iter_mut() + .find(|(character_id, _transform, _color)| { + *character_id == selected_character_id + }) { + particle_effect.translation = transform.translation; + particle_effect.color = color.0; + } + } + } +} + fn win_setup(mut commands: Commands, asset_server: Res) { let font = asset_server.get_handle("UacariLegacy-Thin.ttf"); commands diff --git a/src/particle_effect.rs b/src/particle_effect.rs index fe922d0..42afdc0 100644 --- a/src/particle_effect.rs +++ b/src/particle_effect.rs @@ -1,4 +1,13 @@ use bevy::{prelude::*, sprite::Mesh2dHandle}; +use rand::Rng; +use rand_distr::{UnitCircle, Distribution}; + +pub const POOL_COUNT: usize = 100; + +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; @@ -6,8 +15,9 @@ impl Plugin for ParticleEffectPlugin { fn build(&self, app: &mut App) { app .init_resource::() - .insert_resource(PoolCount(1000)) - .add_startup_system(particle_effect_startup); + .insert_resource(ParticleEffectResource::new(Vec3::new(10000.0, 10000.0, 0.0))) + .add_startup_system(particle_effect_startup) + .add_system(particle_effect_system); } } @@ -18,6 +28,7 @@ pub struct ParticleMesh { 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 { @@ -29,29 +40,87 @@ impl FromWorld for ParticleMesh { } } -pub struct PoolCount(usize); +#[derive(bevy_inspector_egui::Inspectable)] +pub struct ParticleEffectResource { + pub translation: Vec3, + pub prev_translation: Vec3, + pub radius_squared: f32, + pub color: Color, +} -#[derive(Component)] -pub struct ParticleComponent; +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); + return 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, - pool_count: ResMut, mut materials: ResMut>, ) { - for _p in 0 .. pool_count.0 { + for _p in 0 .. POOL_COUNT { let color_mesh = ColorMesh2dBundle { mesh: particle_mesh.square.clone(), material: materials.add(ColorMaterial::from(Color::WHITE)), - // default to invisible - visibility: Visibility {is_visible: false}, ..default() }; commands .spawn_bundle(color_mesh) - .insert(ParticleComponent); + .insert(ParticleComponent::new()); } +} + +fn particle_effect_system( + mut materials: ResMut>, + mut query: Query<(&mut Transform, &mut ParticleComponent, &Handle)>, + mut particle_effect: ResMut, + time: Res