delayed particles
This commit is contained in:
parent
9ed37d31b5
commit
b4c80b919e
2 changed files with 112 additions and 10 deletions
|
|
@ -14,7 +14,12 @@ pub const LONG_PARTICLE_LIFETIME: f32 = 300.0;
|
|||
// running through a list and removing the frame_time_ms from the
|
||||
// delay. When delay is <= 0, make a particle_builder.request for
|
||||
// the particle.
|
||||
pub fn cull_dead_particles(ecs: &mut World, ctx: &Rltk) {
|
||||
pub fn particle_ticker(ecs: &mut World, ctx: &Rltk) {
|
||||
cull_dead_particles(ecs, ctx);
|
||||
create_delayed_particles(ecs, ctx);
|
||||
}
|
||||
|
||||
fn cull_dead_particles(ecs: &mut World, ctx: &Rltk) {
|
||||
let mut dead_particles: Vec<Entity> = Vec::new();
|
||||
{
|
||||
// Age out particles
|
||||
|
|
@ -32,7 +37,51 @@ pub fn cull_dead_particles(ecs: &mut World, ctx: &Rltk) {
|
|||
}
|
||||
}
|
||||
|
||||
struct ParticleRequest {
|
||||
fn create_delayed_particles(ecs: &mut World, ctx: &Rltk) {
|
||||
let mut particle_builder = ecs.write_resource::<ParticleBuilder>();
|
||||
let mut handled_particles: Vec<ParticleRequest> = Vec::new();
|
||||
for delayed_particle in particle_builder.delayed_requests.iter_mut() {
|
||||
rltk::console::log(delayed_particle.delay);
|
||||
delayed_particle.delay -= ctx.frame_time_ms;
|
||||
if delayed_particle.delay < 0.0 {
|
||||
handled_particles.push(ParticleRequest {
|
||||
x: delayed_particle.particle.x,
|
||||
y: delayed_particle.particle.y,
|
||||
fg: delayed_particle.particle.fg,
|
||||
bg: delayed_particle.particle.bg,
|
||||
glyph: delayed_particle.particle.glyph,
|
||||
lifetime: delayed_particle.particle.lifetime,
|
||||
});
|
||||
}
|
||||
}
|
||||
if handled_particles.is_empty() {
|
||||
return;
|
||||
}
|
||||
// This is repeated code from the ticking system. It could probably be put into a function of its own,
|
||||
// but that'd mean having to work around borrow-checker issues, which I'm not convinced is actually
|
||||
// cleaner than just repeating the code twice - here and in the ParticleSpawnSystem.
|
||||
//
|
||||
// We're running separately from the system so we can have it called every single tick, without having
|
||||
// to do the same for every system. Later, this will probably all be refactored so every system can run
|
||||
// at a higher tickrate.
|
||||
let entities = ecs.entities();
|
||||
let mut positions = ecs.write_storage::<Position>();
|
||||
let mut renderables = ecs.write_storage::<Renderable>();
|
||||
let mut particles = ecs.write_storage::<ParticleLifetime>();
|
||||
for handled in handled_particles {
|
||||
let index = particle_builder.delayed_requests.iter().position(|x| x.particle == handled).unwrap();
|
||||
particle_builder.delayed_requests.remove(index);
|
||||
let p = entities.create();
|
||||
positions.insert(p, Position { x: handled.x, y: handled.y }).expect("Could not insert position");
|
||||
renderables
|
||||
.insert(p, Renderable { fg: handled.fg, bg: handled.bg, glyph: handled.glyph, render_order: 0 })
|
||||
.expect("Could not insert renderables");
|
||||
particles.insert(p, ParticleLifetime { lifetime_ms: handled.lifetime }).expect("Could not insert lifetime");
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub struct ParticleRequest {
|
||||
x: i32,
|
||||
y: i32,
|
||||
fg: RGB,
|
||||
|
|
@ -41,14 +90,21 @@ struct ParticleRequest {
|
|||
lifetime: f32,
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub struct DelayedParticleRequest {
|
||||
pub delay: f32,
|
||||
pub particle: ParticleRequest,
|
||||
}
|
||||
|
||||
pub struct ParticleBuilder {
|
||||
requests: Vec<ParticleRequest>,
|
||||
delayed_requests: Vec<DelayedParticleRequest>,
|
||||
}
|
||||
|
||||
impl ParticleBuilder {
|
||||
#[allow(clippy::new_without_default)]
|
||||
pub fn new() -> ParticleBuilder {
|
||||
ParticleBuilder { requests: Vec::new() }
|
||||
ParticleBuilder { requests: Vec::new(), delayed_requests: Vec::new() }
|
||||
}
|
||||
|
||||
/// Makes a single particle request.
|
||||
|
|
@ -56,6 +112,11 @@ impl ParticleBuilder {
|
|||
self.requests.push(ParticleRequest { x, y, fg, bg, glyph, lifetime });
|
||||
}
|
||||
|
||||
pub fn delay(&mut self, x: i32, y: i32, fg: RGB, bg: RGB, glyph: rltk::FontCharType, lifetime: f32, delay: f32) {
|
||||
self.delayed_requests
|
||||
.push(DelayedParticleRequest { delay: delay, particle: ParticleRequest { x, y, fg, bg, glyph, lifetime } });
|
||||
}
|
||||
|
||||
pub fn damage_taken(&mut self, x: i32, y: i32) {
|
||||
self.request(
|
||||
x,
|
||||
|
|
@ -112,12 +173,53 @@ impl ParticleBuilder {
|
|||
}
|
||||
|
||||
// Makes a particle request in the shape of an 'x'. Sort of.
|
||||
pub fn request_star(&mut self, x: i32, y: i32, fg: RGB, bg: RGB, glyph: rltk::FontCharType, lifetime: f32) {
|
||||
self.request(x, y, fg, bg, glyph, lifetime * 2.0);
|
||||
self.request(x + 1, y + 1, fg, bg, rltk::to_cp437('/'), lifetime);
|
||||
self.request(x + 1, y - 1, fg, bg, rltk::to_cp437('\\'), lifetime);
|
||||
self.request(x - 1, y + 1, fg, bg, rltk::to_cp437('\\'), lifetime);
|
||||
self.request(x - 1, y - 1, fg, bg, rltk::to_cp437('/'), lifetime);
|
||||
#[allow(dead_code)]
|
||||
pub fn request_star(
|
||||
&mut self,
|
||||
x: i32,
|
||||
y: i32,
|
||||
fg: RGB,
|
||||
bg: RGB,
|
||||
glyph: rltk::FontCharType,
|
||||
lifetime: f32,
|
||||
secondary_fg: RGB,
|
||||
) {
|
||||
let eighth_l = lifetime / 8.0;
|
||||
let quarter_l = eighth_l * 2.0;
|
||||
self.request(x, y, fg, bg, glyph, lifetime);
|
||||
self.delay(x + 1, y + 1, secondary_fg.lerp(bg, 0.8), bg, rltk::to_cp437('/'), quarter_l, eighth_l);
|
||||
self.delay(x + 1, y - 1, secondary_fg.lerp(bg, 0.6), bg, rltk::to_cp437('\\'), quarter_l, quarter_l);
|
||||
self.delay(x - 1, y - 1, secondary_fg.lerp(bg, 0.2), bg, rltk::to_cp437('/'), quarter_l, eighth_l * 3.0);
|
||||
self.delay(x - 1, y + 1, secondary_fg.lerp(bg, 0.4), bg, rltk::to_cp437('\\'), quarter_l, lifetime);
|
||||
}
|
||||
|
||||
// Makes a rainbow particle request in the shape of an 'x'. Sort of.
|
||||
pub fn request_rainbow_star(&mut self, x: i32, y: i32, glyph: rltk::FontCharType, lifetime: f32) {
|
||||
let bg = RGB::named(rltk::BLACK);
|
||||
let eighth_l = lifetime / 8.0;
|
||||
let quarter_l = eighth_l * 2.0;
|
||||
let half_l = quarter_l * 2.0;
|
||||
|
||||
self.request(x, y, RGB::named(rltk::CYAN), bg, glyph, lifetime);
|
||||
self.delay(x + 1, y + 1, RGB::named(rltk::RED), bg, rltk::to_cp437('\\'), half_l, eighth_l);
|
||||
self.delay(x + 1, y - 1, RGB::named(rltk::ORANGE), bg, rltk::to_cp437('/'), half_l, quarter_l);
|
||||
self.delay(x - 1, y - 1, RGB::named(rltk::GREEN), bg, rltk::to_cp437('\\'), half_l, eighth_l * 3.0);
|
||||
self.delay(x - 1, y + 1, RGB::named(rltk::YELLOW), bg, rltk::to_cp437('/'), half_l, half_l);
|
||||
}
|
||||
|
||||
// Makes a rainbow particle request. Sort of.
|
||||
#[allow(dead_code)]
|
||||
pub fn request_rainbow(&mut self, x: i32, y: i32, glyph: rltk::FontCharType, lifetime: f32) {
|
||||
let bg = RGB::named(rltk::BLACK);
|
||||
let eighth_l = lifetime / 8.0;
|
||||
|
||||
self.request(x, y, RGB::named(rltk::RED), bg, glyph, eighth_l);
|
||||
self.delay(x, y, RGB::named(rltk::ORANGE), bg, glyph, eighth_l, eighth_l);
|
||||
self.delay(x, y, RGB::named(rltk::YELLOW), bg, glyph, eighth_l, eighth_l * 2.0);
|
||||
self.delay(x, y, RGB::named(rltk::GREEN), bg, glyph, eighth_l, eighth_l * 3.0);
|
||||
self.delay(x, y, RGB::named(rltk::BLUE), bg, glyph, eighth_l, eighth_l * 4.0);
|
||||
self.delay(x, y, RGB::named(rltk::INDIGO), bg, glyph, eighth_l, eighth_l * 5.0);
|
||||
self.delay(x, y, RGB::named(rltk::VIOLET), bg, glyph, eighth_l, eighth_l * 6.0);
|
||||
}
|
||||
|
||||
/// Makes a particle request in the shape of a +.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue