use bevy::color::{Color, ColorCurve, LinearRgba}; use bevy::math::cubic_splines::LinearSpline; use bevy::math::{Vec2, VectorSpace}; use rand::Rng; use serde::{Deserialize, Serialize}; use serde::de::DeserializeOwned; #[derive(Deserialize, Serialize)] pub struct ParticleEffect { // -- lifetime / spawning -- // /// Particle lifetime in seconds pub lifetime_seconds: RandF32, /// Delay inbetween each batch of particles spawned pub batch_spawn_delay_seconds: RandF32, /// Number of distinct particles spawned per batch pub particles_in_batch: RandF32, // -- velocity -- // /// Initial linear velocity added to the particle's velocity when it is spawned pub initial_linear_velocity: RandVec2, /// Initial angular velocity added to the particle's rotation when it is spawned pub initial_angular_velocity: RandF32, // -- scale -- // // Scale curve over the lifetime of the particle pub scale: ScaleSpline, // -- color -- // // Color curve over the lifetime of the particle pub color: ColorSpline, } #[derive(Deserialize, Serialize)] pub struct ScaleSpline(Vec); impl From for LinearSpline { fn from(value: ScaleSpline) -> Self { Self::new(&value.0) } } #[derive(Deserialize, Serialize)] pub struct ColorSpline(Vec); impl From for LinearSpline { fn from(value: ColorSpline) -> Self { Self::new(&value.0) } } #[derive(Deserialize, Serialize)] pub struct RandF32 { pub value: f32, pub randomness: f32 } impl RandF32 { pub fn sample(&self, rng: &mut impl Rng) -> f32 { rng.random_range(self.value-self.randomness .. self.value+self.randomness) } } #[derive(Deserialize, Serialize)] pub struct RandVec2 { pub x: RandF32, pub y: RandF32, } impl RandVec2 { pub fn sample(&self, rng: &mut impl Rng) -> Vec2 { Vec2::new(self.x.sample(rng), self.y.sample(rng)) } }