我是JavaScript的新手,我在使用“keypress”事件时遇到了问题;我正在进行一个小的跳转脚本测试,并且“keydown”和“keyup”事件都有效,但不是“keypress”(我在事件发生后立即尝试使用console.log()进行调试但是在按下时没有显示任何内容一把钥匙)。
这是我的window.onload函数(我添加了我的事件监听器):
window.onload = function()
{
canvas = document.getElementById('gameCanvas');
ctx = canvas.getContext('2d');
init();
setInterval(function()
{
tick();
render();
}, 1000/FPS
);
// listeners
window.addEventListener("keypress", function(evt)
{
if (evt.defaultPrevented)
{
return;
}
switch(evt.keyCode)
{
case 38:
player.jump();
break;
default:
return;
}
}
);
window.addEventListener("keydown", function(evt)
{
if (evt.defaultPrevented)
{
return;
}
switch(evt.keyCode)
{
case 37:
player.moveLeft();
break;
case 39:
player.moveRight();
break;
default:
return;
}
}
);
window.addEventListener("keyup", function(evt)
{
if (evt.defaultPrevented)
{
return;
}
switch(evt.keyCode)
{
case 37:
case 39:
player.stop();
break;
default:
return;
}
}
);
}
感谢您的帮助!
答案 0 :(得分:1)
keypress
事件涉及按某个键产生的实际输入,而不是“按下”键的实际物理过程。
我从您的代码中获取您对箭头键感兴趣的内容。由于箭头键不会产生任何类型的字符,因此它们不会触发keypress
事件。 keydown
和keyup
事件是您要使用的事件。
也是最后一点:即使是同时触发keydown
和keypress
事件的键,keyCode
/ which
属性在这两个事件之间通常会有所不同,再次因为一个涉及实际的密钥而另一个涉及所产生的输入。实际上不推荐使用keyCode
和which
,而是使用抽象的key
字符串属性来消除不同事件之间的这种不一致。
答案 1 :(得分:0)
最好将输入与游戏分开。游戏通常使用常规循环来制作动画。键盘/鼠标/触摸以及其他任何可用作控制设备的设备都是间歇性的,并且设备之间具有不同的射速。
您需要知道的是游戏循环的每个帧的输入设备的当前状态。所有输入事件都应该收集设备状态信息。
键盘状态监听器仅记录您感兴趣的键的状态和/或希望阻止其默认行为。它可以根据需要打开和关闭。
不幸的是并非所有浏览器都使用新的code
属性,但是不支持code
属性将意味着将来某个时候,当折旧keyCode
属性为时,您的密钥处理程序将会中断下降。所以现在我们必须处理这两个系统。下面的代码将keyCode
值映射到code
名称。
const keyboard = (() => {
var active = false;
const keys = {
ArrowLeft : false, // only add keys you are interested in
ArrowRight : false,
Space : false,
anyKey : false,
};
// map keyCodes to named code.
const keyCodeMap = {
k37 : "ArrowLeft",
k39 : "ArrowRight",
k32 : "Space",
};
function keyEvents (e) {
var code = e.code;
if (! code) { // if no support for code
code = keyCodeMap["k" + e.keyCode];
}
if (keys[code] !== undefined) {
keys[code] = event.type === "keydown";
e.preventDefault();
}
keys.anyKey = true;
}
const API = {
start () {
if (!active) {
addEventListener("keyup", keyEvents);
addEventListener("keydown", keyEvents);
active = true;
}
return keys;
},
stop () {
if (active) {
removeEventListener("keyup", keyEvents);
removeEventListener("keydown", keyEvents);
active = false;
}
}
}
return API;
})();
启动和停止键盘
// Starting. Returns a keys state object. This is always the same object
const keys = keyboard.start(); // creates listeners
// stopping
keyboard.stop(); // removes listeners
在主游戏循环中使用
function mainLoop (time) {
// check keyboard state and take action if needed
// do rest of game
requestAnimationFrame(mainLoop);
}
仅在键或键关闭时移动
if (keys.ArrowRight) { moveRight() }
if (keys.ArrowLeft) { moveLeft() }
仅执行一次操作
if (keys.Space) { // note holding down the key will repeat
keys.Space = false; // reset the key
jumpAction();
}
检查是否已按任何键
if (keys.anyKey) {
// reset the key
keys.anyKey = false;
startGame();
}