1

所以我有一个围绕网格移动的小方块,但是当我执行 onkeydown 事件时,我的方块移动得非常快。我只希望它每 10 秒执行一次,这样我的小方块就不会碰到剪刀。但是当我尝试 setTimeout 函数时,它只会在第一次按键时超时,然后继续快速执行,当您释放按键时,它仍在执行以赶上。这对我的小广场很不安全。任何帮助将非常感激。

这是没有 setTimeout 函数的代码,只是因为我觉得这不是正确的方法:

function checkArrowKeys(e){
    var arrs= [], key= window.event? event.keyCode: e.keyCode;
    arrs[37]= 'left';
    arrs[38]= 'up';
    arrs[39]= 'right';
    arrs[40]= 'down';
    if(arrs[key]){
        transition(arrs[key]);
    }
}
document.onkeydown=checkArrowKeys;
4

2 回答 2

1

如果您的预设延迟没有发生,您可以通过退出该功能来停止执行过渡。

var bWait=false;
function checkArrowKeys(e){
    if (bWait) return;
    var arrs= [], key= window.event? event.keyCode: e.keyCode;
    arrs[37]= 'left';
    arrs[38]= 'up';
    arrs[39]= 'right';
    arrs[40]= 'down';
    if(arrs[key]){
        transition(arrs[key]);
    }
    bWait=true; //wait for 10 milliseconds
    window.setTimeout("bWait=false;",10);
}
document.onkeydown=checkArrowKeys;

你怎么看?

于 2012-12-22T21:19:22.210 回答
1

键盘响应可能会变得异常复杂。通常你不想关注每个被触发的 keydown 事件,因为这取决于用户的键盘和设置;例如,一个事件最初触发,然后在暂停后触发快速流。当用户同时按住两个键时,还有一个问题。

以下代码通过单独的更新函数将键盘响应与动画分开。按下新的箭头键后,方块最初移动 1 步(设置为 5px),然后在 100 毫秒后连续移动,直到释放键。

小提琴

var directions = [],
    lastPressTime, stepped, ti, frameRate = 30,
    squareSpeed = 5, stepTime = 100;

function update() {
    var x, y, d = directions[directions.length - 1],
        square = document.getElementById('square');
    if (!d) {
        return;
    }
    if (new Date().getTime() < lastPressTime + stepTime) {
        if (stepped) { // already stepped and <100ms has passed
            return;    // so do nothing
        }
        else {
            stepped = true;
        }
    }
    x = square.offsetLeft;
    y = square.offsetTop;
    if (d == 'left') {
        x -= squareSpeed;
    }
    else if (d == 'right') {
        x += squareSpeed;
    }
    else if (d == 'up') {
        y -= squareSpeed;
    }
    else if (d == 'down') {
        y += squareSpeed;
    }
    square.style.left = x + 'px';
    square.style.top = y + 'px';
}
function checkArrowKeys(e) {
    var arrs = [],
        key = window.event ? event.keyCode : e.keyCode;
    arrs[37] = 'left';
    arrs[38] = 'up';
    arrs[39] = 'right';
    arrs[40] = 'down';
    if (arrs[key]) {
        return arrs[key];
    }
}
document.onkeydown = function(e) {
    var d = checkArrowKeys(e);
    if (d) {
        // Key not already pressed; add it to array 
        // of directions and step forward
        if (directions.indexOf(d) === -1) {
            directions.push(d);
            lastPressTime = new Date().getTime();
            stepped = false;
        }
        if (!ti) {
            ti = setInterval(update, 1000 / frameRate);
        }
    }
};

document.onkeyup = function(e) {
    var d = checkArrowKeys(e),
        i;
    if (d) {
        i = directions.indexOf(d);
        // remove this direction from the array of directions
        if (i > -1) {
            directions = 
                directions.slice(0, i).concat(directions.slice(i + 1));
        }
        // if no keys are down then stop updating
        if (directions.length === 0) {
            clearInterval(ti);
            ti = null;
        }
    }
};
于 2012-12-22T22:52:28.520 回答