【问题标题】:Is it possible to make JQuery keydown respond faster?是否可以让 JQuery 按键响应更快?
【发布时间】:2012-11-24 04:07:59
【问题描述】:

我正在编写一个带有 JQuery 和 HTML5 画布标签的简单页面,我在画布上移动一个形状,方法是按“w”向上,“s”向下,“a”向左,“d”向右。我已经完成了所有工作,但我希望形状在敲击键时开始以恒定速度移动。现在有某种保持期,然后运动开始。我怎样才能让运动立即发生?

这是我的代码的重要部分:

<script src="jquery.js"></script>
<script src="JQuery.print.js"></script>    
<body>
<canvas id="myCanvas" width="500" height="200" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<br><br>
start navigating<input type="text" id = "enter"/>
<div id = "soul2">
coords should pop up here
</div>
<div id = "soul3">
key should pop up here
</div>

<script>

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
//keypress movements
var xtriggered = 0;
var keys = {};
var north = -10;
var east = 10;
var flipednorth = 0;

$(document).ready(function(e){
  $("input").keydown(function(){
    keys[event.which] = true;
    if (event.which == 13) {
         event.preventDefault();
      }
    //press w for north
    if (event.which == 87) {
         north++;
         flipednorth--;
      }
    //press s for south
    if (event.which == 83) {
         north--;
         flipednorth++;
      }
    //press d for east
     if (event.which == 68) {
         east++;
      }
    //press a for west
    if (event.which == 65) {
         east--;
      }
     var  msg = 'x: ' + flipednorth*5 + ' y: ' + east*5;
     ctx.beginPath();
     ctx.arc(east*6,flipednorth*6,40,0,2*Math.PI);
     ctx.stroke();
     $('#soul2').html(msg);
    $('#soul3').html(event.which );
     $("input").css("background-color","#FFFFCC");
  });

  $("input").keyup(function(){
    delete keys[event.which];
    $("input").css("background-color","#D6D6FF");
  });
});

</script>

如果我不应该发布这么长的代码,请告诉我。

【问题讨论】:

  • 可能在 keyup 中抛出错误,没有 event 参数,所以 event.which 应该抛出错误。 keys 对象似乎并没有用于任何事情
  • 我正在使用 chrome。另外,我没有错误。我也会发布html,以便你们更好地理解。为什么投反对票?
  • charlietfl,keys 对象用于同时按下两个或多个键。我在这里了解到:stackoverflow.com/questions/4954403/…

标签: javascript jquery html canvas


【解决方案1】:

您缺少的是“游戏循环”。

在决定是否以及何时在画布上移动形状时,您需要使用键事件来跟踪在任何给定时刻哪些键被按下,然后检查键,而不是直接对键向下或向上做出反应来自基于setTimeout() 的循环的状态,该循环独立于关键事件运行。

您已经开始使用 keys 变量来跟踪给定键是否随时关闭:

// in keydown
keys[event.which] = true;
// in keyup
delete keys[event.which];

...除了 event 没有定义 - 你需要将它作为事件处理程序的参数,而且你的代码实际上都没有检查 keys 中的值。

这是我所说的简化版本:

$(document).ready(function(e){
  var keys = {};

  $("input").keydown(function(event){
    keys[event.which] = true;
  }).keyup(function(event){
    delete keys[event.which];
  });

  function gameLoop() {
    // w for north
    if (keys[87]) {
       north++;
       flipednorth--;
    }
    //press s for south
    if (keys[83]) {
       north--;
       flipednorth++;
    }
    // etc. for other keys

    // code to move objects and repaint canvas goes here

    setTimeout(gameLoop, 20);
  }
  gameLoop();
});

演示:http://jsfiddle.net/ktHdD/1/

gameLoop() 函数将运行 20 毫秒左右(您可以根据需要改变它,但这对于相当流畅的动画来说已经足够快了)。每次运行时,它都会检查是否有任何键被按下,如果是,则调整相关的位置变量并重新绘制。如果您有其他自动移动的对象(例如,在游戏中可能有坏人),您也可以在 gameLoop() 函数中更新它们。

【讨论】:

  • 这使得保留所有键更有意义。我的版本只是保持最后一次按下
  • 感谢您的精彩回答。这对我很有帮助,可能对很多其他人也很有帮助。谢谢!
  • 不客气。 (请注意,即使您没有提及您的程序是游戏的任何内容,我也故意使用了术语“游戏循环”,因为如果您遇到“游戏循环”是您想要搜索有关此概念的更多信息的术语进一步的问题。)
  • 您在上面展示的内容背后有一个完整的理念。这对于我接下来的旅程(制作游戏哈哈)将非常重要。再次感谢您的示例,我已将您的代码结构实现到我的画布中,并且所有这些都以我想象的方式组合在一起。
【解决方案2】:

这不是 jQuery。您会在记事本中发现完全相同的延迟。

你要做的就是这个

var keydown=false;
$(document).on('keydown', function(e){
    if (!keydown) 
    {
        keydown=e.which;
        console.log('start moving and keep moving');
    }
}).on('keyup', function(){
    console.log("stop moving");
    keydown=false;
});​

【讨论】:

  • 这是有道理的。您会推荐任何解决密钥延迟的方法吗?
  • @Douglas 你不明白我的代码是做什么的。它会捕获您不关心其余部分的第一个按键,您所等待的只是 keyup jsfiddle.net/LhBk9/1
  • @Drew - 没有延迟,我们已经绕过了操作系统的功能。
  • @popnoodles 我喜欢你在这里的想法,但似乎这种方法并没有绕过操作系统。操作系统发生在浏览器之前,因此浏览器可以请求更多注册的击键,它只能有给定的数量。我制作了一个定时示例来显示每个注册的keydown 事件之间经过的时间。 jsfiddle.net/LhBk9/3 您会注意到从 0-1 的时间始终大于从 1-2、2-3 等开始的时间。
  • @Douglas 你还没有理解代码在做什么。我如何以不同的方式说出我在回应您的第一条评论时所说的话?它只查找第一个按键而不是操作系统重复。看看这个jsfiddle.net/LhBk9/1
【解决方案3】:

我相信您所看到的是一个键的重复率。这是在用户的操作系统中设置的 - 而不是浏览器。基本上,除了要求用户更改它之外,您无能为力。

http://windows.microsoft.com/en-US/windows-xp/help/adjust-the-character-repeat-rate

编辑

这不是您问题的答案,但我将把它留在这里,因为重复率仍然是问题。请注意,@nnnnnn 表明存在可行的解决方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-24
    • 1970-01-01
    • 2018-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多