찾다

 >  Q&A  >  본문

javascript - js如何做到主动监测按键?

由于js是事件驱动,原来键盘监测的时候我们是用onkeydown这种被动监测。
但是我在写游戏的时候发现这种监测行为有点不流畅,可能是我写的问题。不过我想能否有种方式在每帧的执行的时候,主动去监测是否在这一帧按着一些按键?
比如在我绑定了监听之后,我在动画执行30帧动画之后,为了不会继续再执行30帧动画我会重置上面那些数值,但造成的结果是,比如我先按着左(左移是一帧动画,上跳是30帧动画),过了会不放掉接着按上,只会上跳不会左上跳了。

全部源码

天蓬老师天蓬老师2896일 전561

모든 응답(3)나는 대답할 것이다

  • 巴扎黑

    巴扎黑2017-04-10 13:12:42

    JS可以主动监测吗?不可以。可以在按键时保存相应按键是否被按下的信号,并保证一个按键信号判断函数在执行队列常驻,用这种方式模拟“主动”。

    按下和松开是一对成对的逻辑,如果只在按下的时候的改变变量,你按下左右键的先后顺序就会左右最终的方向。@XiNGRZ的思路的核心是正确的思路,将keyup和keydown都做绑定。

    跟@XiNGRZ的思路稍微有些不同,我的方案里会为每个按键留下信号。这样才能对两个键同时按下的情形做处理,同时可以充分解耦。这个方案的两段,关注点分离,也易于扩展。

    按键处理及信号保存:

    var left , right , up , down ;
    
    left = right = up = down = 0 ;
    
    document.addEventListener('keydown', function (evt) {
      switch (evt.which) {
      case 37:  // left
        left = 1 ;
        break;
      case 38:  // up
        up = 1 ;
        break;
      case 39:  // right
        right = 1 ;
        break;
      case 40:  // down
        down = 1 ;
        break;
      };
    });
    
    document.addEventListener('keyup', function (evt) {
      switch (evt.which) {
      case 37:  // left
        left = 0 ;
        break;
      case 38:  // up
        up = 0 ;
        break;
      case 39:  // right
        right = 0 ;
        break;
      case 40:  // down
        down = 0 ;
        break;
      };
    });
    

    刷新数值相关代码:

    (function refresh(){
        // 下面是简化逻辑,跟一大堆if else 判断是一样的
        var horizontal = left + "" + right ;
        switch( horizontal ) {
        case "01" :
          // 右键的情形
          // 向右移动的代码
          break;
        case "10" :
          // 左键的情形
          // 向左移动的代码
          break;
        default : break;
        // 同时按下左右按键,或者什么也不按,就什么也不做。
        }
    
        // 判断上下按键
        if( up ) {
          // ↑键的情形
        } else {
          // 其他情况下,掉落的情形
        }
    
        // 根据相应数值进行重绘,不赘叙了
        repaint() ;
    
        setTimeout(refresh,HEARTBEAT_INTERVAL);
        // 或requestAnimationFrame(refresh)
        // rAF这个方法需要polyfill,需要的话我稍后补充
    })();
    

    회신하다
    0
  • ringa_lee

    ringa_lee2017-04-10 13:12:42

    var direction = 0
    
    document.addEventListener('keydown', function (evt) {
      switch (evt.which) {
        case 37:  // left
          direction = -1
          break
        case 38:  // up
          // jump
          break
        case 39:  // right
          direction = 1
          break
        case 40:  // down
          // nothing to do
          break
    })
    
    document.addEventListener('keyup', function (evt) {
      if ((evt.which == 37 && direction < 0) ||
          (evt.which == 39 && direction > 0)) {
        direction = 0
      }
    })
    

    这段代码只是说明一下思路,大致上是这个意思。

    direction 负数代表向左,正数代表向右,零代表留在原地。

    按下【←】的时候会将 direction 赋值为 -1,松开重置为 0;【→】同理。

    于是任何时候你就可以判断 direction 的值代表的方向了。

    회신하다
    0
  • PHPz

    PHPz2017-04-10 13:12:42

    不行,我从来没有看到过这种用法。这个就是本地游戏的好处。

    회신하다
    0
  • 취소회신하다