Ich mache ein Web-Spiel und möchte einen Timer aufrufen, wenn der Benutzer das Spiel startet. Wenn ich eine der WASD-Tasten drücke, starten Sie den Timer. Das Problem ist, wenn Sie die Tasten mehr als einmal drücken, wird der Timer jedes Mal gestartet. Ich möchte die Funktion nur einmal aufrufen. Ich habe über clearInterval()
nachgedacht, aber das würde den Timer stoppen. Nicht ideal.
Hier ist mein Code. (Geigenlink unten)
Ich denke, wenn eine Taste gedrückt wird, wird zuerst geprüft, ob fired
gleich false
ist. Wenn dies der Fall ist, setzen Sie es auf true
. Wenn dann die Taste W, A, S oder D gedrückt wird, starten Sie den Timer.
Wenn der Schlüssel wieder hochkommt, setzen Sie fired
erneut auf 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;
};
Ich habe auf die Antwort dieser Frage verwiesen und versucht, eine Flagge zu verwenden, aber dies ist nicht der Fall scheint den Trick nicht zu tun.
4 Antworten
Die Schlüsselidee ist, den Timer nur zu starten, wenn fired
false
ist. Wenn der Timer einmal pro Spiel gestartet werden soll, setzen Sie fired
beim ersten Keydown-Ereignis auf true
und starten Sie den Timer. Überprüfen Sie bei nachfolgenden Keydown-Ereignissen den Wert von fired
und lehnen Sie es ab, den Timer zu starten.
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>
Ein anderer Ansatz besteht darin, den Keydown-Handler nach dem ersten Keydown-Ereignis zu ersetzen.
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.
}
};
#timer, #display {
font-family: sans-serif;
font-size: 24px;
color: #444;
padding: 5px 15px;
}
#timer {
display: inline-block;
border: 1px solid #ddd;
}
<div id="timer">-</div>
<div id="display"></div>
Die Frage war ein wenig unklar, so dass dies möglicherweise die Marke verfehlt. Der Timer wird einmal pro WASD-Klick gestartet.
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;
}
};
Ich denke, Sie müssen Ihren Prozess ändern, um Folgendes zu tun:
Onkeydown Überprüfen Sie das Flag w / a / s / d, setzen Sie das Flag und starten Sie den Timer
onkeyup Wenn NICHT w / a / s / d-Tasten, setzen Sie das Flag auf false
Ist im Wesentlichen das, was Sie hier versuchen. Ich denke, das wird der Unterschied sein, also hör auf, wenn du / g / h / etc drückst.
Sie benötigen dafür überhaupt kein Flag. Sie müssen lediglich den Ereignislistener nach dem Start des Timers auf null
setzen. Diese Funktion wird dann nie wieder ausgeführt. Es ist besser als die anderen Lösungen hier, da diese Funktion nicht mehr ausgeführt werden soll und möglicherweise andere Ereignisse in der Benutzeroberfläche blockiert.
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;
}
};