jquery 用按键移动元素(多个)

jv4diomz  于 2023-10-17  发布在  jQuery
关注(0)|答案(3)|浏览(101)

对角线移动不工作,左长按/右同时发出
但在双按键的船疯了!

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

nle07wnf1#

我搞了一个类似的事情,这里有一个解决方案,我遇到的工程。

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.间隔的更新频率。(以上演示中为20 ms)
1.平面每次移动的像素计数。(5在上面的演示)
我发现20毫秒的间隔频率给你相当平稳的运动。
我意识到这是一个非常古老的线程,但我想我会贡献无论如何。

e5nszbig

e5nszbig2#

关于那段时间,
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);
31moq8wy

31moq8wy3#

依靠键盘事件来移动元素将使其依赖于操作系统按键间隔延迟。相反,使用游戏间隔并检查存储在对象中的按键
keydown keyup事件中,如果event.which返回的keyCode是>=37 && <=40,则表示使用了箭头键。在K(keys)Object中存储key-number属性的布尔值。

间隔:

window.requestAnimationFrame中,如果key-number属性(在我们的K对象中)是trueif(K[37])),则增加或减少元素的xy位置。

对角线移动:

同时使用对角移动元素,即。↑和→需要对对角线距离进行补偿:1 / Math.sqrt(2)(0.7071..)

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%;
}
Click here to focus, and use arrows
<div id="player"></div>

或者这里有一个轻微的翻拍,使用new Set()来记录当前按下的键盘键,new Map()为每个按下的键注册功能:

const Player = {
  el: document.querySelector("#player"),
  x: 200,
  y: 100,
  speed: 2,
  move() {
    this.el.style.translate = `${this.x}px ${this.y}px`;
  }
};

const getDistance = () => Player.speed * ((kbd.has("ArrowUp") || kbd.has("ArrowDown")) && (kbd.has("ArrowLeft") || kbd.has("ArrowRight")) ? 0.707 : 1);

// Watch pressed keyboard keys:
const kbd = new Set();
const handleArrowKeys = (evt) => {
  if (!keyActions.has(evt.key)) return; // Do nothing. Not a registered key
  evt.preventDefault(); // Prevent browser default action
  kbd[evt.type === "keydown" ? "add" : "delete"](evt.key); // Add or delete a key
};
addEventListener("keydown", handleArrowKeys);
addEventListener("keyup", handleArrowKeys);

// Register keyboard keys actions
// Set a desired function for every desired key:
const keyActions = new Map();
keyActions.set("ArrowRight", () => {
  Player.x += getDistance();
});
keyActions.set("ArrowLeft", () => {
  Player.x -= getDistance();
});
keyActions.set("ArrowUp", () => {
  Player.y -= getDistance();
});
keyActions.set("ArrowDown", () => {
  Player.y += getDistance();
});

const engine = () => {
  // Trigger a keyAction for pressed keys
  kbd.forEach((key) => keyActions.get(key)());
  Player.move();
  requestAnimationFrame(engine);
};

engine();
#player { position: absolute; left: 0; top: 0; width: 20px; height: 20px; background: #000; border-radius: 50%; }
Click here to focus, and use arrow keys
<div id="player"></div>

相关问题