Jump to content

Call a function with arguments when onInputDown?


Martiny
 Share

Recommended Posts

I have this code right here:

 

 image.events.onInputDown.add(clickListener, this);

 

It calls the function clickListener, but I'm confused with the rest. I was taking a look at the source and I didn't find any way to pass an argument to clickListener when I clicked on my sprite.

 

I wonder if there is a way of passing arguments to a function when I click down a sprite (onInputDown)?

Link to comment
Share on other sites

bmceldowney's solution is probably more simple than mine, but there is another solution in case you don't want to create a new object.

 

This solution uses a feature of JavaScript called a "closure". Basically, whenever you use Signal.add (like with onInputDown.add) you will pass a function that takes no parameters:

 

onInputDown.add(myNoArgumentFunction);

 

But this is only good if the function you want it to call doesn't need arguments.

 

So you might be tempted to wrap your function WITH arguments in a function WITHOUT arguments, which would leave you a function like this:

 

onInputDown.add(function(){myArgumentFunction(someVar)});

 

The problem with that is that you aren't actually creating a new function, so if you set up input on a loop of 3 items, you may always use the last value assigned to the variable.

 

In my example you actually pass into add() the result of a function that generates a no argument function. You can see the pitfall on the first row, and the working solution on the second row.

Here is a fiddle containing my solution:

http://jsfiddle.net/adamholdenyall/wk6T3/1/

 

Like it said, it may be overkill and the other solution may be a better fit, but closures are important to JavaScript and a good tool to have available.

Further reading: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures

Link to comment
Share on other sites

Thanks for the reply. I actually ended up with a solution, I just didn't post it before because I thought my topic was forgotten. I need two parameters for my function, the image that was clicked and one array - for other stuff.

 

I ended up doing this:

 

image.events.onInputDown.add(function(image){clickListener(image, array)}, this);

 

I create a anonymous function that will call my function clickListener with the arguments I want. 

 

I observed that the second parameter of add, the "this", will be the image I clicked and will be passed as the first argument in the function you put inside it.  That's why in my anonymous function I put a parameter called "image" that will receive "this" (the context, the image what was clicked), and then passed it into my clickListener once again, with one more argument (the "array", which I needed).

 

 

Sorry if what I said was confusing. I tried reading Phaser code to try to understand how the add function worked, but with no success. I didn't understand nothing. It's kind of sad that my code is based on "magic" - things I don't understand - , but that's the only way I know how to do it now. I'll read your links and study more Javascript.

Link to comment
Share on other sites

  • 1 year later...

bmceldowney's solution is probably more simple than mine, but there is another solution in case you don't want to create a new object.

 

This solution uses a feature of JavaScript called a "closure". Basically, whenever you use Signal.add (like with onInputDown.add) you will pass a function that takes no parameters:

 

onInputDown.add(myNoArgumentFunction);

 

But this is only good if the function you want it to call doesn't need arguments.

 

So you might be tempted to wrap your function WITH arguments in a function WITHOUT arguments, which would leave you a function like this:

 

onInputDown.add(function(){myArgumentFunction(someVar)});

 

The problem with that is that you aren't actually creating a new function, so if you set up input on a loop of 3 items, you may always use the last value assigned to the variable.

 

In my example you actually pass into add() the result of a function that generates a no argument function. You can see the pitfall on the first row, and the working solution on the second row.

Here is a fiddle containing my solution:

http://jsfiddle.net/adamholdenyall/wk6T3/1/

 

Like it said, it may be overkill and the other solution may be a better fit, but closures are important to JavaScript and a good tool to have available.

Further reading: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures

 

I don't know as of what version of Phaser but I know that Phasr 2.3.0 "Tarabon", using a named function instead of an anonymous one will cause an error. You must wrap a named function within an anonymous one.

var el = image;    el.anotherObject = {foo : 'bar'};// el gets passed to the named function as an argument in your anon functionimage.events.onInputUp.add( function(el){ namedFunction(game, el) }, game);function namedFunction(game, el){	 // game - will give you the game object // el - acts as e.target // arg2 - is whatever you want to pass through	}

This worked for me since I was trying create images that expand when you click them, and shrink back down when you click them again.

Link to comment
Share on other sites

  • 1 year later...
  • 5 months later...
On 8/12/2016 at 5:25 PM, drhayes said:

You can also pass parameters to your function via add like this:


image.events.onInputDown.add(this.clickListener, this, 0, arg1, arg2, arg3);

Those extra things after the "0" will get passed to your function when it gets called.

Weird, in 2.6.2, when I use this, the parameter that is passed is actually 'image'. I tried this.clickListener.bind(this) - same story. 

Link to comment
Share on other sites

1 hour ago, drhayes said:

The extra args get passed after the args the particular signal passes you. In the case of onInputDown, that's the game object that received the event and the pointer that caused it.

So how would you construct it? Like this, maybe? : 

this.image.events.onInputDown.add(this.function, this, 0, null, 'string parameter');
Link to comment
Share on other sites

You don't need that null after the 0 unless that is what you're passing as your extra param.

Say I have a signal: "this.onCatpants = new Phaser.Signal();" You come along and add a listener like this: "thing.onCatpants.add(this.myCatpantsListener, this, 0, 'a', 'b', 'c');". Now, your function, "this.myCatpantsListener", will look like this: "myCatpantsListener: function(one, two, three, four, five) {}". Then I dispatch it like this: "this.onCatpants.dispatch(1,2);". Your "myCatpantsListener" function will get invoked with one = 1 (from my dispatch), two = 2 (also from my dispatch), three = 'a', four = 'b', five = 'c' (all from when you attached the listener). Make sense?

Here's the code for Phaser.Signal.add: https://github.com/photonstorm/phaser/blob/0df61f30572d0cd44916c3f6007b7f1904efb20d/v2/src/core/Signal.js#L256 Trace it through _registerListener to see it create the SignalBinding and how it handles the extra args.

Here's the code for Phaser.SignalBinding.execute: https://github.com/photonstorm/phaser/blob/0df61f30572d0cd44916c3f6007b7f1904efb20d/v2/src/core/SignalBinding.js#L109 Check out what it does on line 119 where it concats the params that just got passed and the args from when the listener got added.

Link to comment
Share on other sites

  • 5 weeks later...
On 1/17/2017 at 6:36 PM, drhayes said:

You don't need that null after the 0 unless that is what you're passing as your extra param.

Say I have a signal: "this.onCatpants = new Phaser.Signal();" You come along and add a listener like this: "thing.onCatpants.add(this.myCatpantsListener, this, 0, 'a', 'b', 'c');". Now, your function, "this.myCatpantsListener", will look like this: "myCatpantsListener: function(one, two, three, four, five) {}". Then I dispatch it like this: "this.onCatpants.dispatch(1,2);". Your "myCatpantsListener" function will get invoked with one = 1 (from my dispatch), two = 2 (also from my dispatch), three = 'a', four = 'b', five = 'c' (all from when you attached the listener). Make sense?

Here's the code for Phaser.Signal.add: https://github.com/photonstorm/phaser/blob/0df61f30572d0cd44916c3f6007b7f1904efb20d/v2/src/core/Signal.js#L256 Trace it through _registerListener to see it create the SignalBinding and how it handles the extra args.

Here's the code for Phaser.SignalBinding.execute: https://github.com/photonstorm/phaser/blob/0df61f30572d0cd44916c3f6007b7f1904efb20d/v2/src/core/SignalBinding.js#L109 Check out what it does on line 119 where it concats the params that just got passed and the args from when the listener got added.

Thank you, I got it now :)

Link to comment
Share on other sites

  • 1 month later...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...