如何通过箭头键连续/平滑地移动元素
How to move an element via arrow keys continuously/smoothly?
为了好玩,我正在用Javascipt制作一个原始游戏。我已经设置了一些功能,当按下箭头键时,可以移动我的角色,如下所示:
document.getElementById("character").style.top = 0;
document.getElementById("character").style.left = 0;
document.body.onkeydown = function() {
var e = event.keyCode,
charTop = parseInt(document.getElementById("character").style.top),
charLeft = parseInt(document.getElementById("character").style.left);
if (e == 40) { //down function
document.getElementById("character").style.top = (parseInt(document.getElementById("character").style.top)) + 10 + "px";
} else if (e == 37) { //left function
document.getElementById("character").style.left = (parseInt(document.getElementById("character").style.left)) - 10 + "px";
} else if (e == 39) { //right function
document.getElementById("character").style.left = (parseInt(document.getElementById("character").style.left)) + 10 + "px";
} else if (e == 38) { //up function
document.getElementById("character").style.top = (parseInt(document.getElementById("character").style.top)) - 10 + "px";
}
}
我发现,如果你按住一个箭头键,它会移动一次,等待一秒钟,然后不断移动,直到你放手。我认为造成这种情况的原因是Windows的内置功能在指定的延迟后以控制面板中设置的速度重复按下按钮。
我更希望角色能立即、连续地移动,没有延迟。我不知道该怎么办。我还希望能够定义如果按钮仍然被按下,再次移动的速度(它一次移动十个像素,如果重复得太快,它会在屏幕上飞过)。
我知道Javascript并不是真正用于游戏编程的,但希望有人能想办法解决这个问题!谢谢
这是许多依赖键盘中断来控制游戏角色的编码语言中的标准问题,而不是JavaScript特有的问题。解决方法是将按键与角色的移动分开,而不是依赖键盘事件来重新绘制/更新游戏。相反,使用一个连续的游戏循环,这种循环可以而且经常不会做任何事情(每秒多次)—直到你的游戏发生变化。这似乎是一件奇怪的事情,但这是许多游戏的设计和构建方式;甚至在JavaScript中;)
/// store key codes and currently pressed ones
var keys = {};
keys.LEFT = 37;
keys.RIGHT = 39;
/// store reference to character's position and element
var character = {
x: 100,
y: 100,
element: document.getElementById("character")
};
/// key detection (better to use addEventListener, but this will do)
document.body.onkeyup =
document.body.onkeydown = function(e){
var kc = e.keyCode || e.which;
keys[kc] = e.type == 'keydown';
};
/// character movement update
var moveCharacter = function(dx, dy){
character.x += dx||0;
character.y += dy||0;
character.element.style.left = character.x + 'px';
character.element.style.top = character.y + 'px';
};
/// character control
var detectCharacterMovement = function(){
if ( keys[keys.LEFT] ) {
moveCharacter(-1);
}
if ( keys[keys.RIGHT] ) {
moveCharacter(1);
}
};
/// game loop
setInterval(function(){
detectCharacterMovement();
}, 1000/24);
一个活生生的例子(也有上下移动):
/// store key codes and currently pressed ones
var keys = {};
keys.UP = 38;
keys.LEFT = 37;
keys.RIGHT = 39;
keys.DOWN = 40;
/// store reference to character's position and element
var character = {
x: 100,
y: 100,
speedMultiplier: 2,
element: document.getElementById("character")
};
/// key detection (better to use addEventListener, but this will do)
document.body.onkeyup =
document.body.onkeydown = function(e){
/// prevent default browser handling of keypresses
if (e.preventDefault) {
e.preventDefault();
}
else {
e.returnValue = false;
}
var kc = e.keyCode || e.which;
keys[kc] = e.type == 'keydown';
};
/// character movement update
var moveCharacter = function(dx, dy){
character.x += (dx||0) * character.speedMultiplier;
character.y += (dy||0) * character.speedMultiplier;
character.element.style.left = character.x + 'px';
character.element.style.top = character.y + 'px';
};
/// character control
var detectCharacterMovement = function(){
if ( keys[keys.LEFT] ) {
moveCharacter(-1, 0);
}
if ( keys[keys.RIGHT] ) {
moveCharacter(1, 0);
}
if ( keys[keys.UP] ) {
moveCharacter(0, -1);
}
if ( keys[keys.DOWN] ) {
moveCharacter(0, 1);
}
};
/// update current position on screen
moveCharacter();
/// game loop
setInterval(function(){
detectCharacterMovement();
}, 1000/24);
#character {
position: absolute;
width: 42px;
height: 42px;
background: red;
border-radius: 50%;
}
<div id="character"></div>
http://jsfiddle.net/7a106ck7/1/
以上只是基本内容,您可以进行一些优化。以上也不是控制游戏角色的全部和最终,可悲的是,浏览器中的键盘事件是不可预测的(与JavaScript无关),如果你开始尝试制作更复杂的控制系统,你会发现很多问题,即某些键不能同时按下而不会出现问题(尤其是CMD或CTRL等控制字符)。
有一天,如果JavaScript有一个Keyboard对象,它的行为就像上面的keys
对象一样,那就太好了。这意味着您可以在任何时候测试当前按下的任何键的状态,而不必依赖事件模型。它可能会在未来某个未知的时刻发生,但我们必须拭目以待。
如果真的发生了,我想推荐一个功能:
Keyboard.isPressed(Keyboard.ANY)
这将有助于无数的游戏介绍/菜单屏幕(为什么我必须在看到菜单之前按下任何键?我们梦想着街机吗?)。更不用说,以上这些将帮助所有仍在等待他们认为缺失的钥匙存在的人。
尝试使用onkeyup而不是onkeydown,onkeyup在密钥释放后取值
document.getElementById("character").style.top = 0;
document.getElementById("character").style.left = 0;
document.body.onkeyup = function() {
var e = event.keyCode,
charTop = parseInt(document.getElementById("character").style.top),
charLeft = parseInt(document.getElementById("character").style.left);
if (e == 40) { //down function
document.getElementById("character").style.top = (parseInt(document.getElementById("character").style.top)) + 10 + "px";
} else if (e == 37) { //left function
document.getElementById("character").style.left = (parseInt(document.getElementById("character").style.left)) - 10 + "px";
} else if (e == 39) { //right function
document.getElementById("character").style.left = (parseInt(document.getElementById("character").style.left)) + 10 + "px";
} else if (e == 38) { //up function
document.getElementById("character").style.top = (parseInt(document.getElementById("character").style.top)) - 10 + "px";
}
}
创建一个全局HOP变量,该变量将定义角色移动的速度。
在按下键时创建一个:
var inter = setInterval(function(){
//apply movements here
}, HOP);
然后在按下键时,您使用以下命令停止移动:
clearInterval(inter);
setInterval()
将在每个HOP
(以毫秒为单位)调用自己。这将循环,直到您检测到用户已释放密钥。
为了确保不创建多个setIntervals,请确保全局初始化您的var inter = -1
,并且每次清除它时都将其设置回-1。当检测到按键按下时,采用这种方式。。只需检查inter是否>-1。如果是,那就什么都不做。
的简单演示
HTML:
<div id="container"></div>
JS:
var container = document.getElementById('container');
var p = document.createElement('p');
var inter = -1;
var HOP = 50; //miliseconds
window.onkeydown = function(){
if(inter == -1){
inter = setInterval(function(){
var p_temp = p.cloneNode();
p_temp.innerHTML = "Key is down";
container.appendChild(p_temp);
}, HOP);
}
};
window.onkeyup = function(){
clearInterval(inter);
inter = -1;
};
- Canvas Html5绘图应用程序,移动画布会导致重大问题
- 正在SharePoint 2013母版页中添加JQuery移动文件
- 如何在android中使用phonegap将文件从一个文件夹移动/复制到另一个文件夹
- 如何使用phaser使html5游戏在移动设备浏览器上运行
- FabricJs-限制主对象内添加对象的移动区域
- Html页面上的多个Base64图像和平滑加载
- 如何从画布上的某个移动事件中获取X和Y
- 如何通过箭头键连续/平滑地移动元素
- 使用 javascript 在移动设备上平滑拖动图像
- 文本自动移动以适应动画相邻文本 (jquery):如何平滑
- CSS动画关键帧平滑移动
- 如何在地图上平滑移动标记而不闪烁
- 在等距地图上平滑的角色移动
- HTML5 Canvas:使用/缓存drawImage绘制的元素在缩放和/或移动时被平滑
- 如何移动/动画DIV背景图像平滑垂直
- 根据页面加载的可变值上下移动画布线,并实现平滑过渡
- 我如何使我的文本移动动画在画布上更平滑(少锯齿运动)
- 使JavaScript图像移动时滚动更平滑
- 在画布游戏中使用键盘控制平滑的角色移动
- 如何在移动设备上使画布上的对象在 x 轴上平滑地左右移动