我在使用onKeyDown事件时会延迟移动元素

时间:2015-11-17 16:39:16

标签: javascript delay game-engine keyboard-events onkeydown

当我按住一个键(在这种情况下是向左或向右箭头)时,我试图让元素移动,但是当我按住一个键时,移动会延迟大约一秒钟。我使用错误的事件或我的代码有什么问题吗?

我正在使用onKeyDown事件来触发移动。



<head>
<script>
	var objX = 100;		
	function blockMove(e){
		if (e.keyCode == 37) { //move left
			objX-=4;
			document.getElementById("object").style.left = objX + "px";	
		} else if (e.keyCode ==  39) { //move right
			objX+=4;
			document.getElementById("object").style.left = objX + "px";	
		}
	}			
	</script>
</head>
<body onkeydown="blockMove(event)">
	<div id=object style="height:10px;width:80px;background-color:red;position:absolute;top:50px;left:100px"></div>
</body>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:2)

而不是依赖于用户键盘重复率,这是最终导致多次调用blockMove的原因,您应该使用计时器来检查对象是否应该以一致的速率移动(在我下面的例子中每隔20ms)。这意味着无论重复率设置如何,它都将为所有用户提供一致的体验。

然后,您需要跟踪对象是否应该移动。通过使用keydownkeyup事件,我们可以跟踪当前是否按下左侧和右侧,然后只检查现有blockMove函数中的这些值:

&#13;
&#13;
//object to keep current state of keys
var keys = {
  left: false,
  right: false
};

function keydown(e) {
  //remember "down" state
  if (e.keyCode == 37)
    keys.left = true;
  if (e.keyCode == 39)
    keys.right = true;
}
function keyup(e) {
  //forget "down" state
  if (e.keyCode == 37)
    keys.left = false;
  if (e.keyCode == 39)
    keys.right = false;
}

var objX = 100;		
function blockMove(){
    //now check the key state, rather than the event object
    if (keys.left) { //move left
        objX -= 4;
    }
    if (keys.right) { //move right
        objX += 4;
    }
    document.getElementById("object").style.left = objX + "px";	
}

//Call the movement function every 20ms
window.setInterval(blockMove, 20);
&#13;
<body onkeydown="keydown(event)" onkeyup="keyup(event)">
	<div id=object style="height:10px;width:80px;background-color:red;position:absolute;top:50px;left:100px"></div>
</body>
&#13;
&#13;
&#13;

正如下面的评论中所讨论的,setInterval仅保证在调用函数之前的最短时间,并且可以受到限制。除了移动DOM对象之外,它还可以用于学习这样的基础知识,但在某些时候,您可能希望查看drawing directly onto <canvas>元素并使用requestAnimationFrame来处理回调,因为它和#39;专为动画而设计,与setTimeout / setInterval不同。

答案 1 :(得分:1)

忍受我,这有点长,可能是马车: (如果你想自己动手,也是一个扰流板)

<head>
<script>
    var objX = 100;     
   var leftDown = false;
   var rightDown = false;
        function blockMove(e){
            if(e.keyCode == 37 && !leftDown) { //move left
            leftDown = true;
                objX-=4;
                document.getElementById("object").style.left = objX + "px"; 
                }else if(e.keyCode ==  39 && !rightDown) { //move right
               rightDown = true;
                    objX+=4;
                    document.getElementById("object").style.left = objX + "px"; 
        }}
      function stopMove(e)
      {
         if( e.keyCode == 37 )
            leftDown = false;
         if( e.keyCode == 39 )
            rightDown = false;
      }
       function timer()
      {
         if( leftDown )
            objX -= 4;
         if( rightDown )
            objX += 4;
         document.getElementById("object").style.left = objX + "px";    
      }
      setInterval(timer, 100);
    </script>
</head>
<body onkeydown="blockMove(event)" onkeyup="stopMove(event)">
    <div id=object 
style="height:10px;width:80px;background-color:red;position:absolute;top:360px;left:100px"
    ></div>
</body>