alex
alex

Reputation: 611

Phaser 3 - Particles become more the more often I emit them?

I have particles that I emit when clicking and moving my mouse over a certain object. However I noticed that while the particles start out as little, they become more and more the more often I click and move my mouse,until the stream of particles is far too dense.

This only seems to happen when I click down multiple times (thus triggering the pointerdown event multiple times), not when I click once and keep moving.

How can I stop this?

function pet(start, scene, pointer = null)
{
    if(start){
        scene.input.on('pointermove', function(){
            if (scene.input.activePointer.isDown && gameState.chara.getBounds().contains(scene.input.activePointer.x, scene.input.activePointer.y)){
                gameState.sparkle.emitParticle(1,scene.input.activePointer.x, scene.input.activePointer.y);   // !!!! Here is where I emit my particles
            }
        });
    } else {
        gameState.sparkle.stop();   // !!!! Here I stop my particles
    }
}

const gameState = {
    gameWidth: 800,
    gameHeight: 800,
    menu: {},
    textStyle: { 
        fontFamily: "'Comic Sans MS'", 
        fill: "#fff", 
        align: "center",
        boundsAlignH: "left", 
        boundsAlignV: "top"
    },
};

function preload()
{
    this.load.baseURL = 'assets/';
    
    //  Chara
    this.load.atlas('chara', 'chara.png', 'chara.json');
    
    // Particle
    this.load.image('sparkle', 'sparkle.png');  // Here I load my particle image
    
}

function create()
{
    // Scene
    let scene = this;
    
    // Chara
    this.anims.create({
        key: "wag",
        frameRate: 12,
        frames: this.anims.generateFrameNames("chara", {
            prefix: 'idle_000',
            start: 0, 
            end: 5}),
        repeat: 0,
    });
    this.anims.create({
    key: "happy",
        frameRate: 12,
        frames: this.anims.generateFrameNames("chara", {
            prefix: 'happy_000',
            start: 0, 
            end: 5}),
        repeat: -1
    });
    gameState.chara = this.add.sprite(400, 400, "chara", "idle_0000");
    gameState.chara.setInteractive({cursor: "pointer"});
    
    // !!!! Here I set up my Particle Emitter !!!!
    gameState.sparkle = this.add.particles('sparkle').createEmitter({
        x: gameState.height/2,
        y: gameState.width/2,
        scale: { min: 0.1, max: 0.5 },
        speed: { min: -100, max: 100 },
        quantity: 0.1,
        frequency: 1,
        lifespan: 1000,
        gravityY: 100,
        on: false,
    });

    gameState.chara.on('pointerdown', function(){ pet(true, scene) });
    gameState.chara.on('pointerout', function(){ pet(false, scene, 'default') });
    gameState.chara.on('pointerup', function(){ pet(false, scene, 'pointer') });
}

function update()
{   

}

// Configs

var config = {
    backgroundColor: "0xf0f0f0",
    scale: {
        width: gameState.gameWidth,
        height: gameState.gameHeight,
        autoCenter: Phaser.Scale.CENTER_BOTH
    },
    scene: {
        preload, create, update
    }
};
var game = new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/phaser.js"></script>

Upvotes: 1

Views: 752

Answers (1)

winner_joiner
winner_joiner

Reputation: 14760

The problem is, that you are adding a new scene.input.on('pointermove',...) event-handler in the pet function, on each click.

I would only change the code abit (look below), this should prevent generating too many particles and too many event-handlers (too many event-handlers could harm performance, so be careful, when adding them).

Here is how I would modify the Code:
(I stripped out and added some stuff to make the demo, easier to understand and shorter. And also that the snippet can be executed, without errors/warnings)

The main changes are marked and explained in the code, with comments

function pet(start, scene, pointer = null)
{
    if(start){
        // Update: remove Event listener add click state
        gameState.mouseDown = true
    } else {
        // Update: add click state
        gameState.mouseDown = false;
        gameState.sparkle.stop();
    }
}

const gameState = {
    gameWidth: 400,
    gameHeight: 200,
   // Update: add click state
    mouseDown: false
};

function create()
{
     // Scene
     let scene = this;
    
     // Just could for Demo START
     var graphics = this.add.graphics();
     graphics.fillStyle(0xff0000);
     graphics.fillRect(2,2,10,10);
     graphics.generateTexture('particle', 20, 20);
     graphics.clear();
     graphics.fillStyle(0xffffff);
     graphics.fillRect(0,0,40,40);
     graphics.generateTexture('player', 40, 40);
     graphics.destroy();
     // Just Code for Demo END

    gameState.chara = this.add.sprite(200, 100, "player");
    gameState.chara.setInteractive({cursor: "pointer"});
    
    gameState.sparkle = this.add.particles('particle').createEmitter({
        scale: { min: 0.1, max: 0.5 },
        speed: { min: -100, max: 100 },
        quantity: 0.1,
        frequency: 1,
        lifespan: 1000,
        gravityY: 100,
        on: false,
    });

    gameState.chara.on('pointerdown', function(){ pet(true, scene) });
    gameState.chara.on('pointerout', function(){ pet(false, scene, 'default') });
    gameState.chara.on('pointerup', function(){ pet(false, scene, 'pointer') });
    
    // Update: add new single Event Listener
    gameState.chara.on('pointermove', function(pointer){
        if(gameState.mouseDown){
          gameState.sparkle.emitParticle(1,pointer.x, pointer.y); 
        }
    });
}

// Configs
var config = {
    width: gameState.gameWidth,
    height: gameState.gameHeight,
    scene: { create }
};
var game = new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/phaser.js"></script>

Upvotes: 1

Related Questions