2

重複の可能性:
キーが押されたときにキーダウンイベントを自動的に繰り返すクロスブラウザの方法

JavaScript/CSS/HTML で簡単なゲームを作成しようとしています。キーの押下を処理するために jQuery (および少しのアンダースコア) を使用しています。プレーヤーは矢印キーを使用してブロックを制御します。複数のキープレスを同時に処理する際に問題が発生しました。クロージャーが押されたすべての矢印キーを追跡するシステムを導入しています。これは、プレーヤーが次の順序でキーを押す場合にうまく機能します。

  1. プレーヤーが下を押す (ブロックが下に移動)
  2. プレーヤーが左を押す (ブロックが左斜め下に移動する)
  3. プレーヤーが下を離す (ブロックが左に移動)
  4. プレーヤーが左を放します (ブロックが停止します)

ただし、ステップ 3 と 4 を逆にすると、ブロックは停止します。その場合、実際に何が起こるかを次に示します。

  1. プレーヤーが下を押す (ブロックが下に移動)
  2. プレーヤーが左を押す (ブロックが左斜め下に移動する)
  3. プレイヤーが左を離す (ブロックが止まる)

予想される動作は、ステップ 3 でブロックが完全に停止するのではなく、下に移動し続けることです。

コードに入力したトレースから、指で矢印キーの 1 つを押したままにしている場合でも、keyup イベントが実際にそれ以上の keydown イベントの伝播を停止しているように見えます。

関連するコードのスニペットを次に示します。問題がどこにあるのか誰か教えてもらえますか?

// Creates an animation handler for a specific element.
// Animation reacts to any changes as they are submitted
var getMovementAnimator = function(element) {
    var params = {},
        $element = $(element);
    return function(changes) {
        _.each(changes, function(val, key) {
            // Remove null or zeroish keys from animation params
            if ( (val == 0 || !val) && _.has(params, key)) {
                delete params[key];
            } else {
                params[key] = '+=' + val + 'px';
            }
        });
        $element.animate(params, {duration: 0, queue: false});
        console.log(params);
    };
};

// Determines direction and speed of movement for an element
// after a keypress event
var getMovementChange = function(keyEvent, keydown) {
    var isMoving = !!keydown,
        params   = {},
        dir      = '',
        speed    = keydown ? 5 : 0,
        arrows   = {left: 37, up: 38, right: 39, down: 40};
    switch (keyEvent.which) {
        case arrows.left:
            dir = 'left';
            speed = -speed;
            break;
        case arrows.up:
            dir = 'top';
            speed = -speed;
            break;
        case arrows.right:
            dir = 'left';
            break;
        case arrows.down:
            dir = 'top';
            break;
    }
    // If key hit not one of above, do nothing
    if (!dir) {
        return false;
    }
    if (!speed) {
        console.log('key up: ', dir);
    }
    params[dir] = speed;
    return params;
}

// Sets up key handlers
$(document).ready(function() {
    var board = $('#board'),
        animatePlayer = getMovementAnimator('.player');
    $(document).keydown(function(e) {
        e.preventDefault();
        var changes = getMovementChange(e, true);
        animatePlayer(changes);
    }).keyup(function(e) {
        e.preventDefault();
        var changes = getMovementChange(e, false);
        animatePlayer(changes);
    });
});
4

1 に答える 1

0

適切なキーワードを使用して Stack Overflow をさらに検索すると、発生している問題は実際にはコードのバグではないことがわかりました。むしろ、これはオペレーティング システムの予想される動作です

ただし、問題を解決すると思われる回避策を見つけました。

于 2013-01-03T20:48:03.170 に答える