Javascript“keypress”事件不起作用

时间:2017-06-18 22:08:59

标签: javascript game-physics addeventlistener

我是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;
		}
	}
	);
}

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

keypress事件涉及按某个键产生的实际输入,而不是“按下”键的实际物理过程。

我从您的代码中获取您对箭头键感兴趣的内容。由于箭头键不会产生任何类型的字符,因此它们不会触发keypress事件。 keydownkeyup事件是您要使用的事件。

也是最后一点:即使是同时触发keydownkeypress事件的键,keyCode / which属性在这两个事件之间通常会有所不同,再次因为一个涉及实际的密钥而另一个涉及所产生的输入。实际上不推荐使用keyCodewhich,而是使用抽象的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();
}