2016-09-02 29 views
1

我正在寫在JavaScript中一個簡單的遊戲,它已經處理基本的鍵盤輸入,像這樣:如何在主遊戲循環中處理關鍵事件?

var input = {}; 
document.onkeydown = function(e) { 
    input[e.keyCode] = true; 
} 
document.onkeyup = function(e) { 
    input[e.keyCode] = false; 
} 

while (!done) { 
    handleInput(input); 
    update(); 
    render(); 
} 

現在我需要遊戲手柄的按鍵組合(如CTRL + X爲例)。我希望它能接受這樣的組合keyup只,

編輯:修飾鍵不需要與「主」鍵同時完成。 /編輯進入我的腦海

兩個可能的解決方案是:

  • 暴露含keyup事件的列表(對象與「主」鍵加修飾)的陣列。 handleInput函數將負責每次輪詢時排空隊列
  • 跟蹤handleInput(注意按住修改鍵)內可能的組合鍵,並在「主」鍵上升時觸發組合行爲(實際上我不喜歡這麼多)

你會建議我一個優雅的方式來擴展當前的功能嗎?

+0

反正,很好的問題! – PDKnight

回答

1

您只需要創建upInput變量,您將在其中存儲您的鍵盤鍵。然後,要檢查組合鍵是否被按下,您必須檢查變量中是否只有CTRL + C(或17,67)組合鍵如果全部是true。然後輕鬆打印您的消息並重置upInput變量。

var input = upInput = {}; 

document.onkeydown = function(e) { 
    input[e.keyCode] = true; 
    if (JSON.stringify(Object.keys(upInput)) != '["17","67"]') 
     upInput = {}; 
} 
document.onkeyup = function(e) { 
    var k = e.keyCode; 
    input[k] = false; 
    if ([17, 67].indexOf(k) > -1) 
     upInput[k] = true; 
    if (JSON.stringify(Object.keys(upInput)) == '["17","67"]' 
      && upInput[17] && upInput[67]) // CTRL + C 
     alert('YES!'), 
     upInput = {}; 
} 

Demo

希望幫助!

+0

嗯...我可以說我不喜歡'JSON.stringify(Object.keys(upInput))=='[「17」,「67」]''位?此外,事件處理程序應該更新輸入狀態,這應該由主循環中的'handleInput'函數來處理(我的問題中的代碼是錯誤的,我將修復它) –

+0

@MarcoBolis'JSON.stringify ()'是最快的選擇,否則我不得不爲Object原型製作一個自定義的'.contains()'函數。據我所知,你不喜歡在你的事件監聽器中有代碼?那麼這是不可能的。另外,你還沒有聲明'done'變量,所以你的while語句在當前代碼中是毫無意義的。 – PDKnight

+0

沒有關於監聽器內部代碼的問題,我們只需將_handling_部分取出並將其強制轉換爲'handleInput'。關於我不喜歡的一點,它不是關於'JSON.stringify()',只是我不相信Object.keys()會以正確的順序返回鍵! –

0

我會做的那些方法之一:

  • 檢查在handleInput部分的組合(那種你 第二apporach的)
  • 保持最後X鍵盤事件的列表(其中X是最大 長度組合序列),並檢查該列表是否遵循 任何預定義的組合的觸發
1

試試這個;) 它會ppear一個消息,當您按下CTRL + X和你釋放他們的

var map = {17: false, 88: false}; 
var fire_event = false; 

window.addEventListener('keydown', function(e) { 
    if (e.keyCode in map) { 
     map[e.keyCode] = true; 
     if (map[17] && map[88]) { 
      fire_event = true; 
     } 
    } 
}, false); 

window.addEventListener('keyup', function(e) { 
    if (e.keyCode in map) { 
     map[e.keyCode] = false; 
    } 
    if (fire_event) { 
     fire_event = false; 
     alert('YOU PRESSED CTRL + X'); 
    } 
}, false); 
+0

第一次工作,但在我再次按下ctrl + x組合鍵後失敗。 – PDKnight

+0

現在就試試吧,我做了一個改變......我沒有看到它是在「只在鍵盤上」指定的。 – Dan

+0

不會。如果我按下「CTRL + X + A」並讓「A」?或者'CTRL + X'然後'CTRL + C'? – PDKnight

0

嘗試,如果它的工作原理一個(或兩個):

var KEY_QUEUE = []; 
var KEYs = [17, 88]; 

document.onkeydown = function (e) { 
    if (KEY_QUEUE.indexOf(e.keyCode) === -1) { 
     KEY_QUEUE.push(e.keyCode); 
    } 
}; 

document.onkeyup = function (e) { 
    var index = KEY_QUEUE.indexOf(e.keyCode); 
    if (isSubArray(KEYs, KEY_QUEUE) 
     && KEYs.indexOf(e.keyCode) > -1) { 
     console.log("You press CTRL + X"); 
    } 
    KEY_QUEUE.splice(index, 1); 
}; 

function isSubArray(ary, targetAry) { 
    return new RegExp(ary.toString()).test(targetAry.toString()); 
} 

我查了一些情況下,像Ctrl xx CtrlCtrl x aCtrl a x,它按我的預期工作。但我不確定它是否與你的想法一樣。

+0

此解決方案是否要求用戶按照正確的順序釋放密鑰? –

+0

@Marco Bolis,它需要。 'Ctrl x'會觸發事件,'x Ctrl'不會。如果你先按下x或Ctrl鍵,那麼'Ctrl a x'將不起作用,但如果你首先按住'a'鍵將'Ctrl'和'x'鍵合在一起,它就會起作用。 –