Martiny Posted April 2, 2014 Share Posted April 2, 2014 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)? Anny 1 Link to comment Share on other sites More sharing options...
Anny Posted April 7, 2014 Share Posted April 7, 2014 I have the same question, have you found a way to do this? Link to comment Share on other sites More sharing options...
bmceldowney Posted April 7, 2014 Share Posted April 7, 2014 The second parameter is the context of the listener. You could pass an object there like this:image.events.onInputDown.add(clickListener, {param1: value1, param2: value2});Then in the clickListener:function clickListener () { this.param1 // equal to value1 this.param2 // equal to value2} scofield, ekiscrim, Ralph and 7 others 10 Link to comment Share on other sites More sharing options...
adamyall Posted April 7, 2014 Share Posted April 7, 2014 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 juandelossantos, drhayes, wordyAllen and 1 other 3 1 Link to comment Share on other sites More sharing options...
bmceldowney Posted April 7, 2014 Share Posted April 7, 2014 Higher order functions are definitely a valid technique, particularly if you want to preserve the value of your context. You did a better job of explaining them than I would have. adamyall 1 Link to comment Share on other sites More sharing options...
Martiny Posted April 7, 2014 Author Share Posted April 7, 2014 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 More sharing options...
Jacobross85 Posted July 7, 2015 Share Posted July 7, 2015 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 More sharing options...
fitness23 Posted August 12, 2016 Share Posted August 12, 2016 Thank you so much @adamyall. You've helped me solve this issue I've been experiencing for several months. Link to comment Share on other sites More sharing options...
drhayes Posted August 12, 2016 Share Posted August 12, 2016 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. ozdy 1 Link to comment Share on other sites More sharing options...
fitness23 Posted August 12, 2016 Share Posted August 12, 2016 @drhayes why is 0 there in your example? I think this is why I was getting confused why it didn't work for me initially because logically you want to pass the first parameter through straight after "this, ". Link to comment Share on other sites More sharing options...
drhayes Posted August 12, 2016 Share Posted August 12, 2016 Logic or not, the third argument is the signal handler's priority. I've never used that feature and been safe passing in 0. Here's a link to the documentation: http://phaser.io/docs/2.6.1/Phaser.Signal.html#add Link to comment Share on other sites More sharing options...
Igor Georgiev Posted January 13, 2017 Share Posted January 13, 2017 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 More sharing options...
drhayes Posted January 13, 2017 Share Posted January 13, 2017 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. ozdy 1 Link to comment Share on other sites More sharing options...
Igor Georgiev Posted January 13, 2017 Share Posted January 13, 2017 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 More sharing options...
drhayes Posted January 17, 2017 Share Posted January 17, 2017 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 More sharing options...
Igor Georgiev Posted February 17, 2017 Share Posted February 17, 2017 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 drhayes 1 Link to comment Share on other sites More sharing options...
juandelossantos Posted April 4, 2017 Share Posted April 4, 2017 Thank @adamyall, your post was so useful!! Link to comment Share on other sites More sharing options...
Recommended Posts