diff options
Diffstat (limited to 'src/sim/particle_manager/mod.rs')
| -rw-r--r-- | src/sim/particle_manager/mod.rs | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/src/sim/particle_manager/mod.rs b/src/sim/particle_manager/mod.rs new file mode 100644 index 0000000..e5e47eb --- /dev/null +++ b/src/sim/particle_manager/mod.rs @@ -0,0 +1,85 @@ +use crate::{ + config::PIXELS_TO_METRES, + sim::{ + cell::{cell::Cell, materials::MaterialForm}, + cell_manager::manager::CellManager, + lib::ray::AwDda, + particle_manager::particle::Particle, + }, +}; + +pub mod particle; + +pub struct ParticleManager { + pub particles: Vec<Particle>, +} + +const PARTICLE_GRAVITY: f32 = 9.81 * PIXELS_TO_METRES; + +impl ParticleManager { + pub fn tick(&mut self, world: &mut CellManager, delta_time: f32) { + puffin::profile_function!(); + let mut i = 0; + 'outer: while i < self.particles.len() { + let p = &mut self.particles[i]; + + p.life -= delta_time; + if p.life <= 0.0 { + self.particles.swap_remove(i); + continue 'outer; + } + + p.velocity.y += PARTICLE_GRAVITY * delta_time; + let dt_velocity = p.velocity * delta_time; + + let mut dda = AwDda::new(p.position, p.position + dt_velocity); + + if let Some(mut prev) = dda.next() { + if let Some(cell) = world.get_cell_from_game_position(prev.x, prev.y) + && [ + MaterialForm::Solid, + MaterialForm::Powder, + MaterialForm::Liquid, + ] + .contains(&cell.material.def().form) + { + // the particle is already inside a collider, we should just kill it + self.particles.swap_remove(i); + continue 'outer; + } + + for next in dda { + if let Some(cell) = world.get_cell_from_game_position(next.x, next.y) + && [ + MaterialForm::Solid, + MaterialForm::Powder, + MaterialForm::Liquid, + ] + .contains(&cell.material.def().form) + { + // write ourselves to the board + world.set_cell_from_game_position( + prev.x, + prev.y, + Cell::from_material(p.material), + false, + ); + self.particles.swap_remove(i); + continue 'outer; + } + prev = next; + } + } + + // no collision, just move + p.position += dt_velocity; + i += 1; + } + } + + pub fn new() -> Self { + ParticleManager { + particles: Vec::new(), + } + } +} |
