javascriptphaser-frameworkparticles

Phaser 3: Allow Particles to emit with flipped/mirrored image?


I have a particle emitter which emits multiple duplicates of the same image, as usual. However I'd like some of the particles to be flipped, either completely at a random amount, or sort of in the middle, so that particles falling to the left would be flipped and particles falling to the right won't be.

However I couldn't find anything regarding flipping particles without flipping ALL of them. I'd only like some to be flipped. Is this possible in any way?


Solution

  • There are serveral way's, I think the "fastest" would be just to use the scaleX property of the emiter.

    this code flips about 10% of the particles ( 0.9 > Math.random() ), through multiplying it with -1, when it should be flipped.

    Example Code:

    this.add.particles('sparkle').createEmitter({
        x: 200,
        y: 100,
        scaleX: {
            onEmit: function () { 
                return ( 0.9 > Math.random() ) ? -1 : 1;
            }
        },
        speed: { min: -100, max: 100 },
        quantity: 0.1,
        frequency: 1,
    });
    

    But I assume from a earlier question, that you have emitter with a "random scale" property. I that case you woud have to do something like this:

    Example Code, for random scaled particles:

    gameState.splash = this.add.particles('droplet').createEmitter({
        x: gameState.height/2,
        y: gameState.width/2,
        scale:  { 
            onEmit: function () {
                // create random new scale
                let newRandowmScale = Phaser.Math.FloatBetween(0.05, 0.3);
                return ( 0.9 > Math.random() ) ? -1 * newRandowmScale  : newRandowmScale;
             }
        },
        speed: { min: -100, max: 100 },
        ...
    });
    

    UPDATE(SlowerFix): Example Code, for random scaled particles:

    What the update does: save the current scale of the scaleX event and use it in the scaleY event. (it is hacky, but should work. I will see if there is a cleaner solution)

    gameState.splash = this.add.particles('droplet').createEmitter({
        x: gameState.height/2,
        y: gameState.width/2,
        scaleY:{
            onEmit: function(particle){
                // keep scale value positive
                return Math.abs(particle.scaleX);
            }
        },
        scaleX:{
            onEmit: function(p){
                let scale = Phaser.Math.FloatBetween(.2, .5);
                return Math.random() > .9 ? scale * -1 : scale;
            }
        }, 
        speed: { min: -100, max: 100 },
        ...
    });