为超级简单的jQuery游戏处理角色动画。
我的问题是,如果您快速切换移动键,则会有大约半秒的延迟。例如,如果您按住W然后非常快速地按D,则会出现意外延迟。我希望它是即时的。有什么方法可以解决这个问题吗?
这是我的代码:
$(document).ready(function () {
var character = $('#character');
var movement;
var move_keys = {
87: {top: "-=1"}, // up
83: {top: "+=1"}, // down
65: {left: "-=1"}, // left
68: {left: "+=1"} // right
};
var moving = false;
var move_timer;
$(this).keydown(function (e) {
e.preventDefault();
if (!moving) {
moving = true;
movement = move_keys[e.keyCode];
move_timer = setInterval(startMoving, 1);
}
});
$(this).keyup(function (e) {
e.preventDefault();
moving = false;
clearInterval(move_timer);
});
function startMoving() {
if (movement !== undefined) {
character.css(movement);
}
}
});
jsfiddle:https://jsfiddle.net/4rycer59/1/
答案 0 :(得分:1)
同时按下键时,您将以不同的顺序接收键盘事件。
我做了以下更改:
var moving; // no longer boolean
var move_timer;
$(this).keydown(function (e) {
e.preventDefault();
if (moving !== e.keyCode) {
moving = e.keyCode; // which key is moving?
movement = move_keys[e.keyCode];
clearInterval(move_timer); // just in case keyup is late
move_timer = setInterval(startMoving, 1);
}
});
$(this).keyup(function (e) {
e.preventDefault();
if(moving === e.keyCode) { // only cancel if not 'late'
moving = false;
clearInterval(move_timer);
}
});
答案 1 :(得分:1)
我建议将按键逻辑与运动逻辑分开。它使事情更容易推理,并允许在多个方向上移动。您还可以使用setTimeout
而不是setInterval
来改善游戏循环,以便尽可能频繁地运行游戏逻辑。然后,如果您考虑增量时间(自上次游戏循环以来的时间),您可以进一步平滑移动,因为setInterval
和setTimeout
并不总是延迟相同的时间。
$(document).ready(function () {
var character = $('#character');
var position = character.position();
var keysPressed = {};
$(this).keydown(function (e) {
keysPressed[e.keyCode] = true;
});
$(this).keyup(function (e) {
delete keysPressed[e.keyCode];
});
function loop(callback, lastTime) {
var currentTime = new Date().getTime();
callback(currentTime - lastTime);
setTimeout(function () {
loop(callback, currentTime);
});
}
loop(function(deltaTime) {
// Use delta from last frame to "smooth" movement
var steps = deltaTime / 10;
if (keysPressed[87]) { // UP
position.top -= steps;
}
if (keysPressed[83]) { // DOWN
position.top += steps;
}
if (keysPressed[65]) { // LEFT
position.left -= steps;
}
if (keysPressed[68]) { // RIGHT
position.left += steps;
}
character.css(position);
});
});