按键移动元素(多个)

对角移动不起作用并且在left-longPress / right同时发出

但是在双键按下时,这艘船发疯了!

$(document).bind('keydown', function(e) { var box = $("#plane"), left = 37, up = 38, right = 39, down = 40 if (e.keyCode == left) { box.animate({left: "-=5000"},3000); } if (e.keyCode == up) { box.animate({top: "-=5000"},3000); } if (e.keyCode == right) { box.animate({left:"+=5000"},3000); } if (e.keyCode == down) { box.animate({top: "+=5000"},3000); } }); $(document).bind('keyup', function() { $('#plane').stop(); }); 

我搞砸了类似的事情,这是我遇到的解决方案。

 setInterval(movePlane, 20); var keys = {} $(document).keydown(function(e) { keys[e.keyCode] = true; }); $(document).keyup(function(e) { delete keys[e.keyCode]; }); function movePlane() { for (var direction in keys) { if (!keys.hasOwnProperty(direction)) continue; if (direction == 37) { $("#plane").animate({left: "-=5"}, 0); } if (direction == 38) { $("#plane").animate({top: "-=5"}, 0); } if (direction == 39) { $("#plane").animate({left: "+=5"}, 0); } if (direction == 40) { $("#plane").animate({top: "+=5"}, 0); } } } 

演示

延迟的问题似乎是大多数浏览器将采用第一个输入(在keyDown上),然后在反复运行函数之前它们有半秒的延迟。 如果我们不记得keydown上的函数,而是有一个间隔检查一个关联数组,我们存储哪些键被按下,这似乎可以平滑移动。 它还允许一次按下多个键,这意味着对角线移动。 然后我们将使用keyup事件删除相应的键。

在此解决方案中,您有两种方法来管理要移动的元素的速度。

  1. 间隔的更新频率。 (上面演示中的20ms)
  2. 平面每次移动的像素数。 (上面的演示中有5个)

我发现间隔频率上的20毫秒可以让你运动相当平稳。

我意识到这是一个非常古老的线索,但我认为无论如何我都会做出贡献。

关于那个间隔,

http://jsfiddle.net/fbFuW/21/

 var leftDown, rightDown, upDown, downDown,leftKey,upKey,rightKey,downKey; var box = $("#plane"); function keye(e) { console.log(e.keyCode); var $key = e.keyCode; $(document).keydown(function(e) { if (e.keyCode == left && $key != left) leftDown = true; if (e.keyCode == right && $key != right) rightDown = true; if (e.keyCode == down && $key != down) downDown = true; if (e.keyCode == up && $key != up) upDown = true; }).keyup(function(e) { if (e.keyCode == left) leftDown = false; if (e.keyCode == right) rightDown = false; if (e.keyCode == down) downDown = false; if (e.keyCode == up) upDown = false; }); if (e.keyCode == left) { leftKey = true; } if (e.keyCode == up) { upKey = true; } if (e.keyCode == right) { rightKey = true; } if (e.keyCode == down) { downKey = true; } } $("body").keydown(function(){ keye(event); }); $("body").keyup(function(e){ if (e.keyCode == left) { leftKey = false; } if (e.keyCode == up) { upKey = false; } if (e.keyCode == right) { rightKey = false; } if (e.keyCode == down) { downKey = false; } }); setInterval(function() { if (leftDown) { box.css('left', '-=5'); } if (rightDown) { box.css('left', '+=5'); } if (downDown) { box.css('top', '+=5'); } if (upDown) { box.css('top', '-=5'); } if (upKey) { box.css("top", "-=5"); } if (rightKey) { box.css("left", "+=5"); } if (downKey) { box.css("top", "+=5"); } if (leftKey) { box.css("left", "-=5"); } },20); 

怎么用jquery动画。 它几乎可以防止延迟移动。

见演示

jsBin演示

依靠键盘事件来移动元素将使其依赖于OS键间隔延迟。

而是使用游戏间隔并检查存储在对象内的按下的键

keydown keyup事件中,如果event.which返回的keyCode >36 || <41 >36 || <41表示使用了箭头键。 在K (keys)对象中存储key-number属性的布尔值( true/false )。

间隔:

如果一个键号属性(在我们的K对象内)为trueif(K[37]) ), window.requestAnimationFrame内部会增加或减少元素的xy位置。

对角线运动问题:

同时沿对角线移动元素(即) 需要补偿较高的对角线距离。
为此,您需要注册多个键并降低乘数:

 var Pl = {el:$('#player'), x:200, y:100, speed:2}, K = {}; // keys: {37:boolean, 38:boolean, ...} $(document).on('keydown keyup', function(e) { var kN = e.which; // The key-number (keyCode normalized by jQuery's `which`) if(kN>36||kN<41) K[kN]= e.type==="keydown"; // (if arrows) Toggle true/false }); function updatePlayerPos() { // Diagonal factor multiplier: 1/Math.sqrt(2) = 0.7071... var dist = K[38]&&(K[37]||K[39]) || K[40]&&(K[37]||K[39]) ? 0.707 : 1; dist *= Pl.speed; if(K[37]) Pl.x -= dist; if(K[38]) Pl.y -= dist; if(K[39]) Pl.x += dist; if(K[40]) Pl.y += dist; Pl.el.css({transform:"translate3D("+ Pl.x +"px, "+ Pl.y +"px, 0)"}); } (function engine() { updatePlayerPos(); window.requestAnimationFrame( engine ); }());