如何处理主游戏循环中的按键事件?
How to handle keyup events in main game loop?
我正在 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
.
上接受这样的组合
编辑: 修改键不需要与 "main" 键同时全部向上。 /编辑
我想到的两个可能的解决方案是:
- 公开包含
keyup
事件列表的数组(带有 "main" 键加修饰符的对象)。 handleInput
函数将负责在每次轮询时清空队列
- 跟踪
handleInput
中可能的组合键(观察按住的修改键)并在 "main" 键上升时触发组合行为(我实际上不太喜欢这个)
你能建议我一个优雅的方式来扩展当前的功能吗?
您所要做的就是创建 upInput
变量,您将在其中存储您的 keyup 键。然后,要检查是否按下了组合键,您必须检查是否只有 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
希望对您有所帮助!
我会采用其中一种方式:
- 正在检查 handleInput 部分中的组合(您的那种
第二个方法)
- 保留最近 X 键盘事件的列表(其中 X 是最大值
组合序列的长度)并检查此列表是否匹配
任何预定义的组合触发器
试试这个 ;)
当您按下 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);
尝试一下是否有效:
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 x
、x Ctrl
、Ctrl x a
、Ctrl a x
,它按我的预期工作。但是不知道是不是跟你的想法一样
我正在 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
.
编辑: 修改键不需要与 "main" 键同时全部向上。 /编辑
我想到的两个可能的解决方案是:
- 公开包含
keyup
事件列表的数组(带有 "main" 键加修饰符的对象)。handleInput
函数将负责在每次轮询时清空队列 - 跟踪
handleInput
中可能的组合键(观察按住的修改键)并在 "main" 键上升时触发组合行为(我实际上不太喜欢这个)
你能建议我一个优雅的方式来扩展当前的功能吗?
您所要做的就是创建 upInput
变量,您将在其中存储您的 keyup 键。然后,要检查是否按下了组合键,您必须检查是否只有 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
希望对您有所帮助!
我会采用其中一种方式:
- 正在检查 handleInput 部分中的组合(您的那种 第二个方法)
- 保留最近 X 键盘事件的列表(其中 X 是最大值 组合序列的长度)并检查此列表是否匹配 任何预定义的组合触发器
试试这个 ;) 当您按下 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);
尝试一下是否有效:
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 x
、x Ctrl
、Ctrl x a
、Ctrl a x
,它按我的预期工作。但是不知道是不是跟你的想法一样