2015-08-22 30 views
0

我正在製作網頁遊戲,並且我想在用戶啓動遊戲時調用計時器。基本上,我如何去做是當一個WASD鍵被擊中時,啓動計時器。問題是,如果您不止一次地按下按鍵,它會每次啓動計時器。我只想調用一次函數。我正在考慮clearInterval(),但那會阻止計時器。不理想。在keydown上,使用JavaScript只運行一次計時器

這是我的代碼。 (小提琴鏈接如下)

我認爲應該發生的事情是,當任何按鍵被按下,它將首先檢查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

+0

那麼你的代碼是在關鍵幀設置標誌回false。不要這樣做。 – nnnnnn

+0

@nnnnnn我覺得這很奇怪。只是做了那個人在問題 – Matthew

+0

中所說的話。在另一個問題中,他們擔心如果用戶把鑰匙關掉,會發生什麼。這不是你想要解決的問題。 – nnnnnn

回答

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>

另一種方法是先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: '&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. 
 
    } 
 
};
#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>

0

我認爲你需要改變你的過程中做到以下幾點:

的onkeydown 檢查W/A/S/d標誌,然後設置標誌,並啓動定時器

onkeyup if not w/a/s/d keys,then set the flag to false

Is essen最後你想在這裏做什麼。我認爲這將是差異,所以當輸入/ g/h/etc時停止。

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; 
    } 
}; 
1

你不需要一個標誌,在所有的,這一切你所要做的就是設置事件監聽到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; 
    } 
}; 
+0

這是最好的解決方案!清潔和簡單,感謝分享。 – Matthew