phaser-frameworkparticlesemitter

How to create a little dust trail being left behind the character when running in Phaser


I'm trying to create an arcade platform where some little dust particles are emitted from my character when running. But I still can make it look good, I'm super newbie when it comes to particle emitters, so many variables to change that I'm kinda lost, and also couldn't find any tutorials about Phaser particle emitters but just some examples. I even purchased ParticleStorm from Phaser, but still couldn't make it work well.

This is the particle code and the character in Player.ts class.

this.game = game;
game.physics.arcade.enable(this);

this.body.gravity.y = Player.GRAVITY;
this.body.velocity.x = 0;
this.body.maxVelocity = 500;

// Allow finger inputs on iOS/Android
this.inputEnabled = true;
this.events.onInputDown.add(this.handleInputDown, this);

// Setup keyboard cursors
this.cursors = this.game.input.keyboard.createCursorKeys();

this.animations.add('running', [5, 6, 7, 8], 20, true);

this.dustEmitter = this.game.add.emitter(0, 0, 5);
this.dustEmitter.makeParticles('dust');
this.dustEmitter.setAlpha(0.9, 1, 200);
this.dustEmitter.setScale(0.3, 1, 0.3, 1, 100, Phaser.Easing.Circular.Out);
// this.dustEmitter.minParticleScale = 0.8;
// this.dustEmitter.maxParticleScale = 1;
// this.dustEmitter.minRotation = -360;
// this.dustEmitter.maxRotation = 360;
this.dustEmitter.setXSpeed(0, 0);
this.dustEmitter.setYSpeed(0, 0);
this.dustEmitter.enableBody = true;
this.dustEmitter.gravity.set(-100, -100);

this.dustEmitter.start(false, 300, 25, -1);

Then during the update() function on my player code i update the emitter position based on player's position:

if (this.playerState === PlayerState.RUNNING) {
    this.dustEmitter.visible = true;

    this.dustEmitter.emitX = this.x;
    this.dustEmitter.emitY = this.y + (this.height / 2);
} else {
    this.dustEmitter.visible = false;
}

I tried so many things, changing variables, even tried to use phaser-particle-editor website to play with the values, but I even couldn't replicate it on my Phaser game even though I put the same exact values i had in the site.

What's the best approach for this? is it good to update emitter position based on player's position? or should I do something else? i think the main idea or what i have in my mind is... particles shouldn't actually follow the player but remain in the place they showed up in the first place. And as soon as player starts moving, respawn of dust will follow the player's X and Y. But how can I achieve this with particle emitters?

Thanks in advance.


Solution

  • You mention that you run this piece of code

    if (this.playerState === PlayerState.RUNNING) {
        this.dustEmitter.visible = true;
    
        this.dustEmitter.emitX = this.x;
        this.dustEmitter.emitY = this.y + (this.height / 2);
    } else {
        this.dustEmitter.visible = false;
    }
    

    inside the player update loop. This means that even if you set the emitter's position properly once, it's going to move along with the player as long as it is running (according to PlayerState) because update() is called once for each frame. What you can do is to introduce a timed event that would raise a bool which you then can use to check whether to update the emitter position. Something along these lines:

    class Player extends Phaser.Sprite {
        // ...
    
        private shouldUpdateEmitterPosition: boolean;
    
        constructor() {
            // ...
    
            this.game.time.events.loop(2000, () => this.shouldUpdateEmitterPosition = true, this);
        }
    
        public update() {
            if (this.shouldUpdateEmitterPosition && this.playerState === PlayerState.RUNNING) {
                this.dustEmitter.visible = true;
    
                this.dustEmitter.emitX = this.x;
                this.dustEmitter.emitY = this.y + (this.height / 2);
    
                this.shouldUpdateEmitterPosition = false;   
            } else {
                this.dustEmitter.visible = false;
            }
        }
    }