在我的游戏中,我使用事件监听器keyup
和keydown
来跟踪按下哪些键(this.input
是对下面Input
函数的引用):< / p>
$(document.body).on('keydown', this.input.keyPress.bind(this.input));
$(document.body).on('keyup', this.input.keyPress.bind(this.input));
一切都按预期工作,直到我一次按下2个键。左键将玩家向左移动,shift键发射武器。另外,他们工作正常。然而,如果同时按下并保持两者,则玩家会两次射击。
以下是我用来处理输入的代码(为简洁起见,删除了其他关键事件)
shootSpecial
只应调用一次,因为keyMap.shift
仅在true
上keydown
。触发keyup
后,会将其设置为false
:
keyMap[key] = e.type === 'keydown';
var Input = function () {
var keyMap = {};
this.handleKeyPress = function () {
if (keyMap.arrowleft === true) {
game.player.moving.left = true;
} else if (keyMap.shift === true) {
game.player.shootSpecial();
}
};
this.keyPress = function (e) {
var key = e.key.toLowerCase();
if (key === ' ') {
key = 'space';
}
keyMap[key] = e.type === 'keydown';
console.log(key, keyMap[key]);
this.handleKeyPress();
};
};
离开和转移的console.log
报告true
keydown
,false
keyup
{} {1}}所以我不太清楚为什么会两次触发shootSpecial
事件。
var keyMap = {};
var handleKeyPress = function () {
if (keyMap.arrowleft === true) {
console.log('left');
} else if (keyMap.shift === true) {
console.log('shift');
}
};
var keyPress = function (e) {
var key = e.key.toLowerCase();
keyMap[key] = e.type === 'keydown';
if (document.getElementById(key))
document.getElementById(key).innerText = e.type === 'keydown';
handleKeyPress();
}
document.addEventListener('keydown', keyPress);
document.addEventListener('keyup', keyPress);
LEFT:<div id="arrowleft">false</div>
SHIFT:<div id="shift">false</div>
正如你可以看到的那样,一个事件会被调用两次。
答案 0 :(得分:1)
您的问题是您使用相同的代码处理keydown和keyup,结果是在按下key2时释放key1与按key2具有相同的效果。
修复非常简单:在keyup事件中根本不调用handleKeyPress函数。
#!/usr/bin/env python
from csv import DictReader, DictWriter
data = '''A,B,C
1,2,3
4,5,6
6,7,8'''
reader = DictReader(data.split('\n'))
# You'll need your fieldnames first in a list to ensure order
fieldnames = ['A', 'C']
# We'll also use a set for efficient lookup
fieldnames_set = set(fieldnames)
with open('outfile.csv', 'w') as outfile:
writer = DictWriter(outfile, fieldnames)
writer.writeheader()
for row in reader:
# Use a dictionary comprehension to iterate over the key, value pairs
# discarding those pairs whose key is not in the set
filtered_row = dict(
(k, v) for k, v in row.iteritems() if k in fieldnames_set
)
writer.writerow(filtered_row)
&#13;
var keyMap = {};
var handleKeyPress = function () {
if (keyMap.arrowleft === true) {
console.log('left');
} else if (keyMap.shift === true) {
console.log('shift');
}
};
var keyPress = function (e) {
var key = e.key.toLowerCase();
keyMap[key] = e.type === 'keydown';
if (document.getElementById(key))
document.getElementById(key).innerText = e.type === 'keydown';
// Only call handleKeyPress if the key is pressed
if (keyMap[key]) {
handleKeyPress();
}
}
document.addEventListener('keydown', keyPress);
document.addEventListener('keyup', keyPress);
&#13;
添加建议以回应OP的评论。你的问题是你的handleKeyPress()没有关于按下或按下按键的信息,也没有知道哪个按键被按下,只有哪些按键在被调用时才被按下。为了得到你的目标,我会做这样的事情:
LEFT:<div id="arrowleft">false</div>
SHIFT:<div id="shift">false</div>
&#13;
var keyPress = function (e) {
var key = e.key.toLowerCase(),
isKeyDown = e.type === "keydown",
output = key + (isKeyDown ? "-down" : "-up") + ": ";
switch (key) {
case "shift":
if (isKeyDown) {
output += "pew pew";
} else {
output += "doing nothing"
}
break;
case "arrowleft":
output += "updating walking_left";
document.getElementById("walking_left").innerText = isKeyDown;
break;
default:
output += "doing nothing";
}
console.log(output);
};
document.addEventListener('keydown', keyPress);
document.addEventListener('keyup', keyPress);
&#13;
答案 1 :(得分:0)
如果按两个键,无论是否同时按下它们,都会触发两个事件。 keyup
事件也是如此。所以总共 handleKeypress 函数被调用四次。
订单可能恰好是:
key | event | keyMap.arrowleft | keyMap.shift | effect
-----------+---------+------------------+--------------+----------
shift | keydown | false | true | shoot
arrowleft | keydown | true | true | moving.left=true
arrowleft | keyup | false | true | shoot
shift | keyup | false | false | nothing
所以在这种情况下你会拍两次。当然,情况并非总是如此,因为订单可能不同。
将键作为参数传递给 handleKeyPress 函数,以确保只执行与该键对应的操作。
var Input = function () {
var keyMap = {};
this.handleKeyPress = function (key) {
switch (key) {
case 'arrowleft':
game.player.moving.left = keyMap[key]; // also sets back to false
break;
case 'shift':
if (keyMap.shift) game.player.shootSpecial();
break;
}
};
this.keyPress = function (e) {
var key = e.key.toLowerCase();
if (key === ' ') {
key = 'space';
}
keyMap[key] = e.type === 'keydown';
this.handleKeyPress(key); // pass key
};
};