在keydown上,使用JavaScript只运行一次计时器

时间:2015-08-22 02:28:35

标签: javascript jquery timer setinterval

我正在制作网页游戏,我想在用户启动游戏时调用计时器。基本上,我是怎么回事,当其中一个WASD键被击中时,启动计时器。问题是,如果您多次按键,它会每次启动计时器。我只想打电话给这个功能一次。我在考虑clearInterval(),但这会停止计时器。不理想。

这是我的代码。 (下面的小提琴链接)

我认为应该发生的是当按下任何键时,首先要检查fired是否等于false。如果是,请将其设置为true。然后,如果按下W,A,S或D键,启动计时器。

然后当密钥重新启动时,再次将fired设置为false。

var fired = false;
var timer = document.getElementById("timer");

var playerObj = {
    elapsedTime: 0,
    startTimer: function () {
        setInterval(function () {
            playerObj.elapsedTime += 1;
            timer.innerHTML = playerObj.elapsedTime;
        }, 1000);
    }
};

var fired = false;
document.onkeydown = function (e) {
    var w = e.keyCode == '87',
        a = e.keyCode == '65',
        s = e.keyCode == '83',
        d = e.keyCode == '68';
    if (!fired) {
        fired = true;
        if (w || a || s || d) {
           playerObj.startTimer();
        }
    }
};

document.onkeyup = function () {
     fired = false;
};

我提到了this question's回答,并试图使用一个标志,但它似乎没有做到这一点。

Fiddle

4 个答案:

答案 0 :(得分:2)

关键的想法是仅在firedfalse时启动计时器。 如果您希望每个游戏启动一次计时器,请在第一个keydown事件上将fired设置为true并启动计时器。在后续的keydown事件中,检查fired的值并拒绝启动计时器。



var fired = false;
var timer = document.getElementById("timer");

var playerObj = {
    elapsedTime: -1,
    update: function () {
      playerObj.elapsedTime += 1;
      timer.innerHTML = playerObj.elapsedTime;
    },
    startTimer: function () {
        playerObj.update();
        setInterval(playerObj.update, 1000);
    }
};

document.onkeydown = function (e) {
    var w = e.keyCode == '87',
        a = e.keyCode == '65',
        s = e.keyCode == '83',
        d = e.keyCode == '68';
    if (!fired) {
        fired = true;
        if (w || a || s || d) {
           playerObj.startTimer();
        }
    }
};

#timer {
  font-family: sans-serif;
  font-size: 24px;
  color: #444;
  border: 1px solid #ddd;
  display: inline-block;
  padding: 5px 15px;
}

<div id="timer">-</div>
&#13;
&#13;
&#13;

另一种方法是在第一次keydown事件之后替换keydown处理程序。

&#13;
&#13;
var fired = false;
var timer = document.getElementById("timer");

var playerObj = {
    elapsedTime: -1,
    update: function () {
      playerObj.elapsedTime += 1;
      timer.innerHTML = playerObj.elapsedTime;
    },
    startTimer: function () {
        playerObj.update();
        setInterval(playerObj.update, 1000);
    }
};

var keyToString = {
  87: '&uarr;',
  65: '&larr;',
  83: '&darr;',
  68: '&rarr;'
};

function keyHandler(event) {             // Handles all valid keys.
  var display = document.getElementById('display');
  display.innerHTML = keyToString[event.keyCode];
}

document.onkeydown = function (event) {  // Handles the first valid key.
  if (keyToString[event.keyCode] !== undefined) {
    playerObj.startTimer();              // Start the timer.
    document.onkeydown = keyHandler;     // Replace this key handler.
    keyHandler(event);                   // Call the general key handler.
  }
};
&#13;
#timer, #display {
  font-family: sans-serif;
  font-size: 24px;
  color: #444;
  padding: 5px 15px;
}
#timer {
  display: inline-block;
  border: 1px solid #ddd;
}
&#13;
<div id="timer">-</div>

<div id="display"></div>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

你根本不需要一个标志,所有你需要做的就是在定时器启动后将eventlistener设置为null,然后这个函数永远不会再运行。它比其他解决方案更好,因为您不希望此函数再次运行,可能会阻止UI中的其他事件。

document.onkeydown = function (e) {
    var w = e.keyCode == '87',
        a = e.keyCode == '65',
        s = e.keyCode == '83',
        d = e.keyCode == '68';

    if (w || a || s || d) {
       playerObj.startTimer();
       document.onkeydown = null;
    }
};

答案 2 :(得分:0)

我认为您需要更改流程以执行以下操作:

<强>的onkeydown 检查w / a / s / d标志,然后设置标志并启动定时器

<强>的onkeyup 如果没有w / a / s / d键,则将标志设置为false

基本上就是你要在这里做的事情。我认为这将是差异,所以在输入/ g / h / etc时会停止。

答案 3 :(得分:0)

这个问题有点不清楚,所以这可能会错过这个标志。它会在每次WASD点击时启动计时器。

var timer = document.getElementById("timer");

var playerObj = {
    elapsedTime: 0,
    startTimer: function () {
        setInterval(function () {
            playerObj.elapsedTime += 1;
            timer.innerHTML = playerObj.elapsedTime;
        }, 1000);
    }
};

// keep track of keys indiividually
var keyPressed = {
    w: false,
    a: false,
    s: false,
    d: false
};

// make it easy to translate keyCodes to key names
var CODES = {
    87: 'w',
    65: 'a',
    83: 's',
    68: 'd'
};

document.onkeydown = function (e) {

    // look up the key
    var keyName = CODES[e.keyCode];

    // if it's one we're interested in and it hasn't been pressed yet
    if (keyName && !keyPressed[keyName]) {
        playerObj.startTimer();

        // mark it as having been pressed
        keyPressed[keyName] = true;
    }
};