4

我正在创建一个可以跳跃、向右和向左移动的角色的简单游戏。

我在使用跳转功能时遇到问题,它使用setInterval.

这是功能:

 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);
}

我应该补充一点,代码在没有setInterval. 我真的不知道为什么当我添加setInterval.

我的问题:

  1. 是什么阻止此代码运行?
  2. setInterval让角色看起来像跳跃和着陆的好方法吗?还是我应该使用不同的方法?

编辑1:

小提琴

4

4 回答 4

7

问题是您使用this. 当您传递给的函数setInterval被调用时,this将是全局对象(window在浏览器中)。您需要保留this调用时的值setInterval。这样做的一种方法是将 的值存储this到一个变量中,然后由匿名函数(这是一个闭包)将其关闭:

 jumpUp: function (speed) {
        var self = this;
        setInterval(function () {
            self.yPos += 10;
            self.playerElement.css("top", '-=' + 10);
        }, 100);
}

编辑:

要回答您的第二个问题,动画精灵(如您的角色)的更好方法是存储角色的速度,然后有一个游戏循环,该循环将根据该信息计算精灵的下一个位置。一个非常简单的示例如下所示:

// 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;
}
于 2013-01-28T21:53:25.560 回答
1

正如 darma 和 danronmoon 指出的那样,您对此有一个范围界定问题。

试试下面的代码:

jumpUp: function (speed) {
    var that = this;

    setInterval(function () {
        that.yPos += 10;
        that.playerElement.css("top", '-=' + 10);
    }, 100);
}

我添加了一个变量,以保持对应该是的任何内容的引用。

于 2013-01-28T21:55:09.373 回答
1

除了你的关闭问题,这可能会导致不连贯的跳跃。

这是另一种模式,它监视时钟以查看每次调用函数之间经过了多少时间(setInterval不一致):

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();
}
于 2013-01-28T22:02:57.153 回答
1

Setinterval 不是实现此目的的好方法,因为它将使用大量资源。移动角色时还需要考虑帧速率,否则他会在快速机器/浏览器上快速移动,而在慢速机器上移动缓慢。

一个好的方法是使用 requestAnimationFrame 方法。您可以在 google 上找到一个 javascript 文件,使其与跨浏览器兼容。

然后,每次调用您的函数时,您都需要检查帧之间经过的时间并相应地移动您的精灵。这需要更多的工作,但这样一来,您的游戏将在任何机器上以相同的速度运行。

于 2013-01-28T22:03:28.970 回答