use std::time::Duration;
use avian2d::prelude::*;
use crate::prelude::*;
use crate::{
particle_editor::ecs::{CircleMesh, LifetimeTimer, ParentEffect, Particle, SpawnDelayTimer},
particles::ParticleEffect,
};
pub fn spawn_plugin(app: &mut App) {
app.add_systems(Update, spawn_particles);
app.add_systems(Update, lifetime_particles);
}
fn spawn_particles(
mut commands: Commands,
particle_effects: Query<(&Transform, &ParticleEffect, &mut SpawnDelayTimer)>,
time: ResMut<Time>,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<ColorMaterial>>,
) {
for (transform, effect, mut delay_timer) in particle_effects {
delay_timer.0.tick(time.delta());
if delay_timer.0.just_finished() {
for _ in 0..effect.particles_in_batch.sample(&mut rand::rng()) {
let circle = CircleMesh(
meshes.add(Circle::new(1.0)),
materials.add(
effect
.color
.sample(effect.color.clamp_time(0.0).unwrap())
.unwrap(),
),
);
commands.spawn((
RigidBody::Dynamic,
Particle,
transform.with_scale(Vec3::splat(
effect
.scale
.sample(effect.scale.clamp_time(0.0).unwrap())
.unwrap(),
)),
Mesh2d(circle.0.clone()),
MeshMaterial2d(circle.1.clone()),
LinearVelocity(effect.initial_linear_velocity.sample(&mut rand::rng())),
AngularVelocity(effect.initial_angular_velocity.sample(&mut rand::rng())),
LifetimeTimer(Timer::from_seconds(
effect.lifetime_seconds.sample(&mut rand::rng()),
TimerMode::Once,
)),
circle,
ParentEffect(effect.clone()),
));
}
delay_timer.0.set_duration(Duration::from_secs_f32(
effect.batch_spawn_delay_seconds.sample(&mut rand::rng()),
));
delay_timer.0.reset();
}
}
}
fn lifetime_particles(
mut commands: Commands,
mut particles: Query<
(
Entity,
&mut LifetimeTimer,
&mut Transform,
&CircleMesh,
&ParentEffect,
),
With<Particle>,
>,
time: ResMut<Time>,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<ColorMaterial>>,
) {
for (entity, mut timer, mut transform, circle, parent) in &mut particles {
timer.0.tick(time.delta());
transform.scale = Vec3::splat(
parent
.0
.scale
.sample(parent.0.scale.clamp_time(timer.0.elapsed_secs()).unwrap())
.unwrap(),
);
materials.get_mut(&circle.1).unwrap().color = parent
.0
.color
.sample(parent.0.color.clamp_time(timer.0.elapsed_secs()).unwrap())
.unwrap();
if timer.0.just_finished() {
commands.entity(entity).despawn();
meshes.remove(&circle.0);
materials.remove(&circle.1);
}
}
}