admin管理员组文章数量:1315347
I'm creating a simple game with a character that can jump, move right, and move left.
I'm having trouble with the jump function, which uses a setInterval
.
Here is the function:
jumpUp: function (speed) {
setInterval(function () {
this.yPos += 10;
this.playerElement.css("top", '-=' + 10);
alert("dude, im not moving....so stop trying"); //for some reson, this line works and other dont.
}, 100);
}
I should add that the code works without the setInterval
. I really don't have any idea why it's not working when I add the setInterval
.
My questions:
- What is stopping this code from running?
- Is
setInterval
a good way to make a character look like it jumping and landing? Or should i use different method?
EDIT 1:
fiddle
I'm creating a simple game with a character that can jump, move right, and move left.
I'm having trouble with the jump function, which uses a setInterval
.
Here is the function:
jumpUp: function (speed) {
setInterval(function () {
this.yPos += 10;
this.playerElement.css("top", '-=' + 10);
alert("dude, im not moving....so stop trying"); //for some reson, this line works and other dont.
}, 100);
}
I should add that the code works without the setInterval
. I really don't have any idea why it's not working when I add the setInterval
.
My questions:
- What is stopping this code from running?
- Is
setInterval
a good way to make a character look like it jumping and landing? Or should i use different method?
EDIT 1:
fiddle
Share Improve this question edited Jan 28, 2013 at 22:07 George 4,25726 silver badges34 bronze badges asked Jan 28, 2013 at 21:49 samysamy 1,9697 gold badges40 silver badges64 bronze badges 5- Would you post a jsfiddle? jsfiddle – Aaron Kurtzhals Commented Jan 28, 2013 at 21:50
- 2 You have a scope problem, using "this" in the context of an anonymous function in setInterval => you lost the context of the jumpUp function. – darma Commented Jan 28, 2013 at 21:52
-
this
is resolving towindow
at runtime – danronmoon Commented Jan 28, 2013 at 21:52 -
1
use
console.log
instead ofalert
, it doesn't stall execution of the script – Dharman ♦ Commented Jan 28, 2013 at 21:57 - 1 i added a fiddle of the class – samy Commented Jan 28, 2013 at 21:59
4 Answers
Reset to default 7The problem is your use of this
. When the function you pass to setInterval
is called, this
will be the global object (window
in browsers). You need to preserve the this
value from when you call setInterval
. One way of doing this is to store the value of this
into a variable, which will then be closed over by the anonymous function (which is a closure):
jumpUp: function (speed) {
var self = this;
setInterval(function () {
self.yPos += 10;
self.playerElement.css("top", '-=' + 10);
}, 100);
}
EDIT:
To answer your second question, a better approach to animating a sprite (like your character) is to store the character's velocity, and then have a single game loop that will calculate the next position of the sprite based on that information. A very simple example would look like:
// Somewhere else in the code:
function tick() {
// move player by player.velocity.x and player.velocity.y
// code to decelerate player gradually, stop player when they hit a wall/floor, etc...
// A very simple example:
if (player.velocity.y > 0) {
player.velocity.y -= 1
}
// call next tick() (setTimeout, or preferably requestAnimationFrame)
}
// In the player code:
velocity: {x: 0, y: 0},
jumpUp: function () {
this.velocity.y -= 10;
},
moveRight: function () {
this.velocity.x += 10;
}
As darma and danronmoon pointed out, you have a scoping problem with this.
Try the following code:
jumpUp: function (speed) {
var that = this;
setInterval(function () {
that.yPos += 10;
that.playerElement.css("top", '-=' + 10);
}, 100);
}
I added a variable, that, to maintain the reference to whatever this is supposed to be.
In addition to your closure problem, this is probably going to cause choppy jumping.
Here's another pattern that watches the clock to see how much time has elapsed between each call to the function (setInterval
is not consistent):
jumpUp: function (speed) // speed in pixels per second
{
var last = +new Date();
var c = this;
var jumptick = function ()
{
var interval = +new Date() - last;
c.yPos += speed * interval;
c.playerElement.css("top", c.yPos);
if (/* condition for reaching maximum height */) speed = -speed;
if (! /* condition for reaching ground */) setTimeout(jumptick);
// could add an interval but this will lead to fastest frame rate
};
jumptick();
}
Setinterval is not a good way to achieve this because it will use a lot a ressources. You also need to consider the framerate when you are moving your character, otherwise he will move fast on a fast machine/browser and slow on a slow machine.
A good method is using the requestAnimationFrame method. You can find a javascript file on google that will make it crossbrowser patible.
Then, everytime your function is called, you will need to check the time elapsed between to frame and move your sprites accordingly. It's more work but that way, your game will run at the same pace on any machine.
本文标签: javascriptAccessing 39this39 variable in function passed to setIntervalsetTimeoutStack Overflow
版权声明:本文标题:javascript - Accessing 'this' variable in function passed to setIntervalsetTimeout - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741976411a2408150.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论