3

キーダウンイベント(文字k)を押し続けていると、次のキーダウンイベントが3000ミル遅くならないのはなぜですか?指を下に向けたままにすると、mcountにsetTimeoutがないため、カウントが急速に増加します。何故ですか?各カウントの間に遅延があるはずですが、私はそれを機能させることができません...

var mcount = 0;
function playershoot() {
if(!game.playerHit){ 
      $(document).keydown(function(e){ 
        switch(e.keyCode){
        case 75: 
        clearTimeout();
        setTimeout(console.log(mcount++), 3000);
        break;
        }
    });
}

}
playershoot();

アドバイスをいただければ幸いです。

ありがとう

4

5 に答える 5

6

1.:でクリアできるsetTimeout()a を返します。あなたはそれをしていません...したがって、3秒の遅延の後、これらすべてのタイムアウトが連続して呼び出されます。timeoutIdclearTimeout(timeoutId)

2.:次のconsole.logように関数でラップしなかったため、すぐに実行されます。

setTimeout(function() { console.log(mcount++) }, 3000);
于 2012-09-27T20:38:54.420 に答える
4

setTimeout遅延は発生しませんが、指定された時間の経過後にイベントを発生させるタイマーを開始します。

Javascript で「スリープ」することはできません。イベントを処理できるようにコードをリファクタリングする必要があります。あなたのコードでは、最初のキー押下時にフラグを設定する必要があるようです。次に戻り、フラグがクリアされたときに新しいキー押下のみを許可します (つまり、応答のみ)。フラグは、 で一定時間後に自動的にクリアできますsetTimeout

于 2012-09-27T20:38:03.580 に答える
4

@Norguard が言ったことに合わせて、実装を次に示します: http://jsfiddle.net/apu3P/

this.fire = function(){
    var cFire = new Date();

    if ((cFire - lastFire) / 1000 > 1/me.fireRate){            
        // code to fire the projectile
        lastFire = cFire;
    }
};

プレイヤーがfireRate1 秒間に何回発砲できるかを示す整数として設定しました。

デモでは、発射速度の異なる 3 人のプレイヤーを設定しました。スペースバーを押したままにすると、これが実際に動作しているのを見ることができます。

于 2012-09-27T21:38:51.453 に答える
2

ここにいる誰もが正しいですが、彼らが見逃しているのは、呼び出されるイベントではなく、発射を遅らせる必要があるということです...

キーダウン イベント内で、タイムスタンプを設定し、イベントの前の時間と現在の時間を設定します。関数内に time_limit があります。

そのため、キーを押す (またはキーが繰り返し発火する) ときは、次の点を確認してください。

current_time - last_fired >= rate_limit;

現在の時間が最後のショットから 3000 ミリ秒を超えている場合は、last_firedタイムスタンプを現在の時間に設定し、武器を発射します。

編集

次の簡単な例を考えてみましょう:

var Keyboard = {};

var player = (function () {
    var gun = {
            charging  : false,
            lastFired : 0,
            rateLimit : 3000
        },

        controls = { shoot : 75 },

        isHit = false,
        public_interface;


    function shoot () {
        var currentTime = Date.now();

        if (gun.rateLimit > currentTime - gun.lastFired) { return; }
        /* make bullet, et cetera */

        gun.lastFired = currentTime;
    }

    function update () {
        if (Keyboard[controls.shoot] || gun.charging) { this.shoot(); }
        // if key was released before this update, then the key is gone...
        // but if the gun was charging, that means that it's ready to be fired

        // do other updates
    }

    function draw (ctx) { /* draw player */ }

    public_interface = {
        shoot : shoot,
        damage : function (amt) { isHurt = true; /* rest of your logic */ }
        draw : draw,
        update : update
    };

    return public_interface;

}());


document.addEventListener("keydown", function (e) {
    // if key is already down, exit
    if (!!Keyboard[e.keyCode]) { return; }
    // else, set the key to the time the key was pressed
    // (think of "charging-up" guns, based on how long you've held the button down)
    Keyboard[e.keyCode] = e.timeStamp;
});

document.addEventListener("keyup", function (e) { delete Keyboard[e.keyCode]; });

ゲームループ内では、少し異なることを行います:
プレーヤーは自分自身を更新します。
そのアップデートの中で、それはキーボードにシュートキーが押されているかどうか尋ねています。
そうであれば、shoot メソッドを呼び出します。

これはまだ 100%正しいとは言えません。プレイヤーはキーボードを気にしたり、知ったりするべきではありません。
を求めるのではなく、何らかのサービスを通じて処理する必要がありますwindow.Keyboard。関係なく...

keyCodeコントロールはプレーヤー内にラップされるようになりました。そのため、あらゆる場所で尋ねるのではなく、それらのコントロールが何であるかを定義できます。

イベントは、キーを設定して終了するという本来の処理を実行しています。
現在の反復では、ブラウザーが起動するたびにkeydown、必要に応じて 300x/秒になる可能性があります。そのイベントは、すべてのプレーヤー ロジックを呼び出す必要もあります... 300x /秒...

大規模なゲームでは、これをさらに一歩進めて、 と からコンポーネントを作成しControlsHealthそれぞれが独自の仕事を行うために必要なすべてのプロパティとすべてのメソッドを持ちます。

このようにコードを分割すると、さまざまな銃を持つことも非常に簡単になります。コンポーネント
を想像してみてください。 在庫にはさまざまな. それぞれが独自のを持ち、独自の を持ち、独自のを持ち、独自のを実行し、独自の を起動します。Inventory
guns
gunrateLimitlastFiredbulletCountdamagebulletType

したがって、あなたは を呼び出しplayer.shoot();、内部では を呼び出しますinventory.equipped.shoot();
その内部関数は、装備された銃を発砲するためのすべてのロジックを処理します (なぜなら、あなたはinventory.add(Gun);自分の銃とinventory.equip(id);、あなたが望む銃を必要とするからです.

于 2012-09-27T20:45:17.400 に答える
1

setTimeout の戻り値を clearTimeout に渡す必要があります。キャンセルします。

var mcount = 0,timeout;
    function playershoot() {
    if(!game.playerHit){ 
          $(document).keydown(function(e){ 
            switch(e.keyCode){
            case 75: 
            clearTimeout(timeout );
            timeout = setTimeout(function(){
                       console.log(mcount++);
               }, 3000);
            break;
            }
        });
    }

    }
    playershoot();
于 2012-09-27T20:39:59.320 に答える