Javascript 重叠的关键事件

Javascript 重叠的关键事件,javascript,css,key-events,Javascript,Css,Key Events,为了好玩,我正在做一个小小的HTML/JavaScript/CSS3项目。我基本上是在尝试制作一个在浏览器窗口中滚动的轮子。为了控制轮子,我使用keyup和keydown事件作为光标键(向左和向右转动轮子,向上和向下向前或向后滚动) 到目前为止,我的工作还不错,但是有两个主要的小故障。假设我想向前滚动车轮,不停下来,我想把它向右转一点,然后我会一直按up键,然后按向右光标键。当我这样做的时候,在它记录两个事件并继续滚动之前,运动会暂停 这是其中一个问题,主要问题是,一旦我执行了上一个操作,然后控

为了好玩,我正在做一个小小的HTML/JavaScript/CSS3项目。我基本上是在尝试制作一个在浏览器窗口中滚动的轮子。为了控制轮子,我使用keyup和keydown事件作为光标键(向左和向右转动轮子,向上和向下向前或向后滚动)

到目前为止,我的工作还不错,但是有两个主要的小故障。假设我想向前滚动车轮,不停下来,我想把它向右转一点,然后我会一直按up键,然后按向右光标键。当我这样做的时候,在它记录两个事件并继续滚动之前,运动会暂停

这是其中一个问题,主要问题是,一旦我执行了上一个操作,然后控制盘处于理想的角度,如果我松开右光标键,浏览器会将两个键注册为已释放,控制盘将停止。下面是它的大致外观:。我知道代码乱七八糟,但这是一个正在进行的工作/学习经验,我只编程了一个月左右


无论如何,谢谢你的帮助。据我所知,目前它只在Chrome上工作。在这一阶段,我并没有真正为解决兼容性问题而烦恼。

这里是我曾经编写的一个简单游戏的一个片段

//key codes
var KEY_LEFT = 37;
var KEY_RIGHT = 39;
var KEY_A = 65;
var KEY_D = 68;
var KEY_SPACE = 32;

var keys = {};

function onKeyDown(e)
{
    e = e || window.event;
    var key = window.event.keyCode || e.which; // ie

    keys[key] = true;
}

function onKeyUp(e)
{
    var key = window.event.keyCode || e.which; // ie

    delete keys[key];
}
这将跟踪所有当前关键状态。然后你的游戏“滴答”在setTimeout()上,而不是在关键事件上移动并检查是否有合适的关键点

function gameTick()
{
    // update paddle angles
if (keys[KEY_LEFT])
    {
        // move left
    }

if (keys[KEY_RIGHT])
    {
        // move right
    }
}

这就是游戏

因此,所发生的事情本质上是操作系统内置的限制,但有一个简单的解决方法。首先我将解释限制,然后是解决方法

如果(在文本框中)按住“j”按钮,第一个“j”将出现,然后在短时间延迟后,许多“j”将出现“JJJJJJJJ”

这与您遇到的问题相同。事件触发一次,等待片刻,然后多次触发

然而,解决办法很简单。当事件被触发时,不要让你的轮子移动。。。让它不断更新,并分别跟踪哪些键处于上升或下降状态

密钥处理程序看起来像这样

function KeyHandler() {
  this.left = false;
  this.right= false;
  ...
  function onKeyDown(e) {
    if (e.keyCode == 37) {
      this.left = true;
    }
    ...
  }
  function onKeyUp(e) {
    if (e.keyCode == 37) {
      this.left = false;
    }
    ...
  }
}
wheel = new Wheel;
setInterval(function() {
  wheel.update();
},100);
(您可以将密钥处理程序附加到主体或任何您希望的元素)

您的控制盘将有一个更新功能,看起来像

wheel.update = function() {
  // the wheel is turning left
  if (wheel.keyhandler.left) {
    // make the appropriate adjustments
  }
}
然后游戏会有这样的东西

function KeyHandler() {
  this.left = false;
  this.right= false;
  ...
  function onKeyDown(e) {
    if (e.keyCode == 37) {
      this.left = true;
    }
    ...
  }
  function onKeyUp(e) {
    if (e.keyCode == 37) {
      this.left = false;
    }
    ...
  }
}
wheel = new Wheel;
setInterval(function() {
  wheel.update();
},100);

这样,您的控制盘将始终根据按键的当前状态进行更新,并且您不必依赖于触发事件的限制。:)

您面临的问题是,您的代码用于检测单次按键,而您的游戏需要检测两次按键

把这条线放在e的环上。将所有按下的键设置为1。目前它只检测一次按键并一次处理一个按键

keys[e.keyCode] = 1;
检查这个线程,你可能会得到你需要的。虽然它是jquery,但在概念上可能会有所帮助。我也在和js一起做这个。。。如果有什么新的东西出现,我们将分享


如果你真的只有一个月的编程经验,那么你的代码和概念是很酷的

但在jQuery中,我相信您可以使用bind函数,但不知道如何实现它。@Shawn31313:我认为这解决不了任何问题;这只是一个不必要的包装@jrl589:您是否尝试使用
移动
设置间隔
?由于您有一个带有键标志的对象,所以只需连续运行它就可以了,尽管它可能不是很有效。@pimvdb setInterval?很抱歉,我有点笨,但今天是我第一次尝试使用js,所以我还不太熟悉库和函数。@jrl589:像这样:。基本上,每100毫秒执行一次
move
,以根据当前关键帧状态更新对象。执行与按键无关;它总是这样做的(因此在出现重叠问题时不会锁定)。@pimvdb我尝试使用setTimeout()函数,但要么它不起作用,要么我没有在正确的上下文中使用它。仅供参考:
setInterval(func,interval)
每隔
interval
毫秒执行一次
func
。这个实现应该更加平滑。