2014-01-09 27 views
0
var canvas = document.getElementById('gameCanvas'); 
var ctx = canvas.getContext('2d'); 
var xPosition = 0; 
var yPosition = 0; 
var frameLength = 20; 

function gameLoop(){ 

    gameUpdate(); 
    setTimeout(function(){gameLoop()}, frameLength); 
} 

function gameUpdate(){ 

ctx.clearRect(0, 0, 480, 640); 
window.addEventListener('keydown', function(event){switch(event.keyCode){case 38: yPosition -= 1; break; case 40: yPosition += 1; break;}}, false); 
ctx.fillRect(xPosition, yPosition, 50, 50); 

} 

$(document).ready(function() { 
gameLoop(); 
}); 

我想通過箭頭鍵在畫布中移動矩形。 X和Y位置是變量xPosition和yPosition。目前嚴格按照Y方向處理,我有一個由「keydown」的eventlistener觸發的開關功能。例如,當按下向下箭頭鍵時,它將增加fillRect(X, Y, originX, OriginY)中的Y值。這將更改全局變量,然後在畫布上繪製具有新座標的新矩形。 GameLoop重置,沖洗重複。這就是我理解它的原理。爲什麼var yPosition在每個循環後增加,儘管沒有發生事件?

因爲某些原因,即使我什麼都不做,腳本運行的時間越長,按下UP或DOWN鍵時,「更遠的」方塊跳動。也就是說,按下按鈕會從畫布上啓動很多由setTimeout循環數決定的像素,但它會出現。爲什麼是這樣的,我該如何解決它?

+2

每次通過循環時都不需要添加事件偵聽器。在$(document).ready上執行它,你會沒事的。 – ericjbasti

+0

它被稱爲**添加** EventListener的原因 - 它不會刪除以前添加的事件監聽器! – Pointy

+0

您不需要將'gameLoop'包裝到'function'中,只需編寫'setTimeout(gameLoop,frameLength);' –

回答

1

您正在多次添加活動。就在這條線移動到全球範圍:

window.addEventListener('keydown', function(event){switch(event.keyCode){case... 

如果沒有密鑰將被多次檢測,併爲此積累

您也可以扔在處理程序preventDefault,而你在它:

window.addEventListener('keydown', function(event){ 
    if (event.preventDefault) event.preventDefault(); 
    switch(event.keyCode){case ... 
+0

非常感謝!爲了進一步瞭解出了什麼問題,EventListener中的函數如何在沒有keydown觸發器的情況下運行?我認爲每次都會發生EventListeners堆疊。因此,當人們按下向上或向下箭頭時,你實際上正在運行該功能,例如50次......? –

+0

@JakeL。它會產生一堆事件需要分發給的偵聽器。由於JS是單線程的,這個事件鏈的處理最終會消耗大部分時間。如果你有50個聽衆,每個聽衆增加一個,每個按鍵的結果是50個增量。下次你可能有150個聽衆等等。 – K3N

相關問題