pixijs / particle-emitter

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

Artifacts when using `playOnce` #184

Closed plurry closed 2 years ago

plurry commented 2 years ago

If I download one of the explosion emitters from the editor, and start it with playOnce:

const particles = new PIXI.ParticleContainer(1500, {rotation: true, tint: true, uvs: true, vertices: true})
const config = PIXI.particles.upgradeConfig(await PIXI.Assets.load('emitter.json'), 'smoke.png')
const emitter = new PIXI.particles.Emitter(particles, {...config, autoUpdate: true, emit: false})

addEventListener('pointerup', _ => {
    emitter.updateSpawnPos(_.x, _.y)
    emitter.playOnce()
})

It consistently happens that a few particles will randomly spawn in between the old position and the new one. I tried calling init and cleanup before I called playOnce but that didn't fix it. Should I be creating a new Emitter every time I want a new explosion?

All the examples I looked at on https://pixijs.io/particle-emitter/examples/ use a manual update loop instead of Pixi's ticker. What's the right way to use the modern features to spawn an emitter where the mouse clicks like the explosion examples do?

One more question that didn't seem like it deserved it's own issue: Why doesn't playOnce set autoUpdate itself like playOnceAndDestroy does?

Thanks 👍

andrewstart commented 2 years ago

As much as the names might lead you to believe otherwise, the way ParticleContainer works and the way Emitter work don't really work well together - I've found that PIXI.particles.LinkedListContainer gets better performance, due to the constant adding and removing of children (plus not having to disable most of the speed boosts of ParticleContainer). ParticleContainer is big on batching sprites and not changing them, so I am not too surprised by weird behavior like that. It may also be that the options you are using are incomplete - here is what I set up several versions of PixiJS ago, I am not sure if any of them have changed since.

For playOnce vs playOnceAndDestroy: playOnce was set up as an easy way to attach a completion callback, for both users of autoUpdate and manual updaters. playOnceAndDestroy only makes sense if you are using autoUpdate, since otherwise you'd have to clean out your own references when complete anyway.

plurry commented 2 years ago

Thanks for the quick reply.

Going by https://pixijs.download/dev/docs/PIXI.ParticleContainer.html, it looks like a one-to-one matchup from your old initialization to mine. scale becomes vertices, position is enabled by default, rotation and uvs stay the same, and alpha becomes tint.

I'm not attached to particle ParticleContainer though. I'll use LinkedListContainer from now on. But when I swap it out I'm still getting a couple rogue particles. As far as I can tell, it's always exactly two: One at the old spawn and one at the midpoint between the old and new one.

https://codesandbox.io/s/eloquent-scooby-h7n62i

andrewstart commented 2 years ago

Oh, in that case it's intended behavior of the emitter to interpolate its own position. When reusing an emitter, call emitter.resetPositionTracking() each time you restart it.

plurry commented 2 years ago

Perfect 👍