particle_system.rs 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. use specs::prelude::*;
  2. use super::{Rltk, ParticleLifetime, Position, Renderable};
  3. use rltk::{RGB};
  4. pub struct ParticleSpawnSystem {}
  5. impl<'a> System<'a> for ParticleSpawnSystem {
  6. #[allow(clippy::type_complexity)]
  7. type SystemData = (
  8. Entities<'a>,
  9. WriteStorage<'a, Position>,
  10. WriteStorage<'a, Renderable>,
  11. WriteStorage<'a, ParticleLifetime>,
  12. WriteExpect<'a, ParticleBuilder>
  13. );
  14. fn run(&mut self, data : Self::SystemData) {
  15. let (entities, mut positions, mut renderables, mut particles, mut particle_builder) = data;
  16. for new_particle in particle_builder.requests.iter() {
  17. let p = entities.create();
  18. positions.insert(p, Position{ x: new_particle.x, y: new_particle.y }).expect("Unable to inser position");
  19. renderables.insert(p, Renderable{ fg: new_particle.fg, bg: new_particle.bg, glyph: new_particle.glyph, render_order: 0 }).expect("Unable to insert renderable");
  20. particles.insert(p, ParticleLifetime{ lifetime_ms: new_particle.lifetime }).expect("Unable to insert lifetime");
  21. }
  22. particle_builder.requests.clear();
  23. }
  24. }
  25. struct ParticleRequest {
  26. x: i32,
  27. y: i32,
  28. fg: RGB,
  29. bg: RGB,
  30. glyph: rltk::FontCharType,
  31. lifetime: f32
  32. }
  33. pub struct ParticleBuilder {
  34. requests : Vec<ParticleRequest>
  35. }
  36. impl ParticleBuilder {
  37. #[allow(clippy::new_without_default)]
  38. pub fn new() -> ParticleBuilder {
  39. ParticleBuilder{ requests : Vec::new() }
  40. }
  41. pub fn request(&mut self, x:i32, y:i32, fg: RGB, bg:RGB, glyph: rltk::FontCharType, lifetime: f32) {
  42. self.requests.push(
  43. ParticleRequest{
  44. x, y, fg, bg, glyph, lifetime
  45. }
  46. );
  47. }
  48. }
  49. pub fn cull_dead_particles(ecs : &mut World, ctx : &Rltk) {
  50. let mut dead_particles : Vec<Entity> = Vec::new();
  51. {
  52. // Age out particles
  53. let mut particles = ecs.write_storage::<ParticleLifetime>();
  54. let entities = ecs.entities();
  55. for (entity, mut particle) in (&entities, &mut particles).join() {
  56. particle.lifetime_ms -= ctx.frame_time_ms;
  57. if particle.lifetime_ms < 0.0 {
  58. dead_particles.push(entity);
  59. }
  60. }
  61. }
  62. for dead in dead_particles.iter() {
  63. ecs.delete_entity(*dead).expect("Particle will not die");
  64. }
  65. }