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。これを行う1つの方法は、の値を変数に格納することですthis。変数は、無名関数(クロージャ)によって閉じられます。

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

編集:

2番目の質問に答えるには、(キャラクターのような)スプライトをアニメーション化するためのより良いアプローチは、キャ​​ラクターの速度を保存し、その情報に基づいてスプライトの次の位置を計算する単一のゲームループを作成することです。非常に単純な例は次のようになります。

// 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メソッドを使用することです。あなたはそれをクロスブラウザ互換にするグーグルでjavascriptファイルを見つけることができます。

次に、関数が呼び出されるたびに、フレーム化してからそれに応じてスプライトを移動するまでの経過時間を確認する必要があります。それはより多くの作業ですが、そうすれば、ゲームはどのマシンでも同じペースで実行されます。

于 2013-01-28T22:03:28.970 に答える