'Getting last element on click every time in Javascript loop with Phaser JS

I am making a game in Phaser although I believe the core of this issue is a lack of my JS understanding.

I am looping through a Phaser container and wish to apply a click handler on each child sprite, but when I execute the click on any of the sprites, it always returns the last child.

I have tried various suggestions on Stack Overflow eg here: JavaScript closure inside loops – simple practical example

but can never get the click to return anything other than the last item.

An Example:

let items = //my container with 4 child sprites to click on
let i = 0;
item.list.forEach(function(obj) {
    obj.setInteractive();
    (function(i) {
        obj.on('pointerdown', function(i){
            console.log(i);
        }.bind(this, i));
    })(i);
    i++;
});

In this example, every sprite I click on outputs '3' tot he console, when it should output 0,1,2 or 3 depending on which was clicked.



Solution 1:[1]

Your code is abit complicated. If you just want to add a EventHandler just, you don't need an extra closure. Just check the code below, for a leaner approach

Working example:

// Minor formating for stackoverflow
    document.body.style = "display: flex;flex-direction: column;";    

    var config = {
        type: Phaser.AUTO,
        width: 536,
        height: 183,
        scene: {
            create
        },
        banner: false
    }; 

    function create () {
        let items = this.add.container(10, 10);
        items.add(this.add.sprite(20, 20, 'sprite'));
        items.add(this.add.sprite(20, 60, 'sprite'));
        items.add(this.add.sprite(20, 100, 'sprite'));
        items.list.forEach(function(obj, index) {
            obj.setInteractive();
            obj.on('pointerdown', function(){
                console.log(`You clicked: sprite with index ${index}`);
            }, this); // although I don't know why you would want do bind this "this"
       });
    }

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

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1