Add event on each element of a pool

Hi there,

I want to add a “pointerdown” event on each element of my pool. When clicked, the element should get killed. I’m browsing code examples with no success since yesterday. Any help? :slight_smile:

Here’s my code.

let balls = this.add.group({
        defaultKey: 'ball',
        maxSize: 10
});
        
this.input.on('pointerdown', () => {
        if(!balls.isFull()){
             let ball = balls.get(
                    Phaser.Math.Between(50,350),
                    Phaser.Math.Between(50,350),
        );
         // DOESN'T WORK
        ball.setInteractive();
        ball.on('pointerover', b => {
                  balls.killAndHide(b);
        })
    }    
});

Change

ball.on('pointerover', b => {
       balls.killAndHide(b);
})

to

ball.on('pointerover', b => {
       balls.killAndHide(ball);
})

I think the first element passed into a pointer event is the event itself, not the object that it was triggered on. So the group wasn’t finding the group item you were trying to kill and hide because it wasn’t a member of the group. But that change got it working for me.

1 Like

Your’re right. Thank you very much Jackolantern. It solves that issue, but generates another one. The pointerdown event works fine as long as the pointerover event isn’t fired. After that, no more ball can be added to the screen.

Any idea on that one?

This is an intricacy to the way groups work. I forgot about that! After you killAndHide() a sprite, you need to call these two lines the next time you create one. Change your input method to this:

this.input.on('pointerdown', () => {
        if(!balls.isFull()){
            let ball = balls.get(
                Phaser.Math.Between(50,350),
                Phaser.Math.Between(50,350),
            );
            
            ball.setInteractive();
            ball.setActive(true);
            ball.setVisible(true);
            ball.on('pointerover', () => {
                balls.killAndHide(ball);
            })
        }
    });

setActive() and setVisible() will allow you to reset your sprite once it has been killed and hidden.

1 Like

Excellent! Thank you so much Jackolantern!
So, (just to understand fully) : the code was working but the ball was invisible or the ball was absolutely missing from the pool? Just to understand what do you man by “reset” your sprite.

Honestly, I am still trying to wrap my head around that question as well. I am still learning Phaser myself and had just worked through the same problem. I do know if your items in your pool have physics and you turn on debugging, you can see the body still sitting there where you killed the sprite even though the sprite itself is gone and no more are generated out of the pool. It seems like calling kill and hide actually just hides them, and those other method calls are what actually finish off the job of the previous pool member that was killed. But that is just my experience.

Maybe a more experienced member could explain why this is necessary and what is technically going on.

1 Like

Actually, thinking about it some more and looking at the method calls, I think it makes more sense. Even though you set the maximum size of your pool to be 10, if you are only generating one sprite at a time (which is the case if you click the canvas and then immediately mouseover the sprite) then the pool only contains one sprite. It doesn’t immediately generate 10 sprites to fill the pool if it doesn’t need to since that would be inefficient.

So in this case, when you click the canvas, then mouseover the sprite to kill and hide it, and then click the canvas again, you are getting back the exact same sprite you just hid and killed. Calling these methods basically reset it back to being visible and alive. It would be nice if the framework did this for you, but I guess there may be some performance tricks where you would not want that to happen automatically.

I am still not 100% sure on this, but it makes sense to me.

1 Like

Thank you very much Jackolantern. The debug mode gives a good insight of what’s happening. I think your hypotheses are absolutely right. I’ve seen it’s possible to create all the sprites of the pool at the beginning. I’m not really sure what’s best in terms of performances. I’ll have a check on JSPerf.

1 Like

It is probably technically best to keep it at the minimum possible, but for most cases it likely won’t matter. You aren’t going to notice the difference in performance between creating 2 sprites and creating 10. Now creating 10 and creating 1000 could be a noticeable difference but most of the time we aren’t going to have a case like that except in maybe a bullet hell shooter.

1 Like

You’re right! Thanks Jackolantern :slight_smile:

1 Like