我正在制作网页游戏,我想在用户启动游戏时调用计时器。基本上,我是怎么回事,当其中一个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回答,并试图使用一个标志,但它似乎没有做到这一点。
答案 0 :(得分:2)
关键的想法是仅在fired
为false
时启动计时器。
如果您希望每个游戏启动一次计时器,请在第一个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;
另一种方法是在第一次keydown事件之后替换keydown处理程序。
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: '↑',
65: '←',
83: '↓',
68: '→'
};
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;
答案 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;
}
};