我如何让我的JavaScript游戏停止冻结每几秒钟?



我正在编写一款《吃豆人》游戏,到目前为止我已经完成了移动和动画,但由于某种原因,《吃豆人》每隔2秒左右就会冻结一次。非常轻微和迅速,但足够明显。也许这与我的浏览器(Google Chrome)或我设置setTimer函数的方式有关?我也知道JavaScript中的canvas功能,我只是想在没有它的情况下制作这款游戏。

script.js:

let pacMan;
let keyPressed;
let keys = [];
/**
* Creates a new Pac-Man <img> element and appends it to the document's body.
* @param {string} src The path to Pac-Man's png image file.
* @param {number} positionX Pac-Man's x position in the document's body.
* @param {number} positionY Pac-Man's y position in the document's body.
* @param {string} transform Pac-Man's rotation in degrees.
*/
function createPacMan(src, positionX, positionY, transform) {
pacMan = document.createElement("img");
pacMan.src = src;
pacMan.id = "pacMan";
pacMan.style.transform = transform;
pacMan.style.left = positionX + "px";
pacMan.style.top = positionY + "px";
document.body.appendChild(pacMan);
}
createPacMan("assets/images/pacMan1.png", 0, 0);
let pacManPosition = {
"x": pacMan.getBoundingClientRect().x,
"y": pacMan.getBoundingClientRect().y
};
/**
* Calls itself continuously to test if Pac-Man is moving and moves him.
*/
function movePacMan() {
switch (keyPressed) {
case "ArrowUp":
pacManPosition.y -= 1;
pacMan.style.top = pacManPosition.y + "px";
pacMan.style.transform = "rotate(90deg)";
break;
case "ArrowDown":
pacManPosition.y += 1;
pacMan.style.top = pacManPosition.y + "px";
pacMan.style.transform = "rotate(-90deg)";
break;
case "ArrowRight":
pacManPosition.x += 1;
pacMan.style.left = pacManPosition.x + "px";
pacMan.style.transform = "rotate(180deg)";
break;
case "ArrowLeft":
pacManPosition.x -= 1;
pacMan.style.left = pacManPosition.x + "px";
pacMan.style.transform = "rotate(0deg)";
break;
}
setTimeout(movePacMan, 15);
}
movePacMan();
/**
* Calls itself continuously to test if Pac-Man is moving and animated him.
*/
function animatePacMan() {
if (keys["ArrowUp"] || keys["ArrowDown"] || keys["ArrowRight"] || keys["ArrowLeft"]) {
setTimeout(function() {
document.body.removeChild(pacMan);
createPacMan("assets/images/pacMan2.png", pacManPosition.x, pacManPosition.y, pacMan.style.transform);
setTimeout(function() {
document.body.removeChild(pacMan);
createPacMan("assets/images/pacMan3.png", pacManPosition.x, pacManPosition.y, pacMan.style.transform);
setTimeout(function() {
document.body.removeChild(pacMan);
createPacMan("assets/images/pacMan1.png", pacManPosition.x, pacManPosition.y, pacMan.style.transform);
}, 50);
}, 50);
}, 50);
}
setTimeout(animatePacMan, 165);
}
animatePacMan();
/**
* Adds an event listener that tests for keydown event and resets the keyPressed
* array, then gets the key pressed and sets its value in the array to be true.
*/
window.addEventListener("keydown", function(event) {
if (event.key == "ArrowUp" || event.key == "ArrowDown" || event.key == "ArrowRight" || event.key == "ArrowLeft") {
keyPressed = "";
keyPressed = event.key;
keys[event.key] = true;
}
});

对movePacMan的递归调用意味着调用堆栈不受约束地增长。这意味着浏览器将不得不换出内存,这可能解释了您观察到的性能问题。使用setInterval()代替递归调用,或者像@mplungjan提到的requestAnimationFrame()。

最新更新