pixijs / particle-emitter

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

Feature: Support for custom path in Path particles #115

Closed patwari closed 3 years ago

patwari commented 4 years ago

Provide support for custom path functions for Path particles, in two ways

  1. within extraData.path = function(x) { return x*x; } or
  2. __emitter__.pathFunction = function(x) { return x*x; }

Also, these custom path functions can control either only y, or both {x, y} values, which opens up a lot of options that allows particles to move in both x- and y-axis, against previously where we could calculate only y value.

These path functions can be changed at run-time.

@andrewstart, For more details, please check following newly added examples:

  1. bubbleStreamCustomPath.html
  2. bubbleStream2DPath.html
andrewstart commented 4 years ago

Sorry, the email for this slipped past me and just recently saw it. I like making PathParticle able to handle function inputs as well as point outputs from path functions. I'm not a fan of making Emitter know about specifics of non-basic particle types. Modifying the function for an emitter's particles globally could still be done by having the provided function branch internally:

let mode = 0;
function pathFunction(movement) {
    switch (mode) {
        case 0:
            return bloop(movement);
        case 1:
            return blip(movement);
    }
}
function bloop(movement) {
    // some stuff
}
function blip(movement) {
    // different stuff
}
patwari commented 4 years ago

Sorry, the email for this slipped past me and just recently saw it.

No issue, man. Thanks for your quick reply though.

I'm not a fan of making Emitter know about specifics of non-basic particle types.

I understand, but presently there isn't any way to control a Particle class' config during run-time, except for changing particleConstructor getter/setter which will trigger init(). I didn't wanted to make a lot of changes.

Modifying the function for an emitter's particles globally could still be done by having the provided function branch internally:

let mode = 0;
function pathFunction(movement) {
    switch (mode) {
        case 0:
            return bloop(movement);
        case 1:
            return blip(movement);
    }
}
function bloop(movement) {
    // some stuff
}
function blip(movement) {
    // different stuff
}

The same with this one. Cannot change during run-time. Run-time modification will be a nice feature to have. I've made two examples demonstrating sample use of this feature. However, I'm open to suggestions.

Also, as I've written in comments, pathFunction getter/setter works only for PathParticles, otherwise returns null.

andrewstart commented 4 years ago

After getting some better sleep, I see now that my "example" was completely unrelated to what you are actually doing, sorry about that (if you ever wanted to change the path of all living & future particles at once, that is how I would do it). My suggestion would be to subclass Emitter in your project to make a PathEmitter, which would also allow you to enforce the usage of the PathParticle constructor without needing to pass it in for each emitter. Also, I don't see any reason why we couldn't have a reset parameter to init() that defaults to true - that would allow someone to put in a whole new config while letting living particles die out if they wanted to. So long as particleConstructor isn't changed, then particle recycling is completely safe. To make it even simpler, we could also add a replaceConfig(config) method that calls this.init(this._origArt, config, false).

patwari commented 4 years ago

My suggestion would be to subclass Emitter in your project to make a PathEmitter, which would also allow you to enforce the usage of the PathParticle constructor without needing to pass it in for each emitter. Also, I don't see any reason why we couldn't have a reset parameter to init() that defaults to true - that would allow someone to put in a whole new config while letting living particles die out if they wanted to. So long as particleConstructor isn't changed, then particle recycling is completely safe.

Quite a modular approach! I like it. But as I said, I didn't wanted to make a lot of changes in the main flow.

To make it even simpler, we could also add a replaceConfig(config) method that calls this.init(this._origArt, config, false).

It will be a nice addition. Will make a simple PR later. :-) For now, I think this PR can be merged.

andrewstart commented 3 years ago

Finally made the modular approach in release 5.0.0, and as part of that you can supply a function directly.