Sign in to follow this  
BeachBum

getting game context from within an event handler

Recommended Posts

I feel like I'm just bad at Javascript to have to ask this question so please keep the disparaging remarks to a minimum.

 

I have some game handling taking place on a server and being sent back to the game via JSON like this:

Strategy.Game.prototype = {    create: function() {        this.greenGroup = this.add.group();        this.greenGroup.create(100,100, 'greenParticle');        this.getPath();    },    getPath: function() {        $.getJSON("http://mysite.com/strategy/ajax/play.ashx", function (data) {            console.log(JSON.stringify(data));            data.forEach(function(step)) {                // need access to "game.greenGroup" here to create group entities and move existing ones.            }        });    }} 

There is more to the game obviously but hopefully you get the idea.  I need to access game entities as I would normally have done with "this.greenGroup" but within the event handler the context has changed.  I've tried pulling up the javascript console and seeing if I could track down how to reference the game object but I haven't found it.  I can reference the class but it's not the actual working game object. Strangely the ways I've found to reference the game class the greenGroup is always undefined.

 

Any idea where I've lost it?

Share this post


Link to post
Share on other sites

This is usually done via local variables, saving the 'this' context so you can use it inside functions which steal 'this' for themselves:

Strategy.Game.prototype = {    create: function() {        this.greenGroup = this.add.group();        this.greenGroup.create(100,100, 'greenParticle');        this.getPath();    },    getPath: function() {        // Store 'this' (the state in this case) in a temporary local variable which will live        // as long as anything in this function is executing, including functions within functions        // - this is what you commonly hear referred to as 'closure' in JavaScript.        var self = this;        $.getJSON("http://mysite.com/strategy/ajax/play.ashx", function (data) {            console.log(JSON.stringify(data));            data.forEach(function(step) {                // self.greenGroup will be accessible here and anywhere else within 'getPath'                // regardless of the amount of nested functions.            });        });    }} 

Share this post


Link to post
Share on other sites

There is also another way. If you don't need the value of the "this" variable within the event handler, you can override it by using "bind()". In your case this would look like:

Strategy.Game.prototype = {    create: function() {        this.greenGroup = this.add.group();        this.greenGroup.create(100,100, 'greenParticle');        this.getPath();    },    getPath: function() {        $.getJSON("http://mysite.com/strategy/ajax/play.ashx", function (data) {            console.log(JSON.stringify(data));            data.forEach(function(step)) {                // need access to "game.greenGroup" here to create group entities and move existing ones.            }        }.bind(this));    }} 

By Adding ".bind(this) at the end, you have overridden the default value of this within the handler with the local value. If you don't need the local value, that's certainly on option.

 

.bind() actually works with multiple arguments to, but I don't think that helps you here. 

 

for instance, if you used .bind(this, "bla") instead of just .bind(this), then the value of the "data" argument in the function will also change to "bla".

 

 

.bind() is somewhat related to .call() and .apply(). Here's some reading that explains it in more detail: http://dailyjs.com/2012/06/25/this-binding/

 

Basically, .bind is used to say "when you later call this function, call it with the context I'm telling you to use". On the other hand, .call() and .apply() both mean "call this function now with this context" except there's a minor, but potentially important difference in how you specify the context between those two.

Share this post


Link to post
Share on other sites

Realised that would probably cause a syntax error. Yeah, bind is another way to do this, but the one drawback is that if you have multiple nested functions, you'll have to add bind(this) to each one in order for 'this' to be passed through them, whereas a local variable will be accessible regardless.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.