为什么我的游戏角色在我使用按键事件时一直在加速?

Why does my game character keep accelerating when I use the keydown event?

我正在尝试做一个简单的游戏。绿色方块是我的游戏角色。我使用 keydown 事件让我的角色能够左右移动。当我按住向右或向左箭头键时,角色会继续加速。如果您首先点击向右或向左箭头键,您会看到角色所在位置和当前位置之间的 space 间隔随着您点击的次数增加而增加。我怎样才能让我的角色以恒定的速度以恒定的 space 间隔移动。

//variables
var canvas = document.getElementById("canvas");
var draw = canvas.getContext("2d");
var characterx = 20;
var charactery = window.innerHeight - 60;
var dx = 0.01;
var dy = 0.01;

//canvas size
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;



//main game function
function run() {

 //loops the function
 requestAnimationFrame(run);

 //clears the screen
 draw.clearRect(0, 0, canvas.width, canvas.height)

 //draws the ground
 draw.beginPath();
 draw.fillStyle = "#823819";
 draw.fillRect(0, canvas.height - 20, canvas.width, 20);
 draw.fill();
 draw.closePath();

 //draws the main character
 draw.beginPath();
 draw.fillStyle = "#128522";
 draw.fillRect(characterx, charactery, 40, 40);
 draw.fill();
 draw.closePath();

 //key evevnts
 window.addEventListener("keydown",function(event) {
  if(event.keyCode == 39) {
   characterx  += dx;
  }
 });

 window.addEventListener("keydown",function(event) {
  if(event.keyCode == 37) {
   characterx  -= dx;
  }  
 });

};
run();
<!DOCTYPE html>
<html>
<head>
 <title>Test</title>
 <style type="text/css">
  body {
   margin: 0;
   overflow: hidden;
  }
  canvas {
   margin: 0;
   overflow: hidden;
  }
 </style>
</head>
<body>
 <canvas id="canvas"></canvas>
 <script type="text/javascript" src="script.js"></script>
</body>
</html>

您的事件侦听器应添加到游戏循环之外。

目前,您正在为每一帧的每个按键添加一个额外的侦听器,这意味着在第一帧,您将为按键移动 dx * 1,但在第 100 帧,您将为按键移动 dx * 100一次按键。

这也是您的 dx 值必须如此低的原因 - 我在下面的示例中增加了它,但您可以根据需要进行调整。

//variables
var canvas = document.getElementById("canvas");
var draw = canvas.getContext("2d");
var characterx = 20;
var charactery = window.innerHeight - 60;
var dx = 3.0;
var dy = 3.0;

//canvas size
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

//key evevnts
window.addEventListener("keydown",function(event) {
 if(event.keyCode == 39) {
  characterx  += dx;
 }
});
window.addEventListener("keydown",function(event) {
 if(event.keyCode == 37) {
  characterx  -= dx;
 }  
});

//main game function
function run() {

 //loops the function
 requestAnimationFrame(run);

 //clears the screen
 draw.clearRect(0, 0, canvas.width, canvas.height)

 //draws the ground
 draw.beginPath();
 draw.fillStyle = "#823819";
 draw.fillRect(0, canvas.height - 20, canvas.width, 20);
 draw.fill();
 draw.closePath();

 //draws the main character
 draw.beginPath();
 draw.fillStyle = "#128522";
 draw.fillRect(characterx, charactery, 40, 40);
 draw.fill();
 draw.closePath();

};
run();
<!DOCTYPE html>
<html>
<head>
 <title>Test</title>
 <style type="text/css">
  body {
   margin: 0;
   overflow: hidden;
  }
  canvas {
   margin: 0;
   overflow: hidden;
  }
 </style>
</head>
<body>
 <canvas id="canvas"></canvas>
 <script type="text/javascript" src="script.js"></script>
</body>
</html>