pixijs / particle-emitter

A particle system for PixiJS
http://pixijs.io/particle-emitter/docs
MIT License
786 stars 124 forks source link

Advanced Lifetimes #126

Closed scristall closed 4 years ago

scristall commented 4 years ago

I want to be able to create particles with more complex lifetimes than ones randomly bounded between two numbers. I implemented a custom particle class that sets maxLife based on some logic prior to calling Particle_init. In theory this works, however, the default Emitter crashes when particles immediately die on the first update. It guards against this normally by this line:

    //only make the particle if it wouldn't immediately destroy itself
    if (-this._spawnTimer < lifetime) {

But in my custom Particle, maxLife is being manipulated after this check has already passed. I worked around this by creating a custom Emitter that is identical except in update I omit the first Particle.update:

        //initialize particle
        p.init();
        //update the particle by the time passed, so the particles are spread out properly
        // p.update(-this._spawnTimer); //we want a positive delta, because a negative delta messes things up
        // ^--- commented out to prevent destroy on first update crash

This appears to work okay right now, but is there a better approach? Could there be a config maybe to manipulate the base Emitter a bit better for this case?

andrewstart commented 4 years ago

I haven't tried it, but I am going to guess that moving p.update(-this._spawnTimer); to the bottom of the block it is in (right after ++this.particleCount;) would allow the Emitter to properly handle the particle immediately dying (because it would already be fully added). I don't know off the top of my head if all Particle class code can handle an update delta greater than its lifetime, but it should be okay (the base class should just immediately kill itself, but your custom lifetime should avoid that).

scristall commented 4 years ago

That seemed to work, as far as I can tell! Would you ever consider making this a feature of the base class? I'm happy to keep using my custom Emitter in any case.

andrewstart commented 4 years ago

Moving the update call is definitely something that should be done, because it doesn't change current behavior and adds more resilience to uncommon use cases like yours. As a side note, I assume that on your emitter minLifetime and maxLifetime are the same very large number (or Infinity), is that correct?

scristall commented 4 years ago

I actually have them both just set to 1. My custom lifetime particle then sets maxAge to a function, much like how the PathParticle example works. This seems to work correctly as far as I can tell.

andrewstart commented 4 years ago

That if (-this._spawnTimer < lifetime) { check will skip your particle if you somehow have update deltas of more than 1 second. That would be a terrible framerate, and potentially not even an edge case in your use case, but I figured I'd mention it.

andrewstart commented 4 years ago

Fixed in release 4.2.1