ZoomBox Posted June 18, 2014 Share Posted June 18, 2014 My problem is simple: I have a class that extends the Sprite class.In the constructor I have this:Piece=function(_game, _x, _y) { this.events.onInputDown.add( this.init(); );};The problem is (obviously?) that when I click on an object of the Piece class, "this" doesn't refers to the class but to my index page... I know how to do in plain javascript but it doesn't work in Phaser. Please HELP Thank you Link to comment Share on other sites More sharing options...
lewster32 Posted June 18, 2014 Share Posted June 18, 2014 Phaser is plain JavaScript, but there are many ways to write JavaScript and each may affect the value of 'this', often in difficult to determine ways. It doesn't look like your syntax is correct as you're trying to call a function inside the add method, rather than pass the function to it (a subtle diffference). Calling functions typically means the function statement ends with () or (parameter, parameter2) etc. When passing the function, you leave off the parentheses. Also, all of the signals Phaser uses for events let you pass a context as the last parameter. At a guess, I'd say try this:Piece=function(_game, _x, _y) { this.events.onInputDown.add(this.init, this);}; Link to comment Share on other sites More sharing options...
eguneys Posted June 18, 2014 Share Posted June 18, 2014 add function takes a callback and a callbackContext http://docs.phaser.io/Phaser.Signal.html#addvar callback = function() { this.init();};this.events.onInputDown.add(callback, this);Alternatively you can use 'bind' to set the function context yourself.var callback = function() { this.init(); };this.events.onInputDown.add(callback.bind(this)); codevinsky 1 Link to comment Share on other sites More sharing options...
ZoomBox Posted June 18, 2014 Author Share Posted June 18, 2014 Oh nice, it works, I was close with my tests...But I still have a problem (because I simplificated too much the first post): Actually, the callback function I call is in an other object which uses "this" to refer itself. And now, with your solution, in my other object's callback function, "this" refers to the original Piece object... Here is the example:piecesManager = new PiecesManager();Piece=function(){ this.events.onInputDown.add(piecesManager.init, this);}PiecesManager=function(){}PiecesManager.prototype.init=function(_piece){ console.log(_piece); // perfectly working, refering to the Piece caller console.log(this); // not working, refering to the Piece caller too :-(}(thank you very much for your time) Link to comment Share on other sites More sharing options...
lewster32 Posted June 18, 2014 Share Posted June 18, 2014 Piece=function(){ this.events.onInputDown.add(piecesManager.init, piecesManager);}Maybe? haden 1 Link to comment Share on other sites More sharing options...
eguneys Posted June 18, 2014 Share Posted June 18, 2014 Take a look at this: http://stackoverflow.com/questions/337878/var-self-this Link to comment Share on other sites More sharing options...
ZoomBox Posted June 19, 2014 Author Share Posted June 19, 2014 @lewster32: It would work I think, but it's not very clean. It doesn't make sense to me to pass the piecesManager as parameter since it's a global variable, I could just use the variable in my class like this:PiecesManager.prototype.init=function(_piece){ console.log(piecesManager); // it obviously works but seems REALLY strange to use a reference to the pieceManager instead of "this" inside the class itself}And I still need my piece to be in the arguments (but I could pass them in an Array I know). @eguneys: Thank you for the article but it's quite the same as having a global variable in my case. This kind of things will forever be blurry for me I guess :-(Thank you for your time, for the moment, I use the global variable solution which I find dirty as hell. Link to comment Share on other sites More sharing options...
lewster32 Posted June 19, 2014 Share Posted June 19, 2014 My syntax is slightly different (pretty much equivalent to the syntax that TypeScript outputs) but here's how I'd usually craft an object manager pattern:var PiecesManager = (function() { function PiecesManager() { // constructor this._pieces = []; } PiecesManager.prototype.init = function() { // instance method - 'this' here always refers to the PiecesManager *instance* created when 'new' is used }; PiecesManager.doSomething = function() { // static method - 'this' here always refers to this original object (i.e. PiecesManager itself, the 'class' all instances derive from) }; PiecesManager.prototype.add = function(piece) { this._pieces.push(piece); }; PiecesManager.prototype.alert = function(text) { alert(text); }; // factory method to easily allow you to create new pieces in the manager // essentially the same as how Phaser's factory methods work PiecesManager.prototype.create = function(x, y) { var newPiece = new Piece(this, x, y); this.add(newPiece); return newPiece; }; return PiecesManager;})();var Piece = (function() { function Piece(piecesManager, x, y) { // constructor this._piecesManager = piecesManager; // keep a reference to the manager this._piecesManager.add(this); // add this piece to the provided manager this.x = x; this.y = y; } // an instance method that calls a function on the manager Piece.prototype.managerAlert = function(text) { this._piecesManager.alert(text); }; return Piece;})();// usagevar piecesManager = new PiecesManager();var piece1 = piecesManager.create(0, 0); // create a new Piece within the manager (easier)piece1.managerAlert("Hello!"); // get the piece to alert the message "Hello!" through its managervar piece2 = new Piece(piecesManager, 10, 10); // instantiate a piece manually (the instance's constructor will ensure it's added to the manager if one is provided)I find this way of writing JS makes scope easier to think about, and this pattern (the factory pattern) works very well for situations where you have interdependent parent-child relationships, such as in the case of objects and object managers. ZoomBox 1 Link to comment Share on other sites More sharing options...
ZoomBox Posted June 19, 2014 Author Share Posted June 19, 2014 Wow thank you for the explanation.You couldn't be closer to what I've done at the moment, it ensures me that it's the best way not to be annoyed with scopes problems.I noticed that Phaser works like that too: Always store a reference to the parent. Thank you very much, it's the most pretty way I found (less dirty ? haha), it's simple and working.Thank you :-D lewster32 1 Link to comment Share on other sites More sharing options...
Recommended Posts