0

当我按下任何箭头或使用 WSAD 时,在 keydown 事件的第一次“激活”之后,到下一个事件会有轻微的延迟,但之后就正常了。示例:当您按住箭头时,您移动 1px,稍等片刻,然后开始定期正常移动 1px。

我的代码:

 //========== KEY LOGGING ==========
          var pressedKeys = [];

          //declare as globals coz of debug
          var x;
          var y;
          var x2;
          var y2;

          function checkMove(checkX, checkY, cSize, cSpeed, direction) {
              x = checkX - cSpeed;
              y = checkY - cSpeed;
              x2 = checkX + cSize + cSpeed;
              y2 = checkY + cSize + cSpeed;

              switch (direction) {
                  case 1:
                      // left
                      if (x > 0) {
                          return checkX - cSpeed;
                      } else {
                          return 0;
                      }
                      break;

                  case 2:
                      // up
                      if (y > 0) {
                          return checkY - cSpeed;
                      } else {
                          return 0;
                      }
                      break;

                  case 3:
                      // right
                      if (x2 < width) {
                          return checkX + cSpeed;
                      } else {
                          return width - cSize;
                      }
                      break;

                  case 4:
                      // down
                      if (y2 < height) {
                          return checkY + cSpeed;
                      } else {
                          return height - cSize;
                      }
                      break;

                  default:
                      return; // exit this handler for other keys
              }

          }

          // == KEYDOWN ==
          $(document.body).keydown(function (e) {
              pressedKeys[e.which] = true;
              $.each(playerList, function (i, currentPlayer) {
                  //player 1
                  if (currentPlayer.id == 0) {
                      //left    
                      if (pressedKeys[37] == true) {
                          currentPlayer.x = checkMove(currentPlayer.x, currentPlayer.y, currentPlayer.size, currentPlayer.speed, 1)
                      }
                      //up    
                      if (pressedKeys[38] == true) {
                          currentPlayer.y = checkMove(currentPlayer.x, currentPlayer.y, currentPlayer.size, currentPlayer.speed, 2)
                      }
                      //right    
                      if (pressedKeys[39] == true) {
                          currentPlayer.x = checkMove(currentPlayer.x, currentPlayer.y, currentPlayer.size, currentPlayer.speed, 3)
                      }
                      //down    
                      if (pressedKeys[40] == true) {
                          currentPlayer.y = checkMove(currentPlayer.x, currentPlayer.y, currentPlayer.size, currentPlayer.speed, 4)
                      }
                  }
                  //player 2
                  else if (currentPlayer.id == 1) {
                      //left    
                      if (pressedKeys[65] == true) {
                          currentPlayer.x = checkMove(currentPlayer.x, currentPlayer.y, currentPlayer.size, currentPlayer.speed, 1)
                      }
                      //up    
                      if (pressedKeys[87] == true) {
                          currentPlayer.y = checkMove(currentPlayer.x, currentPlayer.y, currentPlayer.size, currentPlayer.speed, 2)
                      }
                      //right    
                      if (pressedKeys[68] == true) {
                          currentPlayer.x = checkMove(currentPlayer.x, currentPlayer.y, currentPlayer.size, currentPlayer.speed, 3)
                      }
                      //down    
                      if (pressedKeys[83] == true) {
                          currentPlayer.y = checkMove(currentPlayer.x, currentPlayer.y, currentPlayer.size, currentPlayer.speed, 4)
                      }
                  }

                  //addplayer
                  if (pressedKeys[80] == true && id < 5) {
                      addPlayer("red", size, width / 2, height / 2);
                  }
                  //+    
                  if (pressedKeys[107] == true) {
                      currentPlayer.speed += 1;
                  }
                  //-
                  if (pressedKeys[109] == true && currentPlayer.speed > 1) {
                      currentPlayer.speed -= 1;
                  }

              });
          });

          // == KEYUP ==    
          $(document.body).keyup(function (e) {
              delete pressedKeys[e.which];
          });
4

2 回答 2

0

您的问题主要归结为操作系统的键盘设置中设置的“重复延迟”。在 Windows 7 中,如果您转到控制面板,然后转到您的键盘设置,您将在那里看到您可以设置单个和重复按键事件之间的延迟以及按键重复的频率。

显然,由于这是一个操作系统设置,您不能通过浏览器更改它,也不能更改您自己的设置,因为不是每个人都会共享这些设置。

最好的方法是使用 keydown 和 keyup 事件以及计时器。因此,当某个键触发 keydown 事件时,您可以设置一个间隔计时器,该计时器每隔 x 毫秒使用您的函数触发一次,然后在触发 keyup 时取消间隔。

于 2013-06-30T14:16:22.147 回答
0

正如@Lee 提到的,它是操作系统的一个特性。修复它的唯一方法是使用setInterval函数:

var pressedKeys = [];
$(document.body).keydown(function(e){
    if (!pressedKeys[e.which]){
        pressedKeys[e.which] = setInterval(function(){
           console.log(1); 
        }, 0);
    }
});

$(document.body).keyup(function (e) {
    if (pressedKeys[e.which]){
        clearInterval(pressedKeys[e.which]);
        delete pressedKeys[e.which];
    }
});

http://jsfiddle.net/claustrofob/tByzK/2/

它甚至可以让您更好地控制keydown回调,因为您可以调整延迟,setInteval从而获得更好的跨浏览器性能。

于 2013-06-30T15:00:14.313 回答