Martiny

Call a function with arguments when onInputDown?

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)?

Share this post


Link to post
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

Share this post


Link to post
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.

Share this post


Link to post
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

 

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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites
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. 

Share this post


Link to post
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');

Share this post


Link to post
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.

Share this post


Link to post
Share on other sites
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 :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.