对角移动不起作用,并在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();
});
答案 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);
}
}
}
延迟的问题似乎是大多数浏览器将采用第一个输入(在keyDown上),然后在反复运行函数之前它们有半秒的延迟。如果我们不记得keydown上的函数,而是有一个间隔检查一个关联数组,我们存储哪些键被按下,这似乎平滑了运动。它还允许一次按下多个键,这意味着对角线移动。然后我们将使用keyup事件删除相应的键。
在此解决方案中,您有两种方法来管理您正在移动的元素的速度。
我发现间隔频率上的20毫秒可以让你运动相当平稳。
我意识到这是一个非常古老的主题,但我认为无论如何我都会做出贡献。
答案 1 :(得分:2)
关于那段时间,
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
内部会增加或减少元素的y
,K
位置}(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%;
}