#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum ParticleStyle {
#[default]
Dot,
Line,
Trail,
}
#[derive(Debug, Clone)]
pub struct Particle {
pub position: (f32, f32),
pub prev_position: (f32, f32),
pub trail: Vec<(f32, f32)>,
pub trail_length: usize,
pub velocity: (f32, f32),
pub acceleration: (f32, f32),
pub color: [f32; 4],
pub size: f32,
pub alpha: f32,
pub lifetime: f32,
pub max_lifetime: f32,
pub angle: f32,
pub angular_velocity: f32,
pub custom: f32,
pub custom2: f32,
pub style: ParticleStyle,
}
impl Default for Particle {
fn default() -> Self {
Self {
position: (0.0, 0.0),
prev_position: (0.0, 0.0),
trail: Vec::new(),
trail_length: 0,
velocity: (0.0, 0.0),
acceleration: (0.0, 0.0),
color: [1.0, 1.0, 1.0, 1.0],
size: 2.0,
alpha: 1.0,
lifetime: 1.0,
max_lifetime: 1.0,
angle: 0.0,
angular_velocity: 0.0,
custom: 0.0,
custom2: 0.0,
style: ParticleStyle::Dot,
}
}
}
impl Particle {
pub fn new(x: f32, y: f32) -> Self {
Self { position: (x, y), ..Default::default() }
}
pub fn update(&mut self, dt: f32) {
self.prev_position = self.position;
if self.trail_length > 0 {
self.trail.push(self.position);
while self.trail.len() > self.trail_length {
self.trail.remove(0);
}
}
self.velocity.0 += self.acceleration.0 * dt;
self.velocity.1 += self.acceleration.1 * dt;
self.position.0 += self.velocity.0 * dt;
self.position.1 += self.velocity.1 * dt;
self.angle += self.angular_velocity * dt;
self.lifetime -= dt;
}
pub fn is_alive(&self) -> bool {
self.lifetime > 0.0
}
pub fn age(&self) -> f32 {
1.0 - (self.lifetime / self.max_lifetime).clamp(0.0, 1.0)
}
pub fn with_lifetime(mut self, lifetime: f32) -> Self {
self.lifetime = lifetime;
self.max_lifetime = lifetime;
self
}
pub fn with_velocity(mut self, vx: f32, vy: f32) -> Self {
self.velocity = (vx, vy);
self
}
pub fn with_color(mut self, color: [f32; 4]) -> Self {
self.color = color;
self.alpha = color[3];
self
}
pub fn with_size(mut self, size: f32) -> Self {
self.size = size;
self
}
pub fn with_style(mut self, style: ParticleStyle) -> Self {
self.style = style;
self
}
pub fn with_trail(mut self, length: usize) -> Self {
self.trail_length = length;
self.trail = Vec::with_capacity(length);
self.style = ParticleStyle::Trail;
self
}
pub fn as_line(mut self) -> Self {
self.style = ParticleStyle::Line;
self
}
}