I’ve created a grid of level icons each with a number and add an handler to each icon, see code below.
However, in the pointerdown handler as input I only see a pointer, x,y coordinates and an Object:StopPropagation (whatever that is), the parameters do not include the sprite, is that correct?
My question is: In the pointerdown event handler, how can I retrieve the sprite that called the handler so that I can use its getData() method?
create: function ()
{
// add all level select icons
var index = 0;
for (var y=0; y < LEVEL_SELECT_Y; y++) {
for (var x=0; x < LEVEL_SELECT_X; x++) {
// next position
var xpos = 96 + x * 96;
var ypos = 128 + y * 96;
// add panel icon and add number
var icon1 = this.add.image(xpos, ypos, "sprites", "select1");
var txt = this.add.bitmapText(xpos, ypos-6, "fontwhite", ""+(index+1), 40);
txt.setOrigin(0.5).setCenterAlign();
// store level index in data of sprite, to use in the pointerdown handler
icon1.setData("index", index);
// add input handler
icon1.setInteractive();
icon1.on('pointerdown', this.onLevelIconDown.bind(this));
// next level index
index++;
};
};
},
onLevelIconDown: function(pointer, x, y, PropagationObj) {
debugger;
// ?? how to determine which sprite called onLevelIconDown ??
},
In my code, I would normally write the handler in-line so that I would have icon1 in scope through a closure. However, that is a good question on how to use a separate handler method and refer back to the source game object since all of the targets in the pointer event are DOM-generated and only refer to the canvas itself (in non-game development JS, that is how you would get a reference to the event target).
I would also be interested in a good strategy for handling this.
Looking at the Destroy Sprite On Down Event example, it seems that in Phaser3 you can only set a global handler for ALL gameobjects in the scene, not for individual game objects.
The only downside is that ALL interactive objects will call this handler. If you also have other interactive images (like a back-button etc) they will also trigger the gameobjectdown-handler when clicked. So unless there is a way to set the handler for each sprite, I think I’ll change my code to something like this:
create: function ()
{
// add all level select icons
var index = 0;
for (var y=0; y < LEVEL_SELECT_Y; y++) {
for (var x=0; x < LEVEL_SELECT_X; x++) {
// next position
var xpos = 96 + x * 96;
var ypos = 128 + y * 96;
// add panel icon and add number
var icon1 = this.add.image(xpos, ypos, "sprites", "select1");
var txt = this.add.bitmapText(xpos, ypos-6, "fontwhite", ""+(index+1), 40);
txt.setOrigin(0.5).setCenterAlign();
// store level index in data of sprite, to use in the pointerdown handler
icon1.setData("levelindex", index);
// add input handler
icon1.setInteractive();
// next level index
index++;
};
};
// set down handler for all interactive objects in scene
this.input.on('gameobjectdown', this.onGameObjectDown, this);
},
onGameObjectDown: function(ptr, img) {
// get level index from sprite
var levelindex = img.getData("index");
// make sure level icon was clicked, in that case levelindex is defined
if (typeof levelindex !== "undefined" ) {
// etc.
};
},
There is a way to avoid the global event listener if you want to, by the way. Your old code already used bind to set the handler’s context. bind can receive additional arguments, which will be passed to the function. So, if you instead use this.onLevelIconDown.bind(this, icon1), the handler will receive the icon as the first argument, followed by the pointer and the coordinates.
As a side note, the fourth argument (the one with the stopPropagation function) is the event object itself. You can call that function to stop the event from propagating to lower game objects or scenes.