MrToenails
MrToenails

Reputation: 389

Timed particle emitters in Phaser 3

I'm adding a blood effect for when enemies are hit in my game and I want to be able to specify how long the particle emitter will emit particles for, but the lifespan property when creating a particle emitter is the lifespan of the particles, not the emitter. Is there something like this, or another way? I could set it to off after a minute but I'm not sure how a ton of inactive particle emitters would affect performance.

this.add.particles({
//particle stuff
emitterLifespan: 1000
})

Any suggestions? Thanks!

Upvotes: 1

Views: 940

Answers (1)

winner_joiner
winner_joiner

Reputation: 14760

tldr; ("easy" solution simply use setTimeout(() => emiter.stop(), 1000) , to stop the emitter. In the demo below, it is the last/yellow emitter)

I don't know of any such property, and is also not mentioned in the documentation (or the unofficial more hands on documentation)

I had the same problem, since the particles work abit odd, I think.
It seems you must balance the properies carefully. For the basic scenario, (seen below), the following properties could cause a problem:

  • lifespan lifespan of emitted particles
  • maxParticles hard limit of particles
  • frequency milliseconds for emit cycle

I noticed if the particles "die" before it reaches maxParticles, the emitter won't "stop".

You could configer the properties, so that the emitter stop when it reaches the max ( the red particles in the example), or you could use the setTimeout function to stop it, after some time(like the yellow particles). Green and blue just show how different values won't stop the emitter. (due to the random part, and depending on the performance of the browser/pc, this might run forever or stop. On my CellPhone the blue emitter stops, but the green ones don't. And on my PC green and blue run for "ever")

document.body.style = 'margin:0;';

var config = {
    type: Phaser.AUTO,
    width: 536,
    height: 183,
    physics: {
        default: 'arcade',
        arcade: {            
            gravity:{ y: 100 },
            debug: true
        }
    },
    scene: {
        create
    },
    banner: false
}; 

function create () {

    this.add.text(10,10, 'Click to Create Blood').setOrigin(0);
    let g = this.make.graphics({add:false});
    
    g.fillStyle(0xffffff)
    g.fillCircle(4,4,4);
    g.generateTexture('blood', 8, 8)
    
    let particles = this.add.particles('blood');

    this.input.on('pointerdown',  p => {
        particles.createEmitter({
            tint: 0xff0000,
            alpha: { start: 1, end: 0 },
            scale: { start: 0.5, end: 1.5 },
            speed: {random: [20, 100] },
            accelerationY:  {random: [-100, 200] },
            rotate: { min: -180, max: 180 },
            lifespan: { min: 300, max: 800 },
            frequency: 20,
            maxParticles: 10,
            x: p.x,
            y: p.y
        });    

        particles.createEmitter({
            alpha: { start: 1, end: 0 },
            tint: 0x00ff00,
            scale: { start: 0.5, end: 1.5 },
            speed: {random: [20, 100] },
            accelerationY:  {random: [-100, 200] },
            rotate: { min: -180, max: 180 },
            lifespan: { min: 300, max: 800 },
            frequency: 120,
            maxParticles: 10,
            x: p.x + 100,
            y: p.y
        });    
        
        particles.createEmitter({
            alpha: { start: 1, end: 0 },
            tint: 0x0000ff,
            scale: { start: 0.5, end: 1.5 },
            speed: {random: [20, 100] },
            accelerationY:  {random: [-100, 200] },
            rotate: { min: -180, max: 180 },
            lifespan: { min: 200, max: 300 },
            frequency: 10,
            maxParticles: 20,
            x: p.x + 200,
            y: p.y
        });    
        
          let emitter = particles.createEmitter({
            alpha: { start: 1, end: 0 },
            tint: 0xffff00,
            scale: { start: 0.5, end: 1.5 },
            speed: {random: [20, 100] },
            accelerationY:  {random: [-100, 200] },
            rotate: { min: -180, max: 180 },
            lifespan: { min: 200, max: 300 },
            frequency: 10,
            maxParticles: 20,
            x: p.x + 300,
            y: p.y
        }); 
        
        // Stop after 1000 ms
        setTimeout(()=> emitter.stop(), 1000);
    });

}

new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/phaser.js"></script>

btw.: you could also use the explode function if all particles should be emitted at once, checkout this official example, and here the link to the documenation.

Upvotes: 1

Related Questions