按键移动元素(多个)
对角移动不起作用并且在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事件删除相应的键。
在此解决方案中,您有两种方法来管理要移动的元素的速度。
- 间隔的更新频率。 (上面演示中的20ms)
- 平面每次移动的像素数。 (上面的演示中有5个)
我发现间隔频率上的20毫秒可以让你运动相当平稳。
我意识到这是一个非常古老的线索,但我认为无论如何我都会做出贡献。
关于那个间隔,
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
对象内)为true
( if(K[37])
), window.requestAnimationFrame
内部会增加或减少元素的x
, y
位置。
对角线运动问题:
同时沿对角线移动元素(即) ↑和→需要补偿较高的对角线距离。
为此,您需要注册多个键并降低乘数:
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 ); }());