用按键移动元素(多个)

时间:2011-09-04 10:14:20

标签: jquery keypress

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

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

$(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();
});

4 个答案:

答案 0 :(得分:9)

我用类似的东西搞砸了,这是我遇到的解决方案。

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);  
        }
    }
}

Demo

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

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

  1. 间隔的更新频率。 (上面演示中的20ms)
  2. 飞机每次移动的像素数。 (上面演示中的5个)
  3. 我发现间隔频率上的20毫秒可以让你运动相当平稳。

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

答案 1 :(得分:2)

关于那段时间,

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);

答案 2 :(得分:1)

使用jquery animate如何做到这一点。它几乎可以防止延迟移动。

请参阅demo

答案 3 :(得分:0)

依靠键盘事件移动元素将使其依赖于OS键间隔延迟。 相反,请使用游戏间隔并检查存储在对象

中的按键

keydown keyup事件中,如果event.which返回的keyCode为>=37 && <=40,则表示使用了箭头键。在K(keys)对象中存储key-number属性的布尔值。

间隔:

如果键号属性(在我们的window.requestAnimationFrame对象内)为{{1},x内部会增加或减少元素的yK位置}(true)。

对角线运动:

同时使用对角移动元素,即需要补偿对角线距离:if(K[37])(0.7071 ..)

1 / Math.sqrt(2)
const Player = {
  el: document.getElementById('player'),
  x: 200,
  y: 100,
  speed: 2,
  move() {
    this.el.style.transform = `translate(${this.x}px, ${this.y}px)`;
  }
};

const K = {
  fn(ev) {
    const k = ev.which;
    if (k >= 37 && k <= 40) {
      ev.preventDefault();
      K[k] = ev.type === "keydown"; // If is arrow
    }
  }
};

const update = () => {
  let dist = K[38] && (K[37] || K[39]) || K[40] && (K[37] || K[39]) ? 0.707 : 1;
  dist *= Player.speed;
  if (K[37]) Player.x -= dist;
  if (K[38]) Player.y -= dist;
  if (K[39]) Player.x += dist;
  if (K[40]) Player.y += dist;
  Player.move();
}

document.addEventListener('keydown', K.fn);
document.addEventListener('keyup', K.fn);

(function engine() {
  update();
  window.requestAnimationFrame(engine);
}());
#player{
  position: absolute;
  left: 0;  top: 0;
  width: 20px;  height: 20px;
  background: #000;  border-radius: 50%;
}