I am trying to create an avatar that will turn to follow my mouse.
I have successfully created a working avatar, and now I want to create an identical one with an object constructor. Basically everything is the same, except when I would've typed var angleToBe;
I would write this.angleToBe;
. Everything is linked directly to the constructor. I didn't have any problems until I got to the methods, specifically the turnToMouse
one. My syntax looks like this:
Avatar.prototype.turnToMouse = function() {
if (this.canTurn) {
this.spotX = this.body.position.x;
this.spotY = this.body.position.y;
this.spotY = this.spotY * -1 + height;
this.body.angleToBe = Math.atan2(cursorX - this.spotX, cursorY - this.spotY);
this.body.__dirtyRotation = true;
this.body.__dirtyPosition = true;
this.gun.__dirtyRotation = true;
this.gun.__dirtyPosition = true;
this.body.rotation.set(0, 0, avatarAngleToBe);
}
setTimeout(this.turnToMouse, time);
};
Avatar is the constructor.
Essentially, this function just continually turns the avatar (and it's gun) to the direction of the mouse. This function will work fine, because it is exactly the same (apart from the this
's) as my current working function.
The problem I have is that when I put this code inside the constructor (which is function Avatar() {}
):
this.turnToMouse();
Which should be calling my function, the editor think's there is no function 'turnToMouse()
'.
Am I missing anything?
PS: if you want to see the code I have right now with the working avatar and the object avatar, click this link in google chrome.
JavaScript has a concept called hoisting. What this does is that some statements get "hoisted" to the top of the scope.
In your particular case, your function Avatar(...) { ... }
definition is hoisted so that it is available when you call new Avatar(...)
. If it wasn't, your code wouldn't get that far because Avatar
technically wasn't defined yet.
Where you run into issues however, is that not everything is hoisted. Your assignment to Avatar.prototype.turnToMouse
still happens after you call new Avatar(...)
which means the method doesn't exist yet when it runs!
To fix the issue, simply make sure you run new Avatar(...)
after you've assigned all Avatar.prototype
properties.
PS. If you didn't call the method in the constructor, it'd be okay because properties in the prototype are available even for instances created before they were assigned, just not available during execution until they've actually been assigned.
PPS. You will run into another issue with this
binding with regards to your setTimeout
call. To fix that just change it to:
var avatar = this;
setTimeout(function () { avatar.turnToMouse(); }, time);
Why that is, I'll leave for another answer but you can find resources online if you read up on function binding/context.